Apply PSR-12 code style (#3886)
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / cache / builder / ACPMenuCacheBuilder.class.php
1 <?php
2
3 namespace wcf\system\cache\builder;
4
5 use wcf\acp\form\OptionForm;
6 use wcf\data\acp\menu\item\ACPMenuItem;
7 use wcf\data\acp\menu\item\ACPMenuItemList;
8 use wcf\data\option\category\OptionCategory;
9 use wcf\data\option\category\OptionCategoryList;
10 use wcf\data\option\OptionList;
11
12 /**
13 * Caches the ACP menu items.
14 *
15 * @author Matthias Schmidt, Marcel Werk
16 * @copyright 2001-2019 WoltLab GmbH
17 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
18 * @package WoltLabSuite\Core\System\Cache\Builder
19 */
20 class ACPMenuCacheBuilder extends AbstractCacheBuilder
21 {
22 /**
23 * list of option categories which directly contain options
24 * @var string[]
25 */
26 protected $categoriesWithOptions = [];
27
28 /**
29 * list of option categories grouped by the name of their parent category
30 * @var OptionCategory[]
31 */
32 protected $categoryStructure = [];
33
34 /**
35 * @inheritDoc
36 */
37 public function rebuild(array $parameters)
38 {
39 $data = [];
40
41 // get "real" menu items
42 $menuItemList = new ACPMenuItemList();
43 $menuItemList->sqlOrderBy = "acp_menu_item.showOrder";
44 $menuItemList->readObjects();
45 foreach ($menuItemList as $menuItem) {
46 $data[$menuItem->parentMenuItem][] = $menuItem;
47 }
48
49 // get menu items for top option categories
50 $data['wcf.acp.menu.link.option.category'] = [];
51 foreach ($this->getTopOptionCategories() as $optionCategory) {
52 $data['wcf.acp.menu.link.option.category'][] = new ACPMenuItem(null, [
53 'menuItem' => 'wcf.acp.option.category.' . $optionCategory->categoryName,
54 'parentMenuItem' => 'wcf.acp.menu.link.option.category',
55 'menuItemController' => OptionForm::class,
56 'permissions' => $optionCategory->permissions,
57 'optionCategoryID' => $optionCategory->categoryID,
58 'options' => $optionCategory->options,
59 ]);
60 }
61
62 return $data;
63 }
64
65 /**
66 * Returns the list with top option categories which contain options.
67 *
68 * @return OptionCategory[]
69 */
70 protected function getTopOptionCategories()
71 {
72 $optionCategoryList = new OptionCategoryList();
73 $optionCategoryList->readObjects();
74 $optionCategories = $optionCategoryList->getObjects();
75
76 // build category structure
77 $this->categoryStructure = [];
78 foreach ($optionCategories as $optionCategory) {
79 if (!isset($this->categoryStructure[$optionCategory->parentCategoryName])) {
80 $this->categoryStructure[$optionCategory->parentCategoryName] = [];
81 }
82
83 $this->categoryStructure[$optionCategory->parentCategoryName][] = $optionCategory;
84 }
85
86 $optionList = new OptionList();
87 $optionList->readObjects();
88
89 // collect names of categories which contain options
90 foreach ($optionList as $option) {
91 if (!isset($this->categoriesWithOptions[$option->categoryName])) {
92 $this->categoriesWithOptions[$option->categoryName] = $option->categoryName;
93 }
94 }
95
96 // collect top categories which contain options
97 $topCategories = [];
98 foreach ($this->categoryStructure[""] as $topCategory) {
99 if ($this->containsOptions($topCategory)) {
100 $topCategories[$topCategory->categoryID] = $topCategory;
101 }
102 }
103
104 return $topCategories;
105 }
106
107 /**
108 * Returns true if the given category or one of its child categories contains
109 * options.
110 *
111 * @param OptionCategory $topCategory
112 * @return bool
113 */
114 protected function containsOptions(OptionCategory $topCategory)
115 {
116 // check if category directly contains options
117 if (isset($this->categoriesWithOptions[$topCategory->categoryName])) {
118 return true;
119 }
120
121 if (!isset($this->categoryStructure[$topCategory->categoryName])) {
122 // if category directly contains no options and has no child
123 // categories, it contains no options at all
124 return false;
125 }
126
127 // check child categories
128 foreach ($this->categoryStructure[$topCategory->categoryName] as $category) {
129 if ($this->containsOptions($category)) {
130 return true;
131 }
132 }
133
134 return false;
135 }
136 }