Skip to content

Commit f60043f

Browse files
authored
fix: category tree broken
1 parent c94595b commit f60043f

File tree

6 files changed

+176
-35
lines changed

6 files changed

+176
-35
lines changed

ajax/homepage_wizard.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
}
5454

5555
function plugin_formcreator_showWizardCategories() {
56-
$tree = PluginFormcreatorCategory::getCategoryTree(0, false);
56+
$tree = PluginFormcreatorCommon::getCategoryTree();
5757
echo json_encode($tree, JSON_UNESCAPED_SLASHES);
5858
}
5959

css/styles.scss

Lines changed: 3 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,6 @@ form#plugin_formcreator_form {
289289

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

295294
> h1 {
@@ -523,8 +522,8 @@ tr[data-itemtype="PluginFormcreatorCondition"] ~ tr[data-itemtype="PluginFormcre
523522
a {
524523
display: block;
525524
border: none;
526-
padding: 1em;
527-
height: 16px;
525+
padding: 16px;
526+
height: 51px;
528527
}
529528

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

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

595-
.category_active:not(.next):after,
596-
.category_active ~ul .header:after {
597-
position: absolute;
598-
left: calc(100% - 45px);
599-
top: 50%;
600-
border: solid transparent;
601-
content: " ";
602-
height: 0;
603-
width: 0;
604-
border-right-color: #FFF;
605-
border-width: 23px;
606-
margin-top: -23px;
607-
z-index: 20;
608-
}
609-
610593
.category_active:not(.next):before,
611594
.category_active ~ul .header:before {
612595
position: absolute;
@@ -628,22 +611,13 @@ tr[data-itemtype="PluginFormcreatorCondition"] ~ tr[data-itemtype="PluginFormcre
628611

629612
.card-title {
630613
padding: 0.83em 0;
631-
// border-bottom: 1px solid #DDD;
632614
margin: 0;
633615
padding: 14px;
634-
// color: #000;
635616
}
636-
// .header h2 {
637-
// text-align: left;
638-
// }
639-
// .header .back {
640-
// right: 20px;
641-
// color: #000;
642-
// left: inherit;
643-
// }
644617

645618
li {
646619
background-color: inherit;
620+
height: 51px;
647621
}
648622
}
649623

inc/common.class.php

Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -735,4 +735,171 @@ public static function footer() {
735735
return Html::nullFooter();
736736
}
737737
}
738+
739+
/**
740+
* Get the tree of categories
741+
*
742+
* @return array Tree of form categories as nested array
743+
*/
744+
public static function getCategoryTree(): array {
745+
global $DB;
746+
747+
$cat_table = KnowbaseItemCategory::getTable();
748+
$form_table = PluginFormcreatorForm::getTable();
749+
$table_fp = PluginFormcreatorForm_Profile::getTable();
750+
751+
$query_faqs = KnowbaseItem::getListRequest([
752+
'faq' => '1',
753+
'contains' => '',
754+
'knowbaseitemcategories_id' => 0,
755+
]);
756+
// GLPI 9.5 returns an array
757+
$subQuery = new DBMysqlIterator($DB);
758+
$subQuery->buildQuery($query_faqs);
759+
760+
$dbUtils = new DbUtils();
761+
$entityRestrict = $dbUtils->getEntitiesRestrictCriteria($form_table, "", "", true, false);
762+
if (count($entityRestrict)) {
763+
$entityRestrict = [$entityRestrict];
764+
}
765+
766+
// Selects categories containing forms or sub-categories
767+
$categoryFk = KnowbaseItemCategory::getForeignKeyField();
768+
$count1 = new QuerySubQuery([
769+
'COUNT' => 'count',
770+
'FROM' => $form_table,
771+
'WHERE' => [
772+
'is_active' => '1',
773+
'is_deleted' => '0',
774+
"$form_table.$categoryFk" => new QueryExpression("$cat_table.id"),
775+
'language' => [$_SESSION['glpilanguage'], '', '0', null],
776+
'OR' => [
777+
'access_rights' => ['!=', PluginFormcreatorForm::ACCESS_RESTRICTED],
778+
'id' => new QuerySubQuery([
779+
'SELECT' => 'plugin_formcreator_forms_id',
780+
'FROM' => $table_fp,
781+
'WHERE' => ['profiles_id' => $_SESSION['glpiactiveprofile']['id']],
782+
])
783+
]
784+
]
785+
+ $entityRestrict,
786+
]);
787+
$count2 = new QuerySubQuery([
788+
'COUNT' => 'count',
789+
'FROM' => (new QuerySubQuery($query_faqs, 'faqs')),
790+
'WHERE' => [
791+
"$cat_table.id" => ['!=', '0'],
792+
]
793+
]);
794+
$request = [
795+
'SELECT' => [
796+
'id',
797+
'name',
798+
"$categoryFk as parent",
799+
'level',
800+
new QueryExpression(
801+
$count1->getQuery() . " + " . $count2->getQuery() . " as items_count"
802+
),
803+
],
804+
'FROM' => $cat_table,
805+
'ORDER' => ["level DESC", "name DESC"],
806+
];
807+
$result = $DB->request($request);
808+
809+
$categories = [];
810+
foreach ($result as $category) {
811+
$category['name'] = Dropdown::getDropdownName($cat_table, $category['id'], 0, true, false);
812+
// Keep the short name only
813+
// If a symbol > exists in a name, it is saved as an html entity, making the following reliable
814+
$split = explode(' > ', $category['name']);
815+
$category['name'] = array_pop($split);
816+
$categories[$category['id']] = $category;
817+
}
818+
819+
// Remove categories that have no items and no children
820+
// Requires category list to be sorted by level DESC
821+
foreach ($categories as $index => $category) {
822+
$children = array_filter(
823+
$categories,
824+
function ($element) use ($category) {
825+
return $category['id'] == $element['parent'];
826+
}
827+
);
828+
if (empty($children) && 0 == $category['items_count']) {
829+
unset($categories[$index]);
830+
continue;
831+
}
832+
$categories[$index]['subcategories'] = [];
833+
}
834+
835+
// Create root node
836+
$nodes = [
837+
'name' => '',
838+
'id' => 0,
839+
'parent' => 0,
840+
'subcategories' => [],
841+
];
842+
$flat = [
843+
0 => &$nodes,
844+
];
845+
846+
// Build from root node to leaves
847+
$categories = array_reverse($categories);
848+
foreach ($categories as $item) {
849+
$flat[$item['id']] = $item;
850+
$flat[$item['parent']]['subcategories'][] = &$flat[$item['id']];
851+
}
852+
853+
return $nodes;
854+
}
855+
856+
/**
857+
* Get available categories
858+
*
859+
* @param int $helpdeskHome
860+
* @return DBmysqlIterator
861+
*/
862+
public static function getAvailableCategories($helpdeskHome = 1): DBmysqlIterator {
863+
global $DB;
864+
865+
$result = $DB->request(self::getAvailableCategoriesCriterias($helpdeskHome));
866+
867+
return $result;
868+
}
869+
870+
/**
871+
* Get available categories
872+
*
873+
* @param int $helpdeskHome
874+
* @return array
875+
*/
876+
public static function getAvailableCategoriesCriterias($helpdeskHome = 1): array {
877+
$cat_table = KnowbaseItemCategory::getTable();
878+
$categoryFk = KnowbaseItemCategory::getForeignKeyField();
879+
$formTable = PluginFormcreatorForm::getTable();
880+
$formRestriction = PluginFormcreatorForm::getFormRestrictionCriterias($formTable);
881+
882+
$formRestriction["$formTable.helpdesk_home"] = $helpdeskHome;
883+
884+
return [
885+
'SELECT' => [
886+
$cat_table => [
887+
'name', 'id'
888+
]
889+
],
890+
'FROM' => $cat_table,
891+
'INNER JOIN' => [
892+
$formTable => [
893+
'FKEY' => [
894+
$cat_table => 'id',
895+
$formTable => $categoryFk
896+
]
897+
]
898+
],
899+
'WHERE' => PluginFormcreatorForm::getFormRestrictionCriterias($formTable),
900+
'GROUPBY' => [
901+
"$cat_table.id"
902+
]
903+
];
904+
}
738905
}

inc/form.class.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,7 @@ public function showFormList(int $rootCategory = 0, string $keywords = '', bool
878878
'faq' => '1',
879879
'contains' => $keywords
880880
];
881+
$params['knowbaseitemcategories_id'] = 0;
881882
if (count($selectedCategories) > 0) {
882883
$params['knowbaseitemcategories_id'] = $selectedCategories;
883884
}
@@ -2063,7 +2064,7 @@ public function showForCentral() {
20632064
$formCategoryFk = KnowbaseItemCategory::getForeignKeyField();
20642065

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

21112112
// Show a row for the form

install/install.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -476,7 +476,6 @@ protected function deleteTables() {
476476
// Keep these itemtypes as string because classes might not be available (if plugin is inactive)
477477
$itemtypes = [
478478
'PluginFormcreatorAnswer',
479-
'PluginFormcreatorCategory',
480479
'PluginFormcreatorEntityconfig',
481480
'PluginFormcreatorFormAnswer',
482481
'PluginFormcreatorForm_Profile',

tests/4-functional/Central.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public function testFormsAreVisible() {
7676
// Open the forms tab
7777
$this->browsing->openTab('Forms');
7878
$this->takeScreenshot();
79-
$formSelector = '#plugin_formcreatorHomepageForms [data-itemtype="PluginFormcreatorCategory"][data-id="0"] + [data-itemtype="PluginFormcreatorForm"][data-id="' . $form->getID() . '"]';
79+
$formSelector = '#plugin_formcreatorHomepageForms [data-itemtype="KnowbaseItemCategory"][data-id="0"] + [data-itemtype="PluginFormcreatorForm"][data-id="' . $form->getID() . '"]';
8080
$output = $this->crawler->filter($formSelector)->count();
8181
$this->integer($output)->isEqualTo(1);
8282
$formSelector .= ' a';
@@ -94,7 +94,7 @@ public function testFormsAreVisible() {
9494

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

0 commit comments

Comments
 (0)