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