Skip to content

Commit

Permalink
fix: category tree broken
Browse files Browse the repository at this point in the history
  • Loading branch information
btry authored Dec 17, 2021
1 parent c94595b commit f60043f
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 35 deletions.
2 changes: 1 addition & 1 deletion ajax/homepage_wizard.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
}

function plugin_formcreator_showWizardCategories() {
$tree = PluginFormcreatorCategory::getCategoryTree(0, false);
$tree = PluginFormcreatorCommon::getCategoryTree();
echo json_encode($tree, JSON_UNESCAPED_SLASHES);
}

Expand Down
32 changes: 3 additions & 29 deletions css/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,6 @@ form#plugin_formcreator_form {

> .form_header {
background: #EEE;
/*box-shadow: 2px 2px 2px #CCC;*/
margin: 0 0 10px;

> h1 {
Expand Down Expand Up @@ -523,8 +522,8 @@ tr[data-itemtype="PluginFormcreatorCondition"] ~ tr[data-itemtype="PluginFormcre
a {
display: block;
border: none;
padding: 1em;
height: 16px;
padding: 16px;
height: 51px;
}

li ul {
Expand Down Expand Up @@ -588,25 +587,9 @@ tr[data-itemtype="PluginFormcreatorCondition"] ~ tr[data-itemtype="PluginFormcre

.category_active:not(.next),
.category_active ~ul .header {
border-bottom: 1px dashed #DDD;
position: relative;
}

.category_active:not(.next):after,
.category_active ~ul .header:after {
position: absolute;
left: calc(100% - 45px);
top: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
border-right-color: #FFF;
border-width: 23px;
margin-top: -23px;
z-index: 20;
}

.category_active:not(.next):before,
.category_active ~ul .header:before {
position: absolute;
Expand All @@ -628,22 +611,13 @@ tr[data-itemtype="PluginFormcreatorCondition"] ~ tr[data-itemtype="PluginFormcre

.card-title {
padding: 0.83em 0;
// border-bottom: 1px solid #DDD;
margin: 0;
padding: 14px;
// color: #000;
}
// .header h2 {
// text-align: left;
// }
// .header .back {
// right: 20px;
// color: #000;
// left: inherit;
// }

li {
background-color: inherit;
height: 51px;
}
}

Expand Down
167 changes: 167 additions & 0 deletions inc/common.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -735,4 +735,171 @@ public static function footer() {
return Html::nullFooter();
}
}

/**
* Get the tree of categories
*
* @return array Tree of form categories as nested array
*/
public static function getCategoryTree(): array {
global $DB;

$cat_table = KnowbaseItemCategory::getTable();
$form_table = PluginFormcreatorForm::getTable();
$table_fp = PluginFormcreatorForm_Profile::getTable();

$query_faqs = KnowbaseItem::getListRequest([
'faq' => '1',
'contains' => '',
'knowbaseitemcategories_id' => 0,
]);
// GLPI 9.5 returns an array
$subQuery = new DBMysqlIterator($DB);
$subQuery->buildQuery($query_faqs);

$dbUtils = new DbUtils();
$entityRestrict = $dbUtils->getEntitiesRestrictCriteria($form_table, "", "", true, false);
if (count($entityRestrict)) {
$entityRestrict = [$entityRestrict];
}

// Selects categories containing forms or sub-categories
$categoryFk = KnowbaseItemCategory::getForeignKeyField();
$count1 = new QuerySubQuery([
'COUNT' => 'count',
'FROM' => $form_table,
'WHERE' => [
'is_active' => '1',
'is_deleted' => '0',
"$form_table.$categoryFk" => new QueryExpression("$cat_table.id"),
'language' => [$_SESSION['glpilanguage'], '', '0', null],
'OR' => [
'access_rights' => ['!=', PluginFormcreatorForm::ACCESS_RESTRICTED],
'id' => new QuerySubQuery([
'SELECT' => 'plugin_formcreator_forms_id',
'FROM' => $table_fp,
'WHERE' => ['profiles_id' => $_SESSION['glpiactiveprofile']['id']],
])
]
]
+ $entityRestrict,
]);
$count2 = new QuerySubQuery([
'COUNT' => 'count',
'FROM' => (new QuerySubQuery($query_faqs, 'faqs')),
'WHERE' => [
"$cat_table.id" => ['!=', '0'],
]
]);
$request = [
'SELECT' => [
'id',
'name',
"$categoryFk as parent",
'level',
new QueryExpression(
$count1->getQuery() . " + " . $count2->getQuery() . " as items_count"
),
],
'FROM' => $cat_table,
'ORDER' => ["level DESC", "name DESC"],
];
$result = $DB->request($request);

$categories = [];
foreach ($result as $category) {
$category['name'] = Dropdown::getDropdownName($cat_table, $category['id'], 0, true, false);
// Keep the short name only
// If a symbol > exists in a name, it is saved as an html entity, making the following reliable
$split = explode(' > ', $category['name']);
$category['name'] = array_pop($split);
$categories[$category['id']] = $category;
}

// Remove categories that have no items and no children
// Requires category list to be sorted by level DESC
foreach ($categories as $index => $category) {
$children = array_filter(
$categories,
function ($element) use ($category) {
return $category['id'] == $element['parent'];
}
);
if (empty($children) && 0 == $category['items_count']) {
unset($categories[$index]);
continue;
}
$categories[$index]['subcategories'] = [];
}

// Create root node
$nodes = [
'name' => '',
'id' => 0,
'parent' => 0,
'subcategories' => [],
];
$flat = [
0 => &$nodes,
];

// Build from root node to leaves
$categories = array_reverse($categories);
foreach ($categories as $item) {
$flat[$item['id']] = $item;
$flat[$item['parent']]['subcategories'][] = &$flat[$item['id']];
}

return $nodes;
}

/**
* Get available categories
*
* @param int $helpdeskHome
* @return DBmysqlIterator
*/
public static function getAvailableCategories($helpdeskHome = 1): DBmysqlIterator {
global $DB;

$result = $DB->request(self::getAvailableCategoriesCriterias($helpdeskHome));

return $result;
}

/**
* Get available categories
*
* @param int $helpdeskHome
* @return array
*/
public static function getAvailableCategoriesCriterias($helpdeskHome = 1): array {
$cat_table = KnowbaseItemCategory::getTable();
$categoryFk = KnowbaseItemCategory::getForeignKeyField();
$formTable = PluginFormcreatorForm::getTable();
$formRestriction = PluginFormcreatorForm::getFormRestrictionCriterias($formTable);

$formRestriction["$formTable.helpdesk_home"] = $helpdeskHome;

return [
'SELECT' => [
$cat_table => [
'name', 'id'
]
],
'FROM' => $cat_table,
'INNER JOIN' => [
$formTable => [
'FKEY' => [
$cat_table => 'id',
$formTable => $categoryFk
]
]
],
'WHERE' => PluginFormcreatorForm::getFormRestrictionCriterias($formTable),
'GROUPBY' => [
"$cat_table.id"
]
];
}
}
5 changes: 3 additions & 2 deletions inc/form.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -878,6 +878,7 @@ public function showFormList(int $rootCategory = 0, string $keywords = '', bool
'faq' => '1',
'contains' => $keywords
];
$params['knowbaseitemcategories_id'] = 0;
if (count($selectedCategories) > 0) {
$params['knowbaseitemcategories_id'] = $selectedCategories;
}
Expand Down Expand Up @@ -2063,7 +2064,7 @@ public function showForCentral() {
$formCategoryFk = KnowbaseItemCategory::getForeignKeyField();

// Show categories which have at least one form user can access
$result = PluginFormcreatorCategory::getAvailableCategories();
$result = PluginFormcreatorCommon::getAvailableCategories();
// For each categories, show the list of forms the user can fill
$categories = [0 => __('Forms without category', 'formcreator')];
foreach ($result as $category) {
Expand Down Expand Up @@ -2105,7 +2106,7 @@ public function showForCentral() {
if ($currentCategoryId != $row[$formCategoryFk]) {
// show header for the category
$currentCategoryId = $row[$formCategoryFk];
echo '<tr class="noHover" data-itemtype="PluginFormcreatorCategory" data-id="' . $currentCategoryId . '"><th>' . $categories[$currentCategoryId] . '</th></tr>';
echo '<tr class="noHover" data-itemtype="KnowbaseItemCategory" data-id="' . $currentCategoryId . '"><th>' . $categories[$currentCategoryId] . '</th></tr>';
}

// Show a row for the form
Expand Down
1 change: 0 additions & 1 deletion install/install.php
Original file line number Diff line number Diff line change
Expand Up @@ -476,7 +476,6 @@ protected function deleteTables() {
// Keep these itemtypes as string because classes might not be available (if plugin is inactive)
$itemtypes = [
'PluginFormcreatorAnswer',
'PluginFormcreatorCategory',
'PluginFormcreatorEntityconfig',
'PluginFormcreatorFormAnswer',
'PluginFormcreatorForm_Profile',
Expand Down
4 changes: 2 additions & 2 deletions tests/4-functional/Central.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public function testFormsAreVisible() {
// Open the forms tab
$this->browsing->openTab('Forms');
$this->takeScreenshot();
$formSelector = '#plugin_formcreatorHomepageForms [data-itemtype="PluginFormcreatorCategory"][data-id="0"] + [data-itemtype="PluginFormcreatorForm"][data-id="' . $form->getID() . '"]';
$formSelector = '#plugin_formcreatorHomepageForms [data-itemtype="KnowbaseItemCategory"][data-id="0"] + [data-itemtype="PluginFormcreatorForm"][data-id="' . $form->getID() . '"]';
$output = $this->crawler->filter($formSelector)->count();
$this->integer($output)->isEqualTo(1);
$formSelector .= ' a';
Expand All @@ -94,7 +94,7 @@ public function testFormsAreVisible() {

// Check the form shows in the expected category
$this->takeScreenshot();
$formSelector = '#plugin_formcreatorHomepageForms [data-itemtype="PluginFormcreatorCategory"][data-id="' . $categoryId . '"] + [data-itemtype="PluginFormcreatorForm"][data-id="' . $form->getID() . '"]';
$formSelector = '#plugin_formcreatorHomepageForms [data-itemtype="KnowbaseItemCategory"][data-id="' . $categoryId . '"] + [data-itemtype="PluginFormcreatorForm"][data-id="' . $form->getID() . '"]';
$output = $this->crawler->filter($formSelector)->count();
$this->integer($output)->isEqualTo(1);
$formSelector .= ' a';
Expand Down

0 comments on commit f60043f

Please sign in to comment.