TYPO3 CMS  TYPO3_7-6
CategoryRegistry.php
Go to the documentation of this file.
1 <?php
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 
22 
27 {
31  protected $registry = [];
32 
36  protected $extensions = [];
37 
41  protected $addedCategoryTabs = [];
42 
46  protected $template = '';
47 
53  public static function getInstance()
54  {
55  return GeneralUtility::makeInstance(__CLASS__);
56  }
57 
61  public function __construct()
62  {
63  $this->template = str_repeat(PHP_EOL, 3) . 'CREATE TABLE %s (' . PHP_EOL
64  . ' %s int(11) DEFAULT \'0\' NOT NULL' . PHP_EOL . ');' . str_repeat(PHP_EOL, 3);
65  }
66 
85  public function add($extensionKey, $tableName, $fieldName = 'categories', array $options = [], $override = false)
86  {
87  $didRegister = false;
88  if (empty($tableName) || !is_string($tableName)) {
89  throw new \InvalidArgumentException('No or invalid table name "' . $tableName . '" given.', 1369122038);
90  }
91  if (empty($extensionKey) || !is_string($extensionKey)) {
92  throw new \InvalidArgumentException('No or invalid extension key "' . $extensionKey . '" given.', 1397836158);
93  }
94 
95  if ($override) {
96  $this->remove($tableName, $fieldName);
97  }
98 
99  if (!$this->isRegistered($tableName, $fieldName)) {
100  $this->registry[$tableName][$fieldName] = $options;
101  $this->extensions[$extensionKey][$tableName][$fieldName] = $fieldName;
102 
103  if (!isset($GLOBALS['TCA'][$tableName]['columns']) && isset($GLOBALS['TCA'][$tableName]['ctrl']['dynamicConfigFile'])) {
104  // Handle deprecated old style dynamic TCA column loading.
106  }
107 
108  if (isset($GLOBALS['TCA'][$tableName]['columns'])) {
109  $this->applyTcaForTableAndField($tableName, $fieldName);
110  $didRegister = true;
111  }
112  }
113 
114  return $didRegister;
115  }
116 
122  public function getExtensionKeys()
123  {
124  return array_keys($this->extensions);
125  }
126 
132  public function getCategorizedTables()
133  {
134  return array_keys($this->registry);
135  }
136 
145  public function getCategoryFieldsForTable(array &$configuration)
146  {
147  $table = '';
148  $menuType = isset($configuration['row']['menu_type'][0]) ? $configuration['row']['menu_type'][0] : '';
149  // Define the table being looked up from the type of menu
150  if ($menuType === 'categorized_pages') {
151  $table = 'pages';
152  } elseif ($menuType === 'categorized_content') {
153  $table = 'tt_content';
154  }
155  // Return early if no table is defined
156  if (empty($table)) {
157  throw new \UnexpectedValueException('The given menu_type is not supported.', 1381823570);
158  }
159  // Loop on all registries and find entries for the correct table
160  foreach ($this->registry as $tableName => $fields) {
161  if ($tableName === $table) {
162  foreach ($fields as $fieldName => $options) {
163  $fieldLabel = $this->getLanguageService()->sL($GLOBALS['TCA'][$tableName]['columns'][$fieldName]['label']);
164  $configuration['items'][] = [$fieldLabel, $fieldName];
165  }
166  }
167  }
168  }
169 
177  public function isRegistered($tableName, $fieldName = 'categories')
178  {
179  return isset($this->registry[$tableName][$fieldName]);
180  }
181 
187  public function getDatabaseTableDefinitions()
188  {
189  $sql = '';
190  foreach ($this->getExtensionKeys() as $extensionKey) {
191  $sql .= $this->getDatabaseTableDefinition($extensionKey);
192  }
193  return $sql;
194  }
195 
202  public function getDatabaseTableDefinition($extensionKey)
203  {
204  if (!isset($this->extensions[$extensionKey]) || !is_array($this->extensions[$extensionKey])) {
205  return '';
206  }
207  $sql = '';
208 
209  foreach ($this->extensions[$extensionKey] as $tableName => $fields) {
210  foreach ($fields as $fieldName) {
211  $sql .= sprintf($this->template, $tableName, $fieldName);
212  }
213  }
214  return $sql;
215  }
216 
224  {
226  foreach ($this->registry as $tableName => $fields) {
227  foreach ($fields as $fieldName => $_) {
228  $this->applyTcaForTableAndField($tableName, $fieldName);
229  }
230  }
231  }
232 
239  protected function applyTcaForTableAndField($tableName, $fieldName)
240  {
241  $this->addTcaColumn($tableName, $fieldName, $this->registry[$tableName][$fieldName]);
242  $this->addToAllTCAtypes($tableName, $fieldName, $this->registry[$tableName][$fieldName]);
243  }
244 
250  protected function registerDefaultCategorizedTables()
251  {
252  $defaultCategorizedTables = GeneralUtility::trimExplode(
253  ',',
254  $GLOBALS['TYPO3_CONF_VARS']['SYS']['defaultCategorizedTables'],
255  true
256  );
257  foreach ($defaultCategorizedTables as $defaultCategorizedTable) {
258  if (!$this->isRegistered($defaultCategorizedTable)) {
259  $this->add('core', $defaultCategorizedTable, 'categories');
260  }
261  }
262  }
263 
275  protected function addToAllTCAtypes($tableName, $fieldName, array $options)
276  {
277 
278  // Makes sure to add more TCA to an existing structure
279  if (isset($GLOBALS['TCA'][$tableName]['columns'])) {
280  if (empty($options['fieldList'])) {
281  $fieldList = $this->addCategoryTab($tableName, $fieldName);
282  } else {
283  $fieldList = $options['fieldList'];
284  }
285 
286  $typesList = '';
287  if (isset($options['typesList']) && $options['typesList'] !== '') {
288  $typesList = $options['typesList'];
289  }
290 
291  $position = '';
292  if (!empty($options['position'])) {
293  $position = $options['position'];
294  }
295 
296  // Makes the new "categories" field to be visible in TSFE.
297  ExtensionManagementUtility::addToAllTCAtypes($tableName, $fieldList, $typesList, $position);
298  }
299  }
300 
309  protected function addCategoryTab($tableName, $fieldName)
310  {
311  $fieldList = '';
312  if (!isset($this->addedCategoryTabs[$tableName])) {
313  $fieldList .= '--div--;LLL:EXT:lang/locallang_tca.xlf:sys_category.tabs.category, ';
314  $this->addedCategoryTabs[$tableName] = $tableName;
315  }
316  $fieldList .= $fieldName;
317  return $fieldList;
318  }
319 
333  protected function addTcaColumn($tableName, $fieldName, array $options)
334  {
335  // Makes sure to add more TCA to an existing structure
336  if (isset($GLOBALS['TCA'][$tableName]['columns'])) {
337  // Take specific label into account
338  $label = 'LLL:EXT:lang/locallang_tca.xlf:sys_category.categories';
339  if (!empty($options['label'])) {
340  $label = $options['label'];
341  }
342 
343  // Take specific value of exclude flag into account
344  $exclude = true;
345  if (isset($options['exclude'])) {
346  $exclude = (bool)$options['exclude'];
347  }
348 
349  $fieldConfiguration = empty($options['fieldConfiguration']) ? [] : $options['fieldConfiguration'];
350 
351  $columns = [
352  $fieldName => [
353  'exclude' => $exclude,
354  'label' => $label,
355  'config' => static::getTcaFieldConfiguration($tableName, $fieldName, $fieldConfiguration),
356  ],
357  ];
358 
359  if (isset($options['l10n_mode'])) {
360  $columns[$fieldName]['l10n_mode'] = $options['l10n_mode'];
361  }
362  if (isset($options['l10n_display'])) {
363  $columns[$fieldName]['l10n_display'] = $options['l10n_display'];
364  }
365  if (isset($options['displayCond'])) {
366  $columns[$fieldName]['displayCond'] = $options['displayCond'];
367  }
368 
369  // Register opposite references for the foreign side of a relation
370  if (empty($GLOBALS['TCA']['sys_category']['columns']['items']['config']['MM_oppositeUsage'][$tableName])) {
371  $GLOBALS['TCA']['sys_category']['columns']['items']['config']['MM_oppositeUsage'][$tableName] = [];
372  }
373  if (!in_array($fieldName, $GLOBALS['TCA']['sys_category']['columns']['items']['config']['MM_oppositeUsage'][$tableName])) {
374  $GLOBALS['TCA']['sys_category']['columns']['items']['config']['MM_oppositeUsage'][$tableName][] = $fieldName;
375  }
376 
377  // Add field to interface list per default (unless the 'interface' property is FALSE)
378  if (
379  (!isset($options['interface']) || $options['interface'])
380  && !empty($GLOBALS['TCA'][$tableName]['interface']['showRecordFieldList'])
381  && !GeneralUtility::inList($GLOBALS['TCA'][$tableName]['interface']['showRecordFieldList'], $fieldName)
382  ) {
383  $GLOBALS['TCA'][$tableName]['interface']['showRecordFieldList'] .= ',' . $fieldName;
384  }
385 
386  // Adding fields to an existing table definition
387  ExtensionManagementUtility::addTCAcolumns($tableName, $columns);
388  }
389  }
390 
402  public static function getTcaFieldConfiguration($tableName, $fieldName = 'categories', array $fieldConfigurationOverride = [])
403  {
404  // Forges a new field, default name is "categories"
405  $fieldConfiguration = [
406  'type' => 'select',
407  'renderType' => 'selectTree',
408  'foreign_table' => 'sys_category',
409  'foreign_table_where' => ' AND sys_category.sys_language_uid IN (-1, 0) ORDER BY sys_category.sorting ASC',
410  'MM' => 'sys_category_record_mm',
411  'MM_opposite_field' => 'items',
412  'MM_match_fields' => [
413  'tablenames' => $tableName,
414  'fieldname' => $fieldName,
415  ],
416  'size' => 10,
417  'autoSizeMax' => 50,
418  'maxitems' => 9999,
419  'treeConfig' => [
420  'parentField' => 'parent',
421  'appearance' => [
422  'expandAll' => true,
423  'showHeader' => true,
424  'maxLevels' => 99,
425  ],
426  ],
427  ];
428 
429  // Merge changes to TCA configuration
430  if (!empty($fieldConfigurationOverride)) {
432  $fieldConfiguration,
433  $fieldConfigurationOverride
434  );
435  }
436 
437  return $fieldConfiguration;
438  }
439 
447  public function addCategoryDatabaseSchemaToTablesDefinition(array $sqlString)
448  {
450  $sqlString[] = $this->getDatabaseTableDefinitions();
451  return ['sqlString' => $sqlString];
452  }
453 
462  public function addExtensionCategoryDatabaseSchemaToTablesDefinition(array $sqlString, $extensionKey)
463  {
464  $sqlString[] = $this->getDatabaseTableDefinition($extensionKey);
465  return ['sqlString' => $sqlString, 'extensionKey' => $extensionKey];
466  }
467 
471  protected function getLanguageService()
472  {
473  return $GLOBALS['LANG'];
474  }
475 
482  protected function remove($tableName, $fieldName)
483  {
484  if (!$this->isRegistered($tableName, $fieldName)) {
485  return;
486  }
487 
488  unset($this->registry[$tableName][$fieldName]);
489 
490  foreach ($this->extensions as $extensionKey => $tableFieldConfig) {
491  foreach ($tableFieldConfig as $extTableName => $fieldNameArray) {
492  if ($extTableName === $tableName && isset($fieldNameArray[$fieldName])) {
493  unset($this->extensions[$extensionKey][$tableName][$fieldName]);
494  break;
495  }
496  }
497  }
498 
499  // If no more fields are configured we unregister the categories tab.
500  if (empty($this->registry[$tableName]) && isset($this->addedCategoryTabs[$tableName])) {
501  unset($this->addedCategoryTabs[$tableName]);
502  }
503  }
504 }
addToAllTCAtypes($tableName, $fieldName, array $options)
isRegistered($tableName, $fieldName='categories')
static addTCAcolumns($table, $columnArray, $addTofeInterface=false)
static getTcaFieldConfiguration($tableName, $fieldName='categories', array $fieldConfigurationOverride=[])
addTcaColumn($tableName, $fieldName, array $options)
static trimExplode($delim, $string, $removeEmptyValues=false, $limit=0)
addExtensionCategoryDatabaseSchemaToTablesDefinition(array $sqlString, $extensionKey)
static addToAllTCAtypes($table, $newFieldsString, $typeList='', $position='')
applyTcaForTableAndField($tableName, $fieldName)
getCategoryFieldsForTable(array &$configuration)
static mergeRecursiveWithOverrule(array &$original, array $overrule, $addKeys=true, $includeEmptyValues=true, $enableUnsetFeature=true)
addCategoryDatabaseSchemaToTablesDefinition(array $sqlString)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
$sql
Definition: server.php:84
add($extensionKey, $tableName, $fieldName='categories', array $options=[], $override=false)