Merge pull request #5989 from WoltLab/wsc-rpc-api-const
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / data / category / CategoryEditor.class.php
CommitLineData
13d8b49b 1<?php
a9229942 2
13d8b49b 3namespace wcf\data\category;
a9229942 4
13d8b49b
MS
5use wcf\data\DatabaseObjectEditor;
6use wcf\data\IEditableCachedObject;
b401cd0d 7use wcf\system\cache\builder\CategoryCacheBuilder;
13d8b49b 8use wcf\system\category\CategoryHandler;
13d8b49b
MS
9use wcf\system\WCF;
10
11/**
12 * Provides functions to edit categories.
a9229942
TD
13 *
14 * @author Matthias Schmidt
15 * @copyright 2001-2019 WoltLab GmbH
16 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
a9229942
TD
17 *
18 * @method Category getDecoratedObject()
19 * @mixin Category
13d8b49b 20 */
a9229942
TD
21class CategoryEditor extends DatabaseObjectEditor implements IEditableCachedObject
22{
23 /**
24 * @inheritDoc
25 */
26 protected static $baseClass = Category::class;
27
28 /**
29 * Prepares the update of the show order of this category and return the
30 * correct new show order.
31 *
32 * @param int $parentCategoryID
33 * @param int $showOrder
34 * @return int
35 */
36 public function updateShowOrder($parentCategoryID, $showOrder)
37 {
38 // correct invalid values
39 if ($showOrder === null) {
40 $showOrder = \PHP_INT_MAX;
41 }
42
43 if ($parentCategoryID != $this->parentCategoryID) {
44 $sql = "UPDATE " . static::getDatabaseTableName() . "
45 SET showOrder = showOrder - 1
46 WHERE showOrder > ?
47 AND parentCategoryID = ?
48 AND objectTypeID = ?";
49 $statement = WCF::getDB()->prepareStatement($sql);
50 $statement->execute([
51 $this->showOrder,
52 $this->parentCategoryID,
53 $this->objectTypeID,
54 ]);
55
56 return static::getShowOrder($this->objectTypeID, $parentCategoryID, $showOrder);
57 } else {
58 if ($showOrder < $this->showOrder) {
59 $sql = "UPDATE " . static::getDatabaseTableName() . "
60 SET showOrder = showOrder + 1
61 WHERE showOrder >= ?
62 AND showOrder < ?
63 AND parentCategoryID = ?
64 AND objectTypeID = ?";
65 $statement = WCF::getDB()->prepareStatement($sql);
66 $statement->execute([
67 $showOrder,
68 $this->showOrder,
69 $this->parentCategoryID,
70 $this->objectTypeID,
71 ]);
72 } elseif ($showOrder > $this->showOrder) {
73 $sql = "SELECT MAX(showOrder) AS showOrder
74 FROM " . static::getDatabaseTableName() . "
75 WHERE objectTypeID = ?
76 AND parentCategoryID = ?";
77 $statement = WCF::getDB()->prepareStatement($sql);
78 $statement->execute([
79 $this->objectTypeID,
80 $this->parentCategoryID,
81 ]);
82 $row = $statement->fetchArray();
83 $maxShowOrder = 0;
84 if (!empty($row)) {
85 $maxShowOrder = \intval($row['showOrder']);
86 }
87
88 if ($showOrder > $maxShowOrder) {
89 $showOrder = $maxShowOrder;
90 }
91
92 $sql = "UPDATE " . static::getDatabaseTableName() . "
93 SET showOrder = showOrder - 1
94 WHERE showOrder <= ?
95 AND showOrder > ?
96 AND objectTypeID = ?";
97 $statement = WCF::getDB()->prepareStatement($sql);
98 $statement->execute([
99 $showOrder,
100 $this->showOrder,
101 $this->objectTypeID,
102 ]);
103 }
104
105 return $showOrder;
106 }
107 }
108
109 /**
110 * @inheritDoc
111 * @return Category
112 */
113 public static function create(array $parameters = [])
114 {
115 // default values
116 $parameters['time'] = $parameters['time'] ?? TIME_NOW;
117 $parameters['parentCategoryID'] = $parameters['parentCategoryID'] ?? 0;
118 $parameters['showOrder'] = $parameters['showOrder'] ?? null;
119
120 // handle show order
121 $parameters['showOrder'] = static::getShowOrder(
122 $parameters['objectTypeID'],
123 $parameters['parentCategoryID'],
124 $parameters['showOrder']
125 );
126
127 // handle additionalData
128 if (!isset($parameters['additionalData'])) {
129 $parameters['additionalData'] = \serialize([]);
130 }
131
132 /** @noinspection PhpIncompatibleReturnTypeInspection */
133 return parent::create($parameters);
134 }
135
136 /**
137 * @inheritDoc
138 */
139 public static function deleteAll(array $objectIDs = [])
140 {
141 // update positions
142 $sql = "UPDATE " . static::getDatabaseTableName() . "
143 SET showOrder = showOrder - 1
144 WHERE parentCategoryID = ?
145 AND showOrder > ?";
146 $statement = WCF::getDB()->prepareStatement($sql);
147
148 foreach ($objectIDs as $categoryID) {
149 $category = CategoryHandler::getInstance()->getCategory($categoryID);
150 $statement->execute([$category->parentCategoryID, $category->showOrder]);
151 }
152
153 return parent::deleteAll($objectIDs);
154 }
155
156 /**
157 * Returns the show order for a new category.
158 *
159 * @param int $objectTypeID
160 * @param int $parentCategoryID
161 * @param int $showOrder
162 * @return int
163 */
164 protected static function getShowOrder($objectTypeID, $parentCategoryID, $showOrder)
165 {
166 // correct invalid values
167 if ($showOrder === null) {
168 $showOrder = \PHP_INT_MAX;
169 }
170
171 $sql = "SELECT MAX(showOrder) AS showOrder
172 FROM " . static::getDatabaseTableName() . "
173 WHERE objectTypeID = ?
174 AND parentCategoryID = ?";
175 $statement = WCF::getDB()->prepareStatement($sql);
176 $statement->execute([
177 $objectTypeID,
178 $parentCategoryID,
179 ]);
180 $row = $statement->fetchArray();
181 $maxShowOrder = 0;
182 if (!empty($row)) {
183 $maxShowOrder = \intval($row['showOrder']);
184 }
185
186 if ($maxShowOrder && $showOrder <= $maxShowOrder) {
187 $sql = "UPDATE " . static::getDatabaseTableName() . "
188 SET showOrder = showOrder + 1
189 WHERE objectTypeID = ?
190 AND showOrder >= ?
191 AND parentCategoryID = ?";
192 $statement = WCF::getDB()->prepareStatement($sql);
193 $statement->execute([
194 $objectTypeID,
195 $showOrder,
196 $parentCategoryID,
197 ]);
198
199 return $showOrder;
200 }
201
202 return $maxShowOrder + 1;
203 }
204
205 /**
206 * @inheritDoc
207 */
208 public static function resetCache()
209 {
210 CategoryCacheBuilder::getInstance()->reset();
211 }
13d8b49b 212}