[CLEANUP] Code cleanup in ext:core/Collection
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Collection / AbstractRecordCollection.php
1 <?php
2 namespace TYPO3\CMS\Core\Collection;
3
4 /**
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * Abstract implementation of a RecordCollection
19 *
20 * RecordCollection is a collections of TCA-Records.
21 * The collection is meant to be stored in TCA-table sys_collections and is manageable
22 * via TCEforms.
23 *
24 * A RecordCollection might be used to group a set of records (e.g. news, images, contentElements)
25 * for output in frontend
26 *
27 * The AbstractRecordCollection uses SplDoublyLinkedList for internal storage
28 *
29 * @author Steffen Ritter <typo3@steffen-ritter.net>
30 */
31 abstract class AbstractRecordCollection implements RecordCollectionInterface, PersistableCollectionInterface, SortableCollectionInterface {
32
33 /**
34 * The table name collections are stored to
35 *
36 * @var string
37 */
38 static protected $storageTableName = 'sys_collection';
39
40 /**
41 * The table name collections are stored to
42 *
43 * @var string
44 */
45 static protected $storageItemsField = 'items';
46
47 /**
48 * Uid of the storage
49 *
50 * @var int
51 */
52 protected $uid = 0;
53
54 /**
55 * Collection title
56 *
57 * @var string
58 */
59 protected $title;
60
61 /**
62 * Collection description
63 *
64 * @var string
65 */
66 protected $description;
67
68 /**
69 * Table name of the records stored in this collection
70 *
71 * @var string
72 */
73 protected $itemTableName;
74
75 /**
76 * The local storage
77 *
78 * @var \SplDoublyLinkedList
79 */
80 protected $storage;
81
82 /**
83 * Creates this object.
84 */
85 public function __construct() {
86 $this->storage = new \SplDoublyLinkedList();
87 }
88
89 /**
90 * (PHP 5 >= 5.1.0)
91 * Return the current element
92 *
93 * @link http://php.net/manual/en/iterator.current.php
94 * @return mixed Can return any type.
95 */
96 public function current() {
97 return $this->storage->current();
98 }
99
100 /**
101 * (PHP 5 >= 5.1.0)
102 * Move forward to next element
103 *
104 * @link http://php.net/manual/en/iterator.next.php
105 * @return void Any returned value is ignored.
106 */
107 public function next() {
108 $this->storage->next();
109 }
110
111 /**
112 * (PHP 5 >= 5.1.0)
113 * Return the key of the current element
114 *
115 * @link http://php.net/manual/en/iterator.key.php
116 * @return int 0 on failure.
117 */
118 public function key() {
119 $currentRecord = $this->storage->current();
120 return $currentRecord['uid'];
121 }
122
123 /**
124 * (PHP 5 >= 5.1.0)
125 * Checks if current position is valid
126 *
127 * @link http://php.net/manual/en/iterator.valid.php
128 * @return bool The return value will be casted to boolean and then evaluated.
129 */
130 public function valid() {
131 return $this->storage->valid();
132 }
133
134 /**
135 * (PHP 5 >= 5.1.0)
136 * Rewind the Iterator to the first element
137 *
138 * @link http://php.net/manual/en/iterator.rewind.php
139 * @return void Any returned value is ignored.
140 */
141 public function rewind() {
142 $this->storage->rewind();
143 }
144
145 /**
146 * (PHP 5 >= 5.1.0)
147 * String representation of object
148 *
149 * @link http://php.net/manual/en/serializable.serialize.php
150 * @return string the string representation of the object or &null;
151 */
152 public function serialize() {
153 $data = array(
154 'uid' => $this->getIdentifier()
155 );
156 return serialize($data);
157 }
158
159 /**
160 * (PHP 5 >= 5.1.0)
161 * Constructs the object
162 *
163 * @link http://php.net/manual/en/serializable.unserialize.php
164 * @param string $serialized The string representation of the object
165 * @return mixed the original value unserialized.
166 */
167 public function unserialize($serialized) {
168 $data = unserialize($serialized);
169 return self::load($data['uid']);
170 }
171
172 /**
173 * (PHP 5 >= 5.1.0)
174 * Count elements of an object
175 *
176 * @link http://php.net/manual/en/countable.count.php
177 * @return int The custom count as an integer.
178 */
179 public function count() {
180 return $this->storage->count();
181 }
182
183 /**
184 * Getter for the title
185 *
186 * @return string
187 */
188 public function getTitle() {
189 return $this->title;
190 }
191
192 /**
193 * Getter for the UID
194 *
195 * @return int
196 */
197 public function getUid() {
198 return $this->uid;
199 }
200
201 /**
202 * Getter for the description
203 *
204 * @return string
205 */
206 public function getDescription() {
207 return $this->description;
208 }
209
210 /**
211 * Setter for the title
212 *
213 * @param string $title
214 * @return void
215 */
216 public function setTitle($title) {
217 $this->title = $title;
218 }
219
220 /**
221 * Setter for the description
222 *
223 * @param string $desc
224 * @return void
225 */
226 public function setDescription($desc) {
227 $this->description = $desc;
228 }
229
230 /**
231 * Setter for the name of the data-source table
232 *
233 * @return string
234 */
235 public function getItemTableName() {
236 return $this->itemTableName;
237 }
238
239 /**
240 * Setter for the name of the data-source table
241 *
242 * @param string $tableName
243 * @return void
244 */
245 public function setItemTableName($tableName) {
246 $this->itemTableName = $tableName;
247 }
248
249 /**
250 * Sorts collection via given callBackFunction
251 *
252 * The comparison function given as must return an integer less than, equal to, or greater than
253 * zero if the first argument is considered to be respectively less than, equal to, or greater than the second.
254 *
255 * @param $callbackFunction
256 * @see http://www.php.net/manual/en/function.usort.php
257 * @return void
258 */
259 public function usort($callbackFunction) {
260 // TODO: Implement usort() method with TCEforms in mind
261 throw new \RuntimeException('This method is not yet supported.', 1322545589);
262 }
263
264 /**
265 * Moves the item within the collection
266 *
267 * the item at $currentPosition will be moved to
268 * $newPosition. Omiting $newPosition will move to top.
269 *
270 * @param int $currentPosition
271 * @param int $newPosition
272 * @return void
273 */
274 public function moveItemAt($currentPosition, $newPosition = 0) {
275 // TODO: Implement usort() method with TCEforms in mind
276 throw new \RuntimeException('This method is not yet supported.', 1322545626);
277 }
278
279 /**
280 * Returns the uid of the collection
281 *
282 * @return int
283 */
284 public function getIdentifier() {
285 return $this->uid;
286 }
287
288 /**
289 * Sets the identifier of the collection
290 *
291 * @param int $id
292 * @return void
293 */
294 public function setIdentifier($id) {
295 $this->uid = (int)$id;
296 }
297
298 /**
299 * Loads the collections with the given id from persistence
300 *
301 * For memory reasons, per default only f.e. title, database-table,
302 * identifier (what ever static data is defined) is loaded.
303 * Entries can be load on first access.
304 *
305 * @param int $id Id of database record to be loaded
306 * @param bool $fillItems Populates the entries directly on load, might be bad for memory on large collections
307 * @return \TYPO3\CMS\Core\Collection\CollectionInterface
308 */
309 static public function load($id, $fillItems = FALSE) {
310 $collectionRecord = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
311 '*',
312 static::$storageTableName,
313 'uid=' . (int)$id . \TYPO3\CMS\Backend\Utility\BackendUtility::deleteClause(static::$storageTableName)
314 );
315 return self::create($collectionRecord, $fillItems);
316 }
317
318 /**
319 * Creates a new collection objects and reconstitutes the
320 * given database record to the new object.
321 *
322 * @param array $collectionRecord Database record
323 * @param bool $fillItems Populates the entries directly on load, might be bad for memory on large collections
324 * @return \TYPO3\CMS\Core\Collection\CollectionInterface
325 */
326 static public function create(array $collectionRecord, $fillItems = FALSE) {
327 $collection = new static();
328 $collection->fromArray($collectionRecord);
329 if ($fillItems) {
330 $collection->loadContents();
331 }
332 return $collection;
333 }
334
335 /**
336 * Persists current collection state to underlying storage
337 *
338 * @return void
339 */
340 public function persist() {
341 $uid = $this->getIdentifier() == 0 ? 'NEW' . rand(100000, 999999) : $this->getIdentifier();
342 $data = array(
343 trim(static::$storageTableName) => array(
344 $uid => $this->getPersistableDataArray()
345 )
346 );
347 // New records always must have a pid
348 if ($this->getIdentifier() == 0) {
349 $data[trim(static::$storageTableName)][$uid]['pid'] = 0;
350 }
351 /** @var \TYPO3\CMS\Core\DataHandling\DataHandler $tce */
352 $tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\DataHandling\\DataHandler');
353 $tce->stripslashes_values = 0;
354 $tce->start($data, array());
355 $tce->process_datamap();
356 }
357
358 /**
359 * Returns an array of the persistable properties and contents
360 * which are processable by TCEmain.
361 *
362 * For internal usage in persist only.
363 *
364 * @return array
365 */
366 abstract protected function getPersistableDataArray();
367
368 /**
369 * Generates comma-separated list of entry uids for usage in TCEmain
370 *
371 * also allow to add table name, if it might be needed by TCEmain for
372 * storing the relation
373 *
374 * @param bool $includeTableName
375 * @return string
376 */
377 protected function getItemUidList($includeTableName = TRUE) {
378 $list = array();
379 foreach ($this->storage as $entry) {
380 $list[] = ($includeTableName ? $this->getItemTableName() . '_' : '') . $entry['uid'];
381 }
382 return implode(',', $list);
383 }
384
385 /**
386 * Builds an array representation of this collection
387 *
388 * @return array
389 */
390 public function toArray() {
391 $itemArray = array();
392 foreach ($this->storage as $item) {
393 $itemArray[] = $item;
394 }
395 return array(
396 'uid' => $this->getIdentifier(),
397 'title' => $this->getTitle(),
398 'description' => $this->getDescription(),
399 'table_name' => $this->getItemTableName(),
400 'items' => $itemArray
401 );
402 }
403
404 /**
405 * Loads the properties of this collection from an array
406 *
407 * @param array $array
408 * @return void
409 */
410 public function fromArray(array $array) {
411 $this->uid = $array['uid'];
412 $this->title = $array['title'];
413 $this->description = $array['description'];
414 $this->itemTableName = $array['table_name'];
415 }
416
417 }