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> | |
a9229942 TD |
17 | * |
18 | * @method Category getDecoratedObject() | |
19 | * @mixin Category | |
13d8b49b | 20 | */ |
a9229942 TD |
21 | class 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 | } |