TYPO3 CMS  TYPO3_6-2
DataMapFactory.php
Go to the documentation of this file.
1 <?php
3 
21 
26  protected $reflectionService;
27 
33 
38  protected $objectManager;
39 
44  protected $cacheManager;
45 
49  protected $dataMapCache;
50 
56  public function initializeObject() {
57  $this->dataMapCache = $this->cacheManager->getCache('extbase_datamapfactory_datamap');
58  }
59 
68  public function buildDataMap($className) {
69  $dataMap = $this->dataMapCache->get(str_replace('\\', '%', $className));
70  if ($dataMap === FALSE) {
71  $dataMap = $this->buildDataMapInternal($className);
72  $this->dataMapCache->set(str_replace('\\', '%', $className), $dataMap);
73  }
74  return $dataMap;
75  }
76 
86  protected function buildDataMapInternal($className) {
87  if (!class_exists($className)) {
88  throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\InvalidClassException('Could not find class definition for name "' . $className . '". This could be caused by a mis-spelling of the class name in the class definition.');
89  }
90  $recordType = NULL;
91  $subclasses = array();
92  $tableName = $this->resolveTableName($className);
93  $columnMapping = array();
94  $frameworkConfiguration = $this->configurationManager->getConfiguration(\TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface::CONFIGURATION_TYPE_FRAMEWORK);
95  $classSettings = $frameworkConfiguration['persistence']['classes'][$className];
96  if ($classSettings !== NULL) {
97  if (isset($classSettings['subclasses']) && is_array($classSettings['subclasses'])) {
98  $subclasses = $this->resolveSubclassesRecursive($frameworkConfiguration['persistence']['classes'], $classSettings['subclasses']);
99  }
100  if (isset($classSettings['mapping']['recordType']) && strlen($classSettings['mapping']['recordType']) > 0) {
101  $recordType = $classSettings['mapping']['recordType'];
102  }
103  if (isset($classSettings['mapping']['tableName']) && strlen($classSettings['mapping']['tableName']) > 0) {
104  $tableName = $classSettings['mapping']['tableName'];
105  }
106  $classHierarchy = array_merge(array($className), class_parents($className));
107  foreach ($classHierarchy as $currentClassName) {
108  if (in_array($currentClassName, array('TYPO3\\CMS\\Extbase\\DomainObject\\AbstractEntity', 'TYPO3\\CMS\\Extbase\\DomainObject\\AbstractValueObject'))) {
109  break;
110  }
111  $currentClassSettings = $frameworkConfiguration['persistence']['classes'][$currentClassName];
112  if ($currentClassSettings !== NULL) {
113  if (isset($currentClassSettings['mapping']['columns']) && is_array($currentClassSettings['mapping']['columns'])) {
114  \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($columnMapping, $currentClassSettings['mapping']['columns'], TRUE, FALSE);
115  }
116  }
117  }
118  }
120  $dataMap = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Mapper\\DataMap', $className, $tableName, $recordType, $subclasses);
121  $dataMap = $this->addMetaDataColumnNames($dataMap, $tableName);
122  // $classPropertyNames = $this->reflectionService->getClassPropertyNames($className);
123  $tcaColumnsDefinition = $this->getColumnsDefinition($tableName);
124  \TYPO3\CMS\Core\Utility\ArrayUtility::mergeRecursiveWithOverrule($tcaColumnsDefinition, $columnMapping);
125  // TODO Is this is too powerful?
126 
127  foreach ($tcaColumnsDefinition as $columnName => $columnDefinition) {
128  if (isset($columnDefinition['mapOnProperty'])) {
129  $propertyName = $columnDefinition['mapOnProperty'];
130  } else {
132  }
133  // if (in_array($propertyName, $classPropertyNames)) { // TODO Enable check for property existance
134  $columnMap = $this->createColumnMap($columnName, $propertyName);
135  $propertyMetaData = $this->reflectionService->getClassSchema($className)->getProperty($propertyName);
136  $columnMap = $this->setType($columnMap, $columnDefinition['config']);
137  $columnMap = $this->setRelations($columnMap, $columnDefinition['config'], $propertyMetaData);
138  $columnMap = $this->setFieldEvaluations($columnMap, $columnDefinition['config']);
139  $dataMap->addColumnMap($columnMap);
140  }
141  return $dataMap;
142  }
143 
150  protected function resolveTableName($className) {
151  $className = ltrim($className, '\\');
152  if (strpos($className, '\\') !== FALSE) {
153  $classNameParts = explode('\\', $className);
154  // Skip vendor and product name for core classes
155  if (strpos($className, 'TYPO3\\CMS\\') === 0) {
156  $classPartsToSkip = 2;
157  } else {
158  $classPartsToSkip = 1;
159  }
160  $tableName = 'tx_' . strtolower(implode('_', array_slice($classNameParts, $classPartsToSkip)));
161  } else {
162  $tableName = strtolower($className);
163  }
164  return $tableName;
165  }
166 
175  protected function resolveSubclassesRecursive(array $classesConfiguration, array $subclasses) {
176  $allSubclasses = array();
177  foreach ($subclasses as $subclass) {
178  $allSubclasses[] = $subclass;
179  if (isset($classesConfiguration[$subclass]['subclasses']) && is_array($classesConfiguration[$subclass]['subclasses'])) {
180  $childSubclasses = $this->resolveSubclassesRecursive($classesConfiguration, $classesConfiguration[$subclass]['subclasses']);
181  $allSubclasses = array_merge($allSubclasses, $childSubclasses);
182  }
183  }
184  return $allSubclasses;
185  }
186 
193  protected function getControlSection($tableName) {
194  return is_array($GLOBALS['TCA'][$tableName]['ctrl']) ? $GLOBALS['TCA'][$tableName]['ctrl'] : NULL;
195  }
196 
203  protected function getColumnsDefinition($tableName) {
204  return is_array($GLOBALS['TCA'][$tableName]['columns']) ? $GLOBALS['TCA'][$tableName]['columns'] : array();
205  }
206 
212  protected function addMetaDataColumnNames(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap $dataMap, $tableName) {
213  $controlSection = $GLOBALS['TCA'][$tableName]['ctrl'];
214  $dataMap->setPageIdColumnName('pid');
215  if (isset($controlSection['tstamp'])) {
216  $dataMap->setModificationDateColumnName($controlSection['tstamp']);
217  }
218  if (isset($controlSection['crdate'])) {
219  $dataMap->setCreationDateColumnName($controlSection['crdate']);
220  }
221  if (isset($controlSection['cruser_id'])) {
222  $dataMap->setCreatorColumnName($controlSection['cruser_id']);
223  }
224  if (isset($controlSection['delete'])) {
225  $dataMap->setDeletedFlagColumnName($controlSection['delete']);
226  }
227  if (isset($controlSection['languageField'])) {
228  $dataMap->setLanguageIdColumnName($controlSection['languageField']);
229  }
230  if (isset($controlSection['transOrigPointerField'])) {
231  $dataMap->setTranslationOriginColumnName($controlSection['transOrigPointerField']);
232  }
233  if (isset($controlSection['type'])) {
234  $dataMap->setRecordTypeColumnName($controlSection['type']);
235  }
236  if (isset($controlSection['rootLevel'])) {
237  $dataMap->setRootLevel($controlSection['rootLevel']);
238  }
239  if (isset($controlSection['is_static'])) {
240  $dataMap->setIsStatic($controlSection['is_static']);
241  }
242  if (isset($controlSection['enablecolumns']['disabled'])) {
243  $dataMap->setDisabledFlagColumnName($controlSection['enablecolumns']['disabled']);
244  }
245  if (isset($controlSection['enablecolumns']['starttime'])) {
246  $dataMap->setStartTimeColumnName($controlSection['enablecolumns']['starttime']);
247  }
248  if (isset($controlSection['enablecolumns']['endtime'])) {
249  $dataMap->setEndTimeColumnName($controlSection['enablecolumns']['endtime']);
250  }
251  if (isset($controlSection['enablecolumns']['fe_group'])) {
252  $dataMap->setFrontEndUserGroupColumnName($controlSection['enablecolumns']['fe_group']);
253  }
254  return $dataMap;
255  }
256 
264  protected function setType(ColumnMap $columnMap, $columnConfiguration) {
265  $tableColumnType = (isset($columnConfiguration['type'])) ? $columnConfiguration['type'] : NULL;
266  $columnMap->setType(\TYPO3\CMS\Core\DataHandling\TableColumnType::cast($tableColumnType));
267  $tableColumnSubType = (isset($columnConfiguration['internal_type'])) ? $columnConfiguration['internal_type'] : NULL;
268  $columnMap->setInternalType(\TYPO3\CMS\Core\DataHandling\TableColumnSubType::cast($tableColumnSubType));
269 
270  return $columnMap;
271  }
272 
282  protected function setRelations(ColumnMap $columnMap, $columnConfiguration, $propertyMetaData) {
283  if (isset($columnConfiguration)) {
284  if (isset($columnConfiguration['MM'])) {
285  $columnMap = $this->setManyToManyRelation($columnMap, $columnConfiguration);
286  } elseif (isset($propertyMetaData['elementType'])) {
287  $columnMap = $this->setOneToManyRelation($columnMap, $columnConfiguration);
288  } elseif (isset($propertyMetaData['type']) && strpbrk($propertyMetaData['type'], '_\\') !== FALSE) {
289  $columnMap = $this->setOneToOneRelation($columnMap, $columnConfiguration);
290  } elseif (isset($columnConfiguration['type']) && $columnConfiguration['type'] === 'select' && isset($columnConfiguration['maxitems']) && $columnConfiguration['maxitems'] > 1) {
292  } else {
294  }
295 
296  } else {
298  }
299  return $columnMap;
300  }
301 
309  protected function setFieldEvaluations(ColumnMap $columnMap, array $columnConfiguration = NULL) {
310  if (!empty($columnConfiguration['eval'])) {
311  $fieldEvaluations = \TYPO3\CMS\Core\Utility\GeneralUtility::trimExplode(',', $columnConfiguration['eval'], TRUE);
312  $dateTimeEvaluations = array('date', 'datetime');
313 
314  if (count(array_intersect($dateTimeEvaluations, $fieldEvaluations)) > 0 && !empty($columnConfiguration['dbType'])) {
315  $columnMap->setDateTimeStorageFormat($columnConfiguration['dbType']);
316  }
317  }
318 
319  return $columnMap;
320  }
321 
330  protected function setOneToOneRelation(ColumnMap $columnMap, $columnConfiguration) {
332  $columnMap->setChildTableName($columnConfiguration['foreign_table']);
333  $columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
334  $columnMap->setChildSortByFieldName($columnConfiguration['foreign_sortby']);
335  $columnMap->setParentKeyFieldName($columnConfiguration['foreign_field']);
336  $columnMap->setParentTableFieldName($columnConfiguration['foreign_table_field']);
337  if (is_array($columnConfiguration['foreign_match_fields'])) {
338  $columnMap->setRelationTableMatchFields($columnConfiguration['foreign_match_fields']);
339  }
340  return $columnMap;
341  }
342 
351  protected function setOneToManyRelation(ColumnMap $columnMap, $columnConfiguration) {
353  $columnMap->setChildTableName($columnConfiguration['foreign_table']);
354  $columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
355  $columnMap->setChildSortByFieldName($columnConfiguration['foreign_sortby']);
356  $columnMap->setParentKeyFieldName($columnConfiguration['foreign_field']);
357  $columnMap->setParentTableFieldName($columnConfiguration['foreign_table_field']);
358  if (is_array($columnConfiguration['foreign_match_fields'])) {
359  $columnMap->setRelationTableMatchFields($columnConfiguration['foreign_match_fields']);
360  }
361  return $columnMap;
362  }
363 
373  protected function setManyToManyRelation(ColumnMap $columnMap, $columnConfiguration) {
374  if (isset($columnConfiguration['MM'])) {
376  $columnMap->setChildTableName($columnConfiguration['foreign_table']);
377  $columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
378  $columnMap->setRelationTableName($columnConfiguration['MM']);
379  if (is_array($columnConfiguration['MM_match_fields'])) {
380  $columnMap->setRelationTableMatchFields($columnConfiguration['MM_match_fields']);
381  }
382  if (is_array($columnConfiguration['MM_insert_fields'])) {
383  $columnMap->setRelationTableInsertFields($columnConfiguration['MM_insert_fields']);
384  }
385  $columnMap->setRelationTableWhereStatement($columnConfiguration['MM_table_where']);
386  if (!empty($columnConfiguration['MM_opposite_field'])) {
387  $columnMap->setParentKeyFieldName('uid_foreign');
388  $columnMap->setChildKeyFieldName('uid_local');
389  $columnMap->setChildSortByFieldName('sorting_foreign');
390  } else {
391  $columnMap->setParentKeyFieldName('uid_local');
392  $columnMap->setChildKeyFieldName('uid_foreign');
393  $columnMap->setChildSortByFieldName('sorting');
394  }
395  } else {
396  throw new \TYPO3\CMS\Extbase\Persistence\Generic\Exception\UnsupportedRelationException('The given information to build a many-to-many-relation was not sufficient. Check your TCA definitions. mm-relations with IRRE must have at least a defined "MM" or "foreign_selector".', 1268817963);
397  }
398  if ($this->getControlSection($columnMap->getRelationTableName()) !== NULL) {
399  $columnMap->setRelationTablePageIdColumnName('pid');
400  }
401  return $columnMap;
402  }
403 
412  protected function createColumnMap($columnName, $propertyName) {
413  return $this->objectManager->get('TYPO3\\CMS\\Extbase\\Persistence\\Generic\\Mapper\\ColumnMap', $columnName, $propertyName);
414  }
415 }
setRelationTablePageIdColumnName($relationTablePageIdColumnName)
Definition: ColumnMap.php:282
setManyToManyRelation(ColumnMap $columnMap, $columnConfiguration)
static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=TRUE, $includeEmptyValues=TRUE, $enableUnsetFeature=TRUE)
resolveSubclassesRecursive(array $classesConfiguration, array $subclasses)
setFieldEvaluations(ColumnMap $columnMap, array $columnConfiguration=NULL)
setRelationTableMatchFields(array $relationTableMatchFields)
Definition: ColumnMap.php:296
addMetaDataColumnNames(\TYPO3\CMS\Extbase\Persistence\Generic\Mapper\DataMap $dataMap, $tableName)
static trimExplode($delim, $string, $removeEmptyValues=FALSE, $limit=0)
setRelationTableWhereStatement($relationTableWhereStatement)
Definition: ColumnMap.php:324
setOneToOneRelation(ColumnMap $columnMap, $columnConfiguration)
setRelationTableInsertFields(array $relationTableInsertFields)
Definition: ColumnMap.php:310
setChildTableWhereStatement($childTableWhereStatement)
Definition: ColumnMap.php:240
if(!defined('TYPO3_MODE')) $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_userauth.php']['logoff_pre_processing'][]
setRelations(ColumnMap $columnMap, $columnConfiguration, $propertyMetaData)
setOneToManyRelation(ColumnMap $columnMap, $columnConfiguration)
setType(ColumnMap $columnMap, $columnConfiguration)