c54b8d999b149574bb5a54032361cacf4a5e79b9
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Persistence / Mapper / TX_EXTMVC_Persistence_Mapper_TcaMapper.php
1 <?php
2 declare(ENCODING = 'utf-8');
3
4 /* *
5 * This script belongs to the FLOW3 framework. *
6 * *
7 * It is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU Lesser General Public License as published by the *
9 * Free Software Foundation, either version 3 of the License, or (at your *
10 * option) any later version. *
11 * *
12 * This script is distributed in the hope that it will be useful, but *
13 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- *
14 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser *
15 * General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with the script. *
19 * If not, see http://www.gnu.org/licenses/lgpl.html *
20 * *
21 * The TYPO3 project - inspiring people to share! *
22 * */
23
24 require_once(PATH_t3lib . 'interfaces/interface.t3lib_singleton.php');
25 require_once(t3lib_extMgm::extPath('extmvc') . 'Classes/Utility/TX_EXTMVC_Utility_Strings.php');
26
27 /**
28 * A mapper to map database tables configured in $TCA onto domain objects.
29 *
30 * @version $Id:$
31 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later
32 */
33 class TX_EXTMVC_Persistence_Mapper_TcaMapper implements t3lib_singleton {
34
35 /**
36 * The content object
37 *
38 * @var tslib_cObj
39 **/
40 protected $cObj;
41
42 /**
43 * The persistence session
44 *
45 * @var
46 **/
47 protected $session;
48
49 /**
50 * Constructs a new mapper
51 *
52 * @author Jochen Rau <jochen.rau@typoplanet.de>
53 */
54 public function __construct() {
55 $this->cObj = t3lib_div::makeInstance('tslib_cObj');
56 $this->session = t3lib_div::makeInstance('TX_EXTMVC_Persistence_Session');
57 $GLOBALS['TSFE']->includeTCA();
58 }
59
60 /**
61 * Finds objects matching property="xyz"
62 *
63 * @param string $propertyName The name of the property (will be chekced by a white list)
64 * @param string $arguments The WHERE statement
65 * @return void
66 * @author Jochen Rau <jochen.rau@typoplanet.de>
67 */
68 public function findWhere($className, $where = '1=1') {
69 return $this->reconstituteObjects($className, $this->fetch($className, $where));
70 }
71
72 /**
73 * Fetches a rows from the database by given SQL statement snippets
74 *
75 * @param string $from FROM statement
76 * @param string $where WHERE statement
77 * @param string $groupBy GROUP BY statement
78 * @param string $orderBy ORDER BY statement
79 * @param string $limit LIMIT statement
80 * @return void
81 * @author Jochen Rau <jochen.rau@typoplanet.de>
82 */
83 public function fetch($className, $where = '1=1', $groupBy = NULL, $orderBy = NULL, $limit = NULL) {
84 $tableName = $this->getTableName($className);
85 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
86 '*', // TODO limit fetched fields
87 $tableName,
88 $where . $this->cObj->enableFields($tableName) . $this->cObj->enableFields($tableName),
89 $groupBy,
90 $orderBy,
91 $limit
92 );
93 // TODO language overlay; workspace overlay
94 return $rows ? $rows : array();
95 }
96
97 /**
98 * Fetches a rows from the database by given SQL statement snippets
99 *
100 * @author Jochen Rau <jochen.rau@typoplanet.de>
101 */
102 public function fetchOneToMany($parentObject, $parentField, $tableName, $where = '', $groupBy = NULL, $orderBy = NULL, $limit = NULL) {
103 $where .= ' ' . $parentField . '=' . intval($parentObject->getUid());
104 return $this->fetch($tableName, $where, $groupBy, $orderBy, $limit);
105 }
106
107 /**
108 * Fetches a rows from the database by given SQL statement snippets
109 *
110 * @author Jochen Rau <jochen.rau@typoplanet.de>
111 */
112 public function fetchManyToMany($parentObject, $foreignTableName, $relationTableName, $where = '1=1', $groupBy = NULL, $orderBy = NULL, $limit = NULL) {
113 $rows = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
114 $foreignTableName . '.*, ' . $relationTableName . '.*',
115 $foreignTableName . ' LEFT JOIN ' . $relationTableName . ' ON (' . $foreignTableName . '.uid=' . $relationTableName . '.uid_foreign)',
116 $where . ' AND ' . $relationTableName . '.uid_local=' . intval($parentObject->getUid()) . $this->cObj->enableFields($foreignTableName) . $this->cObj->enableFields($foreignTableName),
117 $groupBy,
118 $orderBy,
119 $limit
120 );
121 // TODO language overlay; workspace overlay
122 return $rows ? $rows : array();
123 }
124
125 /**
126 * Dispatches the reconstitution of a domain object to an appropriate method
127 *
128 * @param array $rows The rows array fetched from the database
129 * @throws TX_EXTMVC_Persistence_Exception_RecursionTooDeep
130 * @return array An array of reconstituted domain objects
131 * @author Jochen Rau <jochen.rau@typoplanet.de>
132 */
133 protected function reconstituteObjects($className, array $rows) {
134 // TODO if ($depth > 10) throw new TX_EXTMVC_Persistence_Exception_RecursionTooDeep('The maximum depth of ' . $depth . ' recursions was reached.', 1233352348);
135 foreach ($rows as $row) {
136 $propertiesToReconstitute = array();
137 foreach ($row as $fieldName => $fieldValue) {
138 $propertyName = TX_EXTMVC_Utility_Strings::underscoredToLowerCamelCase($fieldName);
139 $propertiesToReconstitute[$propertyName] = $this->convertFieldValueToPropertyValue($className, $propertyName, $fieldValue);
140 }
141 $object = $this->reconstituteObject($className, $propertiesToReconstitute);
142 $properties = $object->_getProperties();
143 foreach ($properties as $propertyName => $propertyValue) {
144 if ($this->isOneToManyRelation($className, $propertyName)) {
145 $relatedRows = $this->fetchOneToMany($object, $this->getForeignUidField($className, $propertyName), $this->getForeignTableName($className, $propertyName));
146 $relatedObjects = $this->reconstituteObjects($this->getForeignClass($className, $propertyName), $relatedRows, $depth);
147 $object->_reconstituteProperty($propertyName, $relatedObjects);
148 } elseif ($this->isManyToManyRelation($className, $propertyName)) {
149 $relatedRows = $this->fetchManyToMany($object, $this->getForeignTableName($className, $propertyName), $this->getRelationTableName($className, $propertyName));
150 $relatedObjects = $this->reconstituteObjects($this->getForeignClass($className, $propertyName), $relatedRows, $depth);
151 $object->_reconstituteProperty($propertyName, $relatedObjects);
152 }
153 }
154 $this->session->registerReconstitutedObject($object);
155 $objects[] = $object;
156 }
157 return $objects;
158 }
159
160 /**
161 * Reconstitutes the specified object and fills it with the given properties.
162 *
163 * @param string $objectName Name of the object to reconstitute
164 * @param array $properties The names of properties and their values which should be set during the reconstitution
165 * @return object The reconstituted object
166 * @author Robert Lemke <robert@typo3.org>
167 */
168 protected function reconstituteObject($className, array $properties = array()) {
169 // those objects will be fetched from within the __wakeup() method of the object...
170 $GLOBALS['EXTMVC']['reconstituteObject']['properties'] = $properties;
171 $object = unserialize('O:' . strlen($className) . ':"' . $className . '":0:{};');
172 unset($GLOBALS['EXTMVC']['reconstituteObject']);
173 return $object;
174 }
175
176 /**
177 * Persists all objects of a persistence session
178 *
179 * @param string $session The persistence session
180 * @return void
181 * @author Jochen Rau <jochen.rau@typoplanet.de>
182 */
183 public function persistAll($session) {
184 $this->session = $session;
185
186 // first, persit all aggregate root objects
187 $aggregateRootClassNames = $this->session->getAggregateRootClassNames();
188 foreach ($aggregateRootClassNames as $className) {
189 $this->persistObjects($className);
190 }
191
192 // persist all remaining objects
193 $this->persistObjects();
194 }
195
196 /**
197 * Persists all objects of a persitance session that are of a given class. If there
198 * is no class specified, it persits all objects of a session.
199 *
200 * @param string $className Name of the class of the objects to be persisted
201 * @author Jochen Rau <jochen.rau@typoplanet.de>
202 */
203 protected function persistObjects($className = NULL) {
204 foreach ($this->session->getAddedObjects($className) as $object) {
205 $this->insertObject($object);
206 $this->session->unregisterAddedObject($object);
207 }
208 foreach ($this->session->getDirtyObjects($className) as $object) {
209 $this->updateObject($object);
210 $this->session->unregisterObject($object); // TODO is this necessary?
211 $this->session->registerReconstitutedObject($object);
212 }
213 foreach ($this->session->getRemovedObjects($className) as $object) {
214 $this->deleteObject($object);
215 $this->session->unregisterRemovedObject($object);
216 }
217 }
218
219 /**
220 * Inserts an object to the database.
221 *
222 * @return void
223 * @author Karsten Dambekalns <karsten@typo3.org>
224 * @author Jochen Rau <jochen.rau@typoplanet.de>
225 */
226 public function insertObject(TX_EXTMVC_DomainObject_AbstractDomainObject $object, $parentObject = NULL, $parentPropertyName = NULL) {
227 $queuedRelations = array();
228 $rowToInsert = array();
229 $properties = $object->_getProperties();
230 foreach ($properties as $propertyName => $propertyValue) {
231 if ($this->isOneToManyRelation(get_class($object), $propertyName)) {
232 $queuedRelations = t3lib_div::array_merge_recursive_overrule($queuedRelations, array($propertyName => $propertyValue));
233 $rowToInsert[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)] = count($properties[$propertyName]);
234 } elseif ($this->isManyToManyRelation(get_class($object), $propertyName)) {
235 $queuedRelations = t3lib_div::array_merge_recursive_overrule($queuedRelations, array($propertyName => $propertyValue));
236 $rowToInsert[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)] = count($properties[$propertyName]);
237 } else {
238 $rowToInsert[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)] = $this->convertPropertyValueToFieldValue($propertyValue);
239 }
240 }
241
242 $rowToInsert['pid'] = 0; // FIXME
243 $rowToInsert['tstamp'] = time();
244 if ($parentObject !== NULL && $parentPropertyName !== NULL) {
245 $foreignUidfield = $this->getForeignUidField(get_class($parentObject), $parentPropertyName);
246 if ($foreignUidfield !== NULL) {
247 $rowToInsert[$foreignUidfield] = $parentObject->getUid();
248 }
249 $foreignTablefield = $this->getForeignTableField(get_class($parentObject), $parentPropertyName);
250 if ($foreignTablefield !== NULL) {
251 $rowToInsert[$foreignTablefield] = $this->getTableName(get_class($parentObject));
252 }
253 }
254 $tableName = $this->getTableName(get_class($object));
255 $res = $GLOBALS['TYPO3_DB']->exec_INSERTquery(
256 $tableName,
257 $rowToInsert
258 );
259
260 $object->_reconstituteProperty('uid', $GLOBALS['TYPO3_DB']->sql_insert_id());
261 // var_dump($object);
262
263 foreach ($queuedRelations as $propertyName => $relatedObjects) {
264 foreach ($relatedObjects as $relatedObject) {
265 if (!$this->session->isReconstitutedObject($relatedObject)) {
266 $this->insertObject($relatedObject, $object, $propertyName);
267 if ($this->isManyToManyRelation(get_class($object), $propertyName)) {
268 $this->insertRelation($object, $propertyName, $relatedObject);
269 }
270 }
271 }
272 }
273
274 }
275
276 /**
277 * Updates a modified object in the database
278 *
279 * @return void
280 * @author Karsten Dambekalns <karsten@typo3.org>
281 * @author Jochen Rau <jochen.rau@typoplanet.de>
282 */
283 public function updateObject(TX_EXTMVC_DomainObject_AbstractDomainObject $object, $parentObject = NULL, $parentPropertyName = NULL) {
284 $queuedRelations = array();
285 $fieldsToUpdate = array();
286 $properties = $object->_getDirtyProperties();
287 foreach ($properties as $propertyName => $propertyValue) {
288 if ($this->isOneToManyRelation(get_class($object), $propertyName)) {
289 $queuedRelations = t3lib_div::array_merge_recursive_overrule($queuedRelations, array($propertyName => $propertyValue));
290 $fieldsToUpdate[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)] = count($properties[$propertyName]);
291 } elseif ($this->isManyToManyRelation(get_class($object), $propertyName)) {
292 $queuedRelations = t3lib_div::array_merge_recursive_overrule($queuedRelations, array($propertyName => $propertyValue));
293 $fieldsToUpdate[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)] = count($properties[$propertyName]);
294 } else {
295 $fieldsToUpdate[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)] = $this->convertPropertyValueToFieldValue($propertyValue);
296 }
297 }
298
299 $fieldsToUpdate['crdate'] = time();
300 if (!empty($GLOBALS['TSFE']->fe_user->user['uid'])) {
301 $fieldsToUpdate['cuser_id'] = $GLOBALS['TSFE']->fe_user->user['uid'];
302 }
303 if ($parentObject !== NULL && $parentPropertyName !== NULL) {
304 $foreignUidfield = $this->getForeignUidField(get_class($parentObject), $parentPropertyName);
305 if ($foreignUidfield !== NULL) {
306 $fieldsToUpdate[$foreignUidfield] = $parentObject->getUid();
307 }
308 $foreignTablefield = $this->getForeignTableField(get_class($parentObject), $parentPropertyName);
309 if ($foreignTablefield !== NULL) {
310 $fieldsToUpdate[$foreignTablefield] = $this->getTableName(get_class($parentObject));
311 }
312 }
313 $tableName = $this->getTableName(get_class($object));
314 $res = $GLOBALS['TYPO3_DB']->exec_UPDATEquery(
315 $tableName,
316 'uid=' . $object->getUid(),
317 $fieldsToUpdate
318 );
319
320 // var_dump($object);
321
322 foreach ($queuedRelations as $propertyName => $relatedObjects) {
323 foreach ($relatedObjects as $relatedObject) {
324 if (!$this->session->isReconstitutedObject($relatedObject)) {
325 $this->insertObject($relatedObject, $object, $propertyName);
326 if ($this->isManyToManyRelation(get_class($object), $propertyName)) {
327 $this->insertRelation($object, $propertyName, $relatedObject);
328 }
329 }
330 }
331 }
332
333 }
334
335 /**
336 * Inserts relation to a relation table
337 *
338 * @param TX_EXTMVC_DomainObject_AbstractDomainObject $parentObject The parent object
339 * @param string $parentPropertyName The name of the parent object's property where the related objects are stored in
340 * @param TX_EXTMVC_DomainObject_AbstractDomainObject $relatedObject The related object
341 * @return void
342 * @author Jochen Rau <jochen.rau@typoplanet.de>
343 */
344 protected function insertRelation(TX_EXTMVC_DomainObject_AbstractDomainObject $parentObject, $parentPropertyName, TX_EXTMVC_DomainObject_AbstractDomainObject $relatedObject) {
345 $rowToInsert = array(
346 'uid_local' => $parentObject->getUid(),
347 'uid_foreign' => $relatedObject->getUid(),
348 'tablenames' => $this->getTableName(get_class($parentObject)),
349 'sorting' => 9999 // TODO sorting of mm table items
350 );
351 $tableName = $this->getRelationTableName(get_class($parentObject), $parentPropertyName);
352 $res = $GLOBALS['TYPO3_DB']->exec_INSERTquery(
353 $tableNamew,
354 $rowToInsert
355 );
356 }
357
358 /**
359 * Deletes an object
360 *
361 * @return void
362 * @author Jochen Rau <jochen.rau@typoplanet.de>
363 */
364 public function deleteObject(TX_EXTMVC_DomainObject_AbstractDomainObject $object, $onlyMarkAsDeleted = TRUE) {
365 // TODO implement delete object
366 }
367
368 /**
369 * Returns all columns configured in $TCA for a given class
370 *
371 * @param string $className The class name
372 * @return array The column configurations from $TCA
373 * @author Jochen Rau <jochen.rau@typoplanet.de>
374 */
375 protected function getColumns($className) {
376 $tableName = $this->getTableName($className);
377 t3lib_div::loadTCA($tableName);
378 return $GLOBALS['TCA'][$tableName]['columns'];
379 }
380
381 /**
382 * Returns a table name for a given class
383 *
384 * @param string $className The class name
385 * @return string The table name
386 * @author Jochen Rau <jochen.rau@typoplanet.de>
387 */
388 protected function getTableName($className) {
389 // TODO implement table name aliases
390 return strtolower($className);
391 }
392
393 /**
394 * Returns the name of a column indicating the 'deleted' state of the row
395 *
396 * @param string $className The class name
397 * @return string The class name
398 * @author Jochen Rau <jochen.rau@typoplanet.de>
399 */
400 protected function getDeletedColumnName($className) {
401 $this->getTableName($className);
402 return $GLOBALS['TCA'][$tableName]['ctrl']['delete'];
403 }
404
405 /**
406 * Returns the name of a column indicating the 'hidden' state of the row
407 *
408 * @param string $className The class name
409 * @author Jochen Rau <jochen.rau@typoplanet.de>
410 */
411 protected function getHiddenColumnName($className) {;
412 $this->getTableName($className);
413 return $GLOBALS['TCA'][$tableName]['ctrl']['enablecolumns']['disabled'];
414 }
415
416 /**
417 * Returns TRUE if the given property corresponds to one to many relation in the database
418 *
419 * @param string $className The class name
420 * @param string $propertyName The property name
421 * @return boolean TRUE if the given property corresponds to one to many relation in the database
422 * @author Jochen Rau <jochen.rau@typoplanet.de>
423 */
424 protected function isOneToManyRelation($className, $propertyName) {
425 $columns = $this->getColumns($this->getTableName($className));
426 $columnConfiguration = $columns[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)]['config'];
427 if (array_key_exists('foreign_table', $columnConfiguration) && !array_key_exists('MM', $columnConfiguration)) return TRUE;
428 return FALSE;
429 }
430
431 /**
432 * Returns TRUE if the given property corresponds to many to many relation in the database
433 *
434 * @param string $className The class name
435 * @param string $propertyName The property name
436 * @return boolean TRUE if the given property corresponds to many to many relation in the database
437 * @author Jochen Rau <jochen.rau@typoplanet.de>
438 */
439 protected function isManyToManyRelation($className, $propertyName) {
440 $columns = $this->getColumns($this->getTableName($className));
441 $columnConfiguration = $columns[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)]['config'];
442 if (array_key_exists('foreign_table', $columnConfiguration) && array_key_exists('MM', $columnConfiguration)) return TRUE;
443 return FALSE;
444 }
445
446 /**
447 * Returns the foreign class name for a given parent class and property
448 *
449 * @param string $className The class name
450 * @param string $propertyName The property name
451 * @return string The foreign class name
452 * @author Jochen Rau <jochen.rau@typoplanet.de>
453 */
454 protected function getForeignClass($className, $propertyName) {
455 $columns = $this->getColumns($this->getTableName($className));
456 return $columns[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)]['config']['foreign_class'];
457 }
458
459 /**
460 * Returns the foreign table name for a given parent class and property
461 *
462 * @param string $className The class name
463 * @param string $propertyName The property name
464 * @return string The foreign table name
465 * @author Jochen Rau <jochen.rau@typoplanet.de>
466 */
467 protected function getForeignTableName($className, $propertyName) {
468 $columns = $this->getColumns($this->getTableName($className));
469 return $columns[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)]['config']['foreign_table'];
470 }
471
472 /**
473 * Returns the foreign uid field name for a given parent class and property
474 *
475 * @param string $className The class name
476 * @param string $propertyName The property name
477 * @return string The foreign uid field name
478 * @author Jochen Rau <jochen.rau@typoplanet.de>
479 */
480 protected function getForeignUidField($className, $propertyName) {
481 $columns = $this->getColumns($this->getTableName($className));
482 return $columns[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)]['config']['foreign_field'];
483 }
484
485 /**
486 * Returns the foreign table field name for a given parent class and property
487 *
488 * @param string $className The class name
489 * @param string $propertyName The property name
490 * @return string The foreign table field name
491 * @author Jochen Rau <jochen.rau@typoplanet.de>
492 */
493 protected function getForeignTableField($className, $propertyName) {
494 $columns = $this->getColumns($this->getTableName($className));
495 return $columns[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)]['config']['foreign_table_field'];
496 }
497
498 /**
499 * Returns the relation table name for a given parent class and property
500 *
501 * @param string $className The class name
502 * @param string $propertyName The property name
503 * @return string The relation table name
504 * @author Jochen Rau <jochen.rau@typoplanet.de>
505 */
506 protected function getRelationTableName($className, $propertyName) {
507 $columns = $this->getColumns($this->getTableName($className));
508 return $columns[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)]['config']['MM'];
509 }
510
511 /**
512 * Returns TRUE if the property of a given class is of type date (as configured in $TCA)
513 *
514 * @param string $className The class name
515 * @param string $propertyName The property name
516 * @return boolean TRUE if the property of a given class is of type date (as configured in $TCA)
517 * @author Jochen Rau <jochen.rau@typoplanet.de>
518 */
519 protected function isOfTypeDate($className, $propertyName) {
520 $columns = $this->getColumns($this->getTableName($className));
521 return strpos($columns[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)]['config']['eval'], 'date') !== FALSE
522 || strpos($columns[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)]['config']['eval'], 'datetime') !== FALSE;
523 }
524
525 /**
526 * Returns TRUE if the property of a given class is of type boolean (as configured in $TCA)
527 *
528 * @param string $className The class name
529 * @param string $propertyName The property name
530 * @return boolean TRUE if the property of a given class is of type boolean (as configured in $TCA)
531 * @author Jochen Rau <jochen.rau@typoplanet.de>
532 */
533 protected function isOfTypeBoolean($className, $propertyName) {
534 $columns = $this->getColumns($this->getTableName($className));
535 return $columns[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)]['config']['type'] === 'check'
536 && empty($columns[TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName)]['config']['items']);
537 }
538
539 /**
540 * Returns TRUE if the property is persistable (configured in $TCA)
541 *
542 * @param string $className The class name
543 * @param string $propertyName The property name
544 * @return boolean TRUE if the property is persistable (configured in $TCA)
545 * @author Jochen Rau <jochen.rau@typoplanet.de>
546 */
547 public function isPersistableProperty($className, $propertyName) {
548 $columns = $this->getColumns($this->getTableName($className));
549 if (array_key_exists(TX_EXTMVC_Utility_Strings::camelCaseToLowerCaseUnderscored($propertyName), $columns)) return TRUE;
550 return FALSE;
551 }
552
553 /**
554 * Converts a value from a database field type to a property type
555 *
556 * @param string $className The class name
557 * @param string $propertyName The property name
558 * @param mixed $fieldValue The field value
559 * @return mixed The converted value
560 * @author Jochen Rau <jochen.rau@typoplanet.de>
561 */
562 protected function convertFieldValueToPropertyValue($className, $propertyName, $fieldValue) {
563 if ($this->isOfTypeDate($className, $propertyName)) {
564 $convertedValue = new DateTime(strftime('%Y-%m-%d %H:%M', $fieldValue), new DateTimeZone('UTC'));
565 } elseif ($this->isOfTypeBoolean($className, $propertyName)) {
566 if ($fieldValue === '0') {
567 $convertedValue = FALSE;
568 } else {
569 $convertedValue = TRUE;
570 }
571 } else {
572 $convertedValue = $fieldValue;
573 }
574 return $convertedValue;
575 }
576
577 /**
578 * Converts a value from a property type to a database field type
579 *
580 * @param mixed $propertyValue The property value
581 * @return mixed The converted value
582 * @author Jochen Rau <jochen.rau@typoplanet.de>
583 */
584 protected function convertPropertyValueToFieldValue($propertyValue) {
585 if ($propertyValue instanceof DateTime) {
586 $convertedValue = $propertyValue->format('U');
587 } elseif (is_bool($propertyValue)) {
588 $convertedValue = $propertyValue ? 1 : 0;
589 } else {
590 $convertedValue = $propertyValue;
591 }
592 return $convertedValue;
593 }
594
595 }
596 ?>