Apply PSR-12 code style (#3886)
[GitHub/WoltLab/WCF.git] / wcfsetup / install / files / lib / system / user / collapsible / content / UserCollapsibleContentHandler.class.php
CommitLineData
efc4e026 1<?php
a9229942 2
a8e8aa21 3namespace wcf\system\user\collapsible\content;
a9229942 4
efc4e026 5use wcf\data\object\type\ObjectTypeCache;
fc521fb9 6use wcf\system\database\util\PreparedStatementConditionBuilder;
79bbb75a 7use wcf\system\exception\InvalidObjectTypeException;
efc4e026 8use wcf\system\SingletonFactory;
a9229942 9use wcf\system\user\storage\UserStorageHandler;
efc4e026
AE
10use wcf\system\WCF;
11
12/**
13 * Provides methods for handling collapsible containers.
a9229942
TD
14 *
15 * @author Alexander Ebert
16 * @copyright 2001-2019 WoltLab GmbH
17 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
18 * @package WoltLabSuite\Core\System\User\Collapsible\Content
efc4e026 19 */
a9229942
TD
20class UserCollapsibleContentHandler extends SingletonFactory
21{
22 /**
23 * object type cache
24 * @var mixed[][]
25 */
26 protected $cache;
27
28 /**
29 * list of collapsed object ids per object type id
30 * @var int[][]
31 */
32 protected $collapsedContent = [];
33
34 /**
35 * @inheritDoc
36 */
37 protected function init()
38 {
39 $this->cache = [
40 'objectTypes' => [],
41 'objectTypeIDs' => [],
42 ];
43
44 $objectTypes = ObjectTypeCache::getInstance()->getObjectTypes('com.woltlab.wcf.collapsibleContent');
45 foreach ($objectTypes as $objectType) {
46 $this->cache['objectTypes'][$objectType->objectTypeID] = $objectType;
47 $this->cache['objectTypeIDs'][$objectType->objectType] = $objectType->objectTypeID;
48 }
49 }
50
51 /**
52 * Returns true if given object is collapsed.
53 *
54 * @param string $objectType
55 * @param string $objectID
56 * @return bool
57 * @throws InvalidObjectTypeException
58 */
59 public function isCollapsed($objectType, $objectID)
60 {
61 $objectTypeID = $this->getObjectTypeID($objectType);
62 if ($objectTypeID === null) {
63 throw new InvalidObjectTypeException($objectType, 'com.woltlab.wcf.collapsibleContent');
64 }
65
66 return \in_array($objectID, $this->getCollapsedContent($objectTypeID));
67 }
68
69 /**
70 * Returns the object type id based upon specified object type name. Returns
71 * null, if object type is unknown.
72 *
73 * @param string $objectType
74 * @return int
75 */
76 public function getObjectTypeID($objectType)
77 {
78 if (isset($this->cache['objectTypeIDs'][$objectType])) {
79 return $this->cache['objectTypeIDs'][$objectType];
80 }
81 }
82
83 /**
84 * Returns a list of object ids being collapsed by current user.
85 *
86 * @param int $objectTypeID
87 * @return int[]
88 */
89 public function getCollapsedContent($objectTypeID)
90 {
91 if (!isset($this->collapsedContent[$objectTypeID])) {
92 $this->collapsedContent[$objectTypeID] = [];
93
94 if (WCF::getUser()->userID) {
95 $data = UserStorageHandler::getInstance()->getField('collapsedContent-' . $objectTypeID);
96
97 // cache does not exist or is outdated
98 if ($data === null) {
99 $sql = "SELECT objectID
100 FROM wcf" . WCF_N . "_user_collapsible_content
101 WHERE objectTypeID = ?
102 AND userID = ?";
103 $statement = WCF::getDB()->prepareStatement($sql);
104 $statement->execute([
105 $objectTypeID,
106 WCF::getUser()->userID,
107 ]);
108 $this->collapsedContent[$objectTypeID] = $statement->fetchAll(\PDO::FETCH_COLUMN);
109
110 // update storage data
111 UserStorageHandler::getInstance()->update(
112 WCF::getUser()->userID,
113 'collapsedContent-' . $objectTypeID,
114 \serialize($this->collapsedContent[$objectTypeID])
115 );
116 } else {
117 $this->collapsedContent[$objectTypeID] = @\unserialize($data);
118 }
119 } else {
120 $collapsedContent = WCF::getSession()->getVar('collapsedContent');
121 if ($collapsedContent !== null && \is_array($collapsedContent)) {
122 if (isset($collapsedContent[$objectTypeID])) {
123 $this->collapsedContent[$objectTypeID] = $collapsedContent[$objectTypeID];
124 }
125 }
126 }
127 }
128
129 return $this->collapsedContent[$objectTypeID];
130 }
131
132 /**
133 * Marks content as collapsed.
134 *
135 * @param int $objectTypeID
136 * @param string $objectID
137 */
138 public function markAsCollapsed($objectTypeID, $objectID)
139 {
140 if (WCF::getUser()->userID) {
141 $sql = "SELECT *
142 FROM wcf" . WCF_N . "_user_collapsible_content
143 WHERE objectTypeID = ?
144 AND objectID = ?
145 AND userID = ?";
146 $statement = WCF::getDB()->prepareStatement($sql);
147 $statement->execute([
148 $objectTypeID,
149 $objectID,
150 WCF::getUser()->userID,
151 ]);
152 $row = $statement->fetchArray();
153
154 if (!$row) {
155 $sql = "INSERT INTO wcf" . WCF_N . "_user_collapsible_content
156 (objectTypeID, objectID, userID)
157 VALUES (?, ?, ?)";
158 $statement = WCF::getDB()->prepareStatement($sql);
159 $statement->execute([
160 $objectTypeID,
161 $objectID,
162 WCF::getUser()->userID,
163 ]);
164 }
165
166 // reset storage
167 UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'collapsedContent-' . $objectTypeID);
168 } else {
169 $collapsedContent = WCF::getSession()->getVar('collapsedContent');
170 if ($collapsedContent === null || !\is_array($collapsedContent)) {
171 $collapsedContent = [];
172 }
173
174 if (!\in_array($objectID, $collapsedContent)) {
175 $collapsedContent[$objectTypeID] = [];
176 }
177
178 $collapsedContent[$objectTypeID][] = $objectID;
179 WCF::getSession()->register('collapsedContent', $collapsedContent);
180 }
181 }
182
183 /**
184 * Marks content as opened, thus removing the collapsed marking.
185 *
186 * @param int $objectTypeID
187 * @param string $objectID
188 */
189 public function markAsOpened($objectTypeID, $objectID)
190 {
191 if (WCF::getUser()->userID) {
192 $sql = "DELETE FROM wcf" . WCF_N . "_user_collapsible_content
193 WHERE objectTypeID = ?
194 AND objectID = ?
195 AND userID = ?";
196 $statement = WCF::getDB()->prepareStatement($sql);
197 $statement->execute([
198 $objectTypeID,
199 $objectID,
200 WCF::getUser()->userID,
201 ]);
202
203 // reset storage
204 UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'collapsedContent-' . $objectTypeID);
205 } else {
206 $collapsedContent = WCF::getSession()->getVar('collapsedContent');
207 if ($collapsedContent === null || !\is_array($collapsedContent)) {
208 $collapsedContent = [];
209 }
210
211 if (isset($collapsedContent[$objectTypeID])) {
212 foreach ($collapsedContent[$objectTypeID] as $index => $collapsedObjectID) {
213 if ($collapsedObjectID == $objectID) {
214 unset($collapsedContent[$objectTypeID][$index]);
215 }
216 }
217 }
218
219 WCF::getSession()->register('collapsedContent', $collapsedContent);
220 }
221 }
222
223 /**
224 * Deletes all saved states for a specific object type.
225 *
226 * @param int $objectTypeID
227 */
228 public function reset($objectTypeID)
229 {
230 if (WCF::getUser()->userID) {
231 $sql = "DELETE FROM wcf" . WCF_N . "_user_collapsible_content
232 WHERE objectTypeID = ?
233 AND userID = ?";
234 $statement = WCF::getDB()->prepareStatement($sql);
235 $statement->execute([
236 $objectTypeID,
237 WCF::getUser()->userID,
238 ]);
239
240 // reset storage
241 UserStorageHandler::getInstance()->reset([WCF::getUser()->userID], 'collapsedContent-' . $objectTypeID);
242 } else {
243 $collapsedContent = WCF::getSession()->getVar('collapsedContent');
244 if ($collapsedContent === null || !\is_array($collapsedContent)) {
245 $collapsedContent = [];
246 }
247
248 if (isset($collapsedContent[$objectTypeID])) {
249 unset($collapsedContent[$objectTypeID]);
250 }
251
252 WCF::getSession()->register('collapsedContent', $collapsedContent);
253 }
254 }
255
256 /**
257 * Deletes the saved states for a specific object or all objects of a
258 * specific object type for all users.
259 *
260 * @param string $objectType
261 * @param int $objectID
262 * @throws InvalidObjectTypeException
263 */
264 public function resetAll($objectType, $objectID = null)
265 {
266 $objectTypeID = $this->getObjectTypeID($objectType);
267 if (!$objectTypeID) {
268 throw new InvalidObjectTypeException($objectType, 'com.woltlab.wcf.collapsibleContent');
269 }
270
271 $conditionBuilder = new PreparedStatementConditionBuilder();
272 $conditionBuilder->add('objectTypeID = ?', [$objectTypeID]);
273 if ($objectID) {
274 $conditionBuilder->add('objectID = ?', [$objectID]);
275 }
276
277 $sql = "DELETE FROM wcf" . WCF_N . "_user_collapsible_content
278 " . $conditionBuilder;
279 $statement = WCF::getDB()->prepareStatement($sql);
280 $statement->execute($conditionBuilder->getParameters());
281
282 UserStorageHandler::getInstance()->resetAll('collapsedContent-' . $objectTypeID);
283 }
efc4e026 284}