[+BUGFIX] Extbase (Persistence): Extbase respects the default value for maxitems...
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Classes / Persistence / Mapper / DataMapFactory.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009 Jochen Rau <jochen.rau@typoplanet.de>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 /**
26 * A factory for a data map to map a single table configured in $TCA on a domain object.
27 *
28 * @package Extbase
29 * @subpackage Persistence\Mapper
30 * @version $ID:$
31 */
32 class Tx_Extbase_Persistence_Mapper_DataMapFactory {
33
34 /**
35 * Builds a data map by adding column maps for all the configured columns in the $TCA.
36 * It also resolves the type of values the column is holding and the typo of relation the column
37 * represents.
38 *
39 * @return void
40 */
41 public function buildDataMap($className) {
42 $tableName = NULL;
43 $columnMapping = array();
44 $extbaseSettings = Tx_Extbase_Dispatcher::getExtbaseFrameworkConfiguration();
45 if (is_array($extbaseSettings['persistence']['classes'][$className])) {
46 $persistenceSettings = $extbaseSettings['persistence']['classes'][$className];
47 if (is_string($persistenceSettings['mapping']['tableName']) && strlen($persistenceSettings['mapping']['tableName']) > 0) {
48 $tableName = $persistenceSettings['mapping']['tableName'];
49 }
50 if (is_array($persistenceSettings['mapping']['columns'])) {
51 $columnMapping = $persistenceSettings['mapping']['columns'];
52 }
53 } elseif (class_exists($className)) {
54 foreach (class_parents($className) as $parentClassName) {
55 $persistenceSettings = $extbaseSettings['persistence']['classes'][$parentClassName];
56 if (is_array($persistenceSettings)) {
57 if (is_string($persistenceSettings['mapping']['tableName']) && strlen($persistenceSettings['mapping']['tableName']) > 0) {
58 $tableName = $persistenceSettings['mapping']['tableName'];
59 }
60 if (is_array($persistenceSettings['mapping']['columns'])) {
61 $columnMapping = $persistenceSettings['mapping']['columns'];
62 }
63 }
64 break;
65 }
66 }
67 if ($tableName === NULL) {
68 $tableName = strtolower($className);
69 }
70 $dataMap = t3lib_div::makeInstance('Tx_Extbase_Persistence_Mapper_DataMap', $className, $tableName);
71 $dataMap = $this->addMetaDataColumnNames($dataMap, $tableName);
72 $columnConfigurations = array();
73 foreach ($this->getColumnsDefinition($tableName) as $columnName => $columnDefinition) {
74 $columnConfigurations[$columnName] = $columnDefinition['config'];
75 $columnConfigurations[$columnName]['mapOnProperty'] = Tx_Extbase_Utility_Extension::convertUnderscoredToLowerCamelCase($columnName);
76 }
77 $columnConfigurations = t3lib_div::array_merge_recursive_overrule($columnConfigurations, $columnMapping);
78 foreach ($columnConfigurations as $columnName => $columnConfiguration) {
79 $columnMap = new Tx_Extbase_Persistence_Mapper_ColumnMap($columnName, $columnConfiguration['mapOnProperty']);
80 $columnMap = $this->setRelations($columnMap, $columnConfiguration);
81 $dataMap->addColumnMap($columnMap);
82 }
83 return $dataMap;
84 }
85
86 /**
87 * Returns the TCA columns array of the specified table
88 *
89 * @param string $tableName An optional table name to fetch the columns definition from
90 * @return array The TCA columns definition
91 */
92 protected function getColumnsDefinition($tableName) {
93 if (TYPO3_MODE === 'FE') {
94 $GLOBALS['TSFE']->includeTCA();
95 }
96 t3lib_div::loadTCA($tableName);
97 $columns = is_array($GLOBALS['TCA'][$tableName]['columns']) ? $GLOBALS['TCA'][$tableName]['columns'] : array();
98 return $columns;
99 }
100
101 protected function addMetaDataColumnNames(Tx_Extbase_Persistence_Mapper_DataMap $dataMap, $tableName) {
102 $controlSection = $GLOBALS['TCA'][$tableName]['ctrl'];
103 $dataMap->setPageIdColumnName('pid');
104 if (isset($controlSection['tstamp'])) $dataMap->setModificationDateColumnName($controlSection['tstamp']);
105 if (isset($controlSection['crdate'])) $dataMap->setCreationDateColumnName($controlSection['crdate']);
106 if (isset($controlSection['cruser_id'])) $dataMap->setCreatorColumnName($controlSection['cruser_id']);
107 if (isset($controlSection['delete'])) $dataMap->setDeletedFlagColumnName($controlSection['delete']);
108 if (isset($controlSection['enablecolumns']['disabled'])) $dataMap->setDisabledFlagColumnName($controlSection['enablecolumns']['disabled']);
109 if (isset($controlSection['enablecolumns']['starttime'])) $dataMap->setStartTimeColumnName($controlSection['enablecolumns']['starttime']);
110 if (isset($controlSection['enablecolumns']['endtime'])) $dataMap->setEndTimeColumnName($controlSection['enablecolumns']['endtime']);
111 if (isset($controlSection['enablecolumns']['fe_group'])) $dataMap->setFrontEndUserGroupColumnName($controlSection['enablecolumns']['fe_group']);
112 return $dataMap;
113 }
114
115 /**
116 * This method tries to determine the type of type of relation to other tables and sets it based on
117 * the $TCA column configuration
118 *
119 * @param Tx_Extbase_Persistence_Mapper_ColumnMap $columnMap The column map
120 * @param string $columnConfiguration The column configuration from $TCA
121 * @return void
122 */
123 protected function setRelations(Tx_Extbase_Persistence_Mapper_ColumnMap $columnMap, $columnConfiguration) {
124 if (isset($columnConfiguration) && $columnConfiguration['type'] !== 'passthrough') {
125 if (isset($columnConfiguration['foreign_table'])) {
126 if (isset($columnConfiguration['MM']) || isset($columnConfiguration['foreign_selector'])) {
127 $columnMap = $this->setManyToManyRelation($columnMap, $columnConfiguration);
128 } else {
129 if (!isset($columnConfiguration['maxitems']) || $columnConfiguration['maxitems'] == 1) {
130 $columnMap = $this->setOneToOneRelation($columnMap, $columnConfiguration);
131 } else {
132 $columnMap = $this->setOneToManyRelation($columnMap, $columnConfiguration);
133 }
134 }
135 } else {
136 $columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_NONE);
137 }
138 }
139 return $columnMap;
140 }
141
142 /**
143 * This method sets the configuration for a 1:1 relation based on
144 * the $TCA column configuration
145 *
146 * @param string $columnMap The column map
147 * @param string $columnConfiguration The column configuration from $TCA
148 * @return void
149 */
150 protected function setOneToOneRelation(Tx_Extbase_Persistence_Mapper_ColumnMap $columnMap, $columnConfiguration) {
151 $columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_ONE);
152 $columnMap->setChildTableName($columnConfiguration['foreign_table']);
153 $columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
154 $columnMap->setChildSortbyFieldName($columnConfiguration['foreign_sortby']);
155 $columnMap->setParentKeyFieldName($columnConfiguration['foreign_field']);
156 $columnMap->setParentTableFieldName($columnConfiguration['foreign_table_field']);
157 return $columnMap;
158 }
159
160 /**
161 * This method sets the configuration for a 1:n relation based on
162 * the $TCA column configuration
163 *
164 * @param string $columnMap The column map
165 * @param string $columnConfiguration The column configuration from $TCA
166 * @return void
167 */
168 protected function setOneToManyRelation(Tx_Extbase_Persistence_Mapper_ColumnMap $columnMap, $columnConfiguration) {
169 $columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_MANY);
170 $columnMap->setChildTableName($columnConfiguration['foreign_table']);
171 $columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
172 $columnMap->setChildSortbyFieldName($columnConfiguration['foreign_sortby']);
173 $columnMap->setParentKeyFieldName($columnConfiguration['foreign_field']);
174 $columnMap->setParentTableFieldName($columnConfiguration['foreign_table_field']);
175 return $columnMap;
176 }
177
178 /**
179 * This method sets the configuration for a m:n relation based on
180 * the $TCA column configuration
181 *
182 * @param string $columnMap The column map
183 * @param string $columnConfiguration The column configuration from $TCA
184 * @return void
185 */
186 protected function setManyToManyRelation(Tx_Extbase_Persistence_Mapper_ColumnMap $columnMap, $columnConfiguration) {
187 $columnMap->setTypeOfRelation(Tx_Extbase_Persistence_Mapper_ColumnMap::RELATION_HAS_AND_BELONGS_TO_MANY);
188 if (isset($columnConfiguration['MM'])) {
189 $columnMap->setChildTableName($columnConfiguration['foreign_table']);
190 $columnMap->setChildTableWhereStatement($columnConfiguration['foreign_table_where']);
191 $columnMap->setRelationTableName($columnConfiguration['MM']);
192 if (is_array($columnConfiguration['MM_match_fields'])) {
193 $columnMap->setRelationTableMatchFields($columnConfiguration['MM_match_fields']);
194 }
195 if (is_array($columnConfiguration['MM_insert_fields'])) {
196 $columnMap->setRelationTableInsertFields($columnConfiguration['MM_insert_fields']);
197 }
198 $columnMap->setRelationTableWhereStatement($columnConfiguration['MM_table_where']);
199 if (!empty($columnConfiguration['MM_opposite_field'])) {
200 $columnMap->setParentKeyFieldName('uid_foreign');
201 $columnMap->setChildKeyFieldName('uid_local');
202 $columnMap->setChildSortByFieldName('sorting_foreign');
203 } else {
204 $columnMap->setParentKeyFieldName('uid_local');
205 $columnMap->setChildKeyFieldName('uid_foreign');
206 $columnMap->setChildSortByFieldName('sorting');
207 }
208 } elseif (isset($columnConfiguration['foreign_selector'])) {
209 $columns = $this->getColumnsDefinition($columnConfiguration['foreign_table']);
210 $childKeyFieldName = $columnConfiguration['foreign_selector'];
211 $columnMap->setChildTableName($columns[$childKeyFieldName]['config']['foreign_table']);
212 $columnMap->setRelationTableName($columnConfiguration['foreign_table']);
213 $columnMap->setParentKeyFieldName($columnConfiguration['foreign_field']);
214 $columnMap->setChildKeyFieldName($childKeyFieldName);
215 $columnMap->setChildSortByFieldName($columnConfiguration['foreign_sortby']);
216 } else {
217 throw new Tx_Extbase_Persistence_Exception_UnsupportedRelation('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);
218 }
219 return $columnMap;
220 }
221
222 }