Merge branch 'master' into next
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / acp / page / AbstractCategoryListPage.class.php
1 <?php
2 declare(strict_types=1);
3 namespace wcf\acp\page;
4 use wcf\data\category\CategoryNodeTree;
5 use wcf\data\object\type\ObjectType;
6 use wcf\page\AbstractPage;
7 use wcf\system\category\CategoryHandler;
8 use wcf\system\exception\InvalidObjectTypeException;
9 use wcf\system\exception\PermissionDeniedException;
10 use wcf\system\user\collapsible\content\UserCollapsibleContentHandler;
11 use wcf\system\WCF;
12
13 /**
14 * Abstract implementation of a page with lists all categories of a certain object
15 * type.
16 *
17 * @author Matthias Schmidt
18 * @copyright 2001-2018 WoltLab GmbH
19 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
20 * @package WoltLabSuite\Core\Acp\Page
21 */
22 abstract class AbstractCategoryListPage extends AbstractPage {
23 /**
24 * name of the controller used to add new categories
25 * @var string
26 */
27 public $addController = '';
28
29 /**
30 * category node tree
31 * @var CategoryNodeTree
32 */
33 public $categoryNodeTree = null;
34
35 /**
36 * ids of collapsed categories
37 * @var integer[]
38 */
39 public $collapsedCategoryIDs = null;
40
41 /**
42 * id of the collapsible category object type
43 * @var integer
44 */
45 public $collapsibleObjectTypeID = 0;
46
47 /**
48 * name of the controller used to edit categories
49 * @var string
50 */
51 public $editController = '';
52
53 /**
54 * language item with the page title
55 * @var string
56 */
57 public $pageTitle = 'wcf.category.list';
58
59 /**
60 * category object type object
61 * @var ObjectType
62 */
63 public $objectType = null;
64
65 /**
66 * name of the category object type
67 * @var string
68 */
69 public $objectTypeName = '';
70
71 /**
72 * @inheritDoc
73 */
74 public $templateName = 'categoryList';
75
76 /**
77 * @inheritDoc
78 */
79 public function __run() {
80 $classNameParts = explode('\\', get_called_class());
81 $className = array_pop($classNameParts);
82
83 // autoset controllers
84 if (empty($this->addController)) {
85 $this->addController = str_replace('ListPage', 'Add', $className);
86 }
87 if (empty($this->editController)) {
88 $this->editController = str_replace('ListPage', 'Edit', $className);
89 }
90
91 parent::__run();
92 }
93
94 /**
95 * @inheritDoc
96 */
97 public function assignVariables() {
98 parent::assignVariables();
99
100 WCF::getTPL()->assign([
101 'addController' => $this->addController,
102 'categoryNodeList' => $this->categoryNodeTree->getIterator(),
103 'collapsedCategoryIDs' => $this->collapsedCategoryIDs,
104 'collapsibleObjectTypeID' => $this->collapsibleObjectTypeID,
105 'editController' => $this->editController,
106 'objectType' => $this->objectType
107 ]);
108
109 if ($this->pageTitle) {
110 WCF::getTPL()->assign('pageTitle', $this->pageTitle);
111 }
112 }
113
114 /**
115 * Checks if the active user has the needed permissions to view this list.
116 */
117 protected function checkCategoryPermissions() {
118 if (!$this->objectType->getProcessor()->canDeleteCategory() && !$this->objectType->getProcessor()->canEditCategory()) {
119 throw new PermissionDeniedException();
120 }
121 }
122
123 /**
124 * Reads the categories.
125 */
126 protected function readCategories() {
127 $this->categoryNodeTree = new CategoryNodeTree($this->objectType->objectType, 0, true);
128 }
129
130 /**
131 * @inheritDoc
132 */
133 public function readData() {
134 $this->objectType = CategoryHandler::getInstance()->getObjectTypeByName($this->objectTypeName);
135 if ($this->objectType === null) {
136 throw new InvalidObjectTypeException($this->objectTypeName, 'com.woltlab.wcf.category');
137 }
138
139 // check permissions
140 $this->checkCategoryPermissions();
141
142 $this->readCategories();
143
144 // note that the implementation of wcf\system\category\ICategoryType
145 // needs to support a object type of the pseudo definition
146 // 'com.woltlab.wcf.collapsibleContent.acp' which has to be registered
147 // during package installation as a 'com.woltlab.wcf.collapsibleContent'
148 // object type if you want to support collapsible categories in the
149 // acp; the pseudo object type is used to distinguish between
150 // collapsible categories in the frontend and the acp
151 $collapsibleObjectTypeName = $this->objectType->getProcessor()->getObjectTypeName('com.woltlab.wcf.collapsibleContent.acp');
152 if ($collapsibleObjectTypeName) {
153 $this->collapsibleObjectTypeID = UserCollapsibleContentHandler::getInstance()->getObjectTypeID($collapsibleObjectTypeName);
154 // get ids of collapsed category
155 if ($this->collapsibleObjectTypeID !== null) {
156 $this->collapsedCategoryIDs = UserCollapsibleContentHandler::getInstance()->getCollapsedContent($this->collapsibleObjectTypeID);
157 $this->collapsedCategoryIDs = array_flip($this->collapsedCategoryIDs);
158 }
159 }
160
161 parent::readData();
162 }
163 }