@@ -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}
0 commit comments