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