TYPO3 CMS  TYPO3_8-7
FormFileExtensionUpdate.php
Go to the documentation of this file.
1 <?php
2 declare(strict_types = 1);
3 namespace TYPO3\CMS\Form\Hooks;
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
34 
39 {
40 
44  protected $title = 'Rename form definition file extension from .yaml to .form.yaml';
45 
50 
54  protected $resourceFactory;
55 
59  protected $referenceIndex;
60 
64  protected $flexFormTools;
65 
69  protected $connection;
70 
77  public function checkForUpdate(&$description)
78  {
79  $updateNeeded = false;
80  $information = [];
81 
82  $this->persistenceManager = $this->getObjectManager()->get(FormPersistenceManager::class);
83  $this->resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
84 
85  foreach ($this->getFormDefinitionsInformation() as $formDefinitionInformation) {
86  if (
87  (
88  $formDefinitionInformation['hasNewFileExtension'] === true
89  && $formDefinitionInformation['hasReferencesForOldFileExtension'] === false
90  && $formDefinitionInformation['hasReferencesForNewFileExtension'] === false
91  )
92  || (
93  $formDefinitionInformation['hasNewFileExtension'] === false
94  && $formDefinitionInformation['location'] === 'extension'
95  && $formDefinitionInformation['hasReferencesForOldFileExtension'] === false
96  && $formDefinitionInformation['hasReferencesForNewFileExtension'] === false
97  )
98  ) {
99  continue;
100  }
101 
102  if (
103  $formDefinitionInformation['hasNewFileExtension'] === false
104  && $formDefinitionInformation['location'] === 'storage'
105  ) {
106  $updateNeeded = true;
107  $information['rename'] = 'Form definition files were found that should be migrated to be named .form.yaml.';
108  }
109 
110  if (
111  $formDefinitionInformation['hasNewFileExtension']
112  && $formDefinitionInformation['hasReferencesForOldFileExtension']
113  ) {
114  $updateNeeded = true;
115  $information['updateReference'] = 'Referenced form definition files found that should be updated.';
116  }
117 
118  if (
119  $formDefinitionInformation['referencesForOldFileExtensionNeedsFlexformUpdates'] === true
120  || $formDefinitionInformation['referencesForNewFileExtensionNeedsFlexformUpdates'] === true
121  ) {
122  $updateNeeded = true;
123  if ($formDefinitionInformation['hasNewFileExtension'] === true) {
124  $information['updateReference'] = 'Referenced form definition files found that should be updated.';
125  } else {
126  if ($formDefinitionInformation['location'] === 'storage') {
127  $information['updateReference'] = 'Referenced form definition files found that should be updated.';
128  } else {
129  $information['manualStepsNeeded'] =
130  'There are references to form definitions which are located in extensions and thus cannot be renamed automatically by this wizard.'
131  . 'This form definitions from extensions that do not end with .form.yaml have to be renamed by hand!'
132  . 'After that you can run this wizard again to migrate the references.';
133  }
134  }
135  }
136  }
137 
138  $description = implode('<br>', $information);
139 
140  return $updateNeeded;
141  }
142 
150  public function performUpdate(array &$dbQueries, &$customMessage): bool
151  {
152  $messages = [];
153 
154  $GLOBALS['LANG'] = GeneralUtility::makeInstance(LanguageService::class);
155  $connectionPool = GeneralUtility::makeInstance(ConnectionPool::class);
156  $filePersistenceSlot = GeneralUtility::makeInstance(FilePersistenceSlot::class);
157 
158  $this->connection = $connectionPool->getConnectionForTable('tt_content');
159  $this->persistenceManager = $this->getObjectManager()->get(FormPersistenceManager::class);
160  $this->resourceFactory = GeneralUtility::makeInstance(ResourceFactory::class);
161  $this->referenceIndex = GeneralUtility::makeInstance(ReferenceIndex::class);
162  $this->flexFormTools = GeneralUtility::makeInstance(FlexFormTools::class);
163 
164  $filePersistenceSlot->defineInvocation(
166  true
167  );
168 
169  $formDefinitionsInformation = $this->getFormDefinitionsInformation();
170  foreach ($formDefinitionsInformation as $currentPersistenceIdentifier => $formDefinitionInformation) {
171  if (
172  (
173  $formDefinitionInformation['hasNewFileExtension'] === true
174  && $formDefinitionInformation['hasReferencesForOldFileExtension'] === false
175  && $formDefinitionInformation['hasReferencesForNewFileExtension'] === false
176  )
177  || (
178  $formDefinitionInformation['hasNewFileExtension'] === false
179  && $formDefinitionInformation['location'] === 'extension'
180  && $formDefinitionInformation['hasReferencesForOldFileExtension'] === false
181  && $formDefinitionInformation['hasReferencesForNewFileExtension'] === false
182  )
183  ) {
184  continue;
185  }
186 
187  if (
188  $formDefinitionInformation['hasNewFileExtension'] === true
189  && (
190  $formDefinitionInformation['hasReferencesForOldFileExtension'] === true
191  || $formDefinitionInformation['hasReferencesForNewFileExtension'] === true
192  )
193  ) {
194  foreach ($formDefinitionInformation['referencesForOldFileExtension'] as $referenceForOldFileExtension) {
195  $newFlexformXml = $this->generateNewFlexformForReference(
196  $referenceForOldFileExtension,
197  $referenceForOldFileExtension['sheetIdentifiersWhichNeedsUpdate'],
198  $formDefinitionInformation['persistenceIdentifier']
199  );
200  $this->updateContentReference(
201  $referenceForOldFileExtension['ttContentUid'],
202  $newFlexformXml,
203  true
204  );
205  }
206 
207  foreach ($formDefinitionInformation['referencesForNewFileExtension'] as $referenceForNewFileExtension) {
208  $newFlexformXml = $this->generateNewFlexformForReference(
209  $referenceForNewFileExtension,
210  $referenceForNewFileExtension['sheetIdentifiersWhichNeedsUpdate']
211  );
212  $this->updateContentReference(
213  $referenceForNewFileExtension['ttContentUid'],
214  $newFlexformXml
215  );
216  }
217 
218  continue;
219  }
220 
221  if ($formDefinitionInformation['location'] === 'storage') {
222  $file = $formDefinitionInformation['file'];
223 
224  $newPossiblePersistenceIdentifier = $this->persistenceManager->getUniquePersistenceIdentifier(
225  $file->getNameWithoutExtension(),
226  $file->getParentFolder()->getCombinedIdentifier()
227  );
228  $newFileName = PathUtility::pathinfo(
229  $newPossiblePersistenceIdentifier,
230  PATHINFO_BASENAME
231  );
232 
233  try {
234  $file->rename($newFileName, DuplicationBehavior::RENAME);
235  $newPersistenceIdentifier = $file->getCombinedIdentifier();
236  } catch (\Exception $e) {
237  $messages[] = sprintf(
238  'Failed to rename form definition "%s" to "%s".',
239  $formDefinitionInformation['persistenceIdentifier'],
240  $newFileName
241  );
242  continue;
243  }
244 
245  if (
246  $formDefinitionInformation['hasReferencesForOldFileExtension'] === true
247  || $formDefinitionInformation['hasReferencesForNewFileExtension'] === true
248  ) {
249  foreach ($formDefinitionInformation['referencesForOldFileExtension'] as $referenceForOldFileExtension) {
250  $sheetIdentifiersWhichNeedsUpdate = $this->getSheetIdentifiersWhichNeedsUpdate(
251  $referenceForOldFileExtension['flexform'],
252  $formDefinitionsInformation,
253  $currentPersistenceIdentifier,
254  $formDefinitionInformation['persistenceIdentifier'],
255  $newPersistenceIdentifier
256  );
257  $newFlexformXml = $this->generateNewFlexformForReference(
258  $referenceForOldFileExtension,
259  $sheetIdentifiersWhichNeedsUpdate,
260  $newPersistenceIdentifier
261  );
262  $this->updateContentReference(
263  $referenceForOldFileExtension['ttContentUid'],
264  $newFlexformXml
265  );
266  }
267 
268  foreach ($formDefinitionInformation['referencesForNewFileExtension'] as $referenceForNewFileExtension) {
269  $sheetIdentifiersWhichNeedsUpdate = $this->getSheetIdentifiersWhichNeedsUpdate(
270  $referenceForNewFileExtension['flexform'],
271  $formDefinitionsInformation,
272  $currentPersistenceIdentifier,
273  $formDefinitionInformation['persistenceIdentifier'],
274  $newPersistenceIdentifier
275  );
276  $newFlexformXml = $this->generateNewFlexformForReference(
277  $referenceForNewFileExtension,
278  $sheetIdentifiersWhichNeedsUpdate,
279  $newPersistenceIdentifier
280  );
281  $this->updateContentReference(
282  $referenceForNewFileExtension['ttContentUid'],
283  $newFlexformXml
284  );
285  }
286  }
287  } else {
288  $messages[] = sprintf(
289  'Failed to rename form definition "%s" to "%s". You have to be rename it by hand!. '
290  . 'After that you can run this wizard again to migrate the references.',
291  $formDefinitionInformation['persistenceIdentifier'],
292  $this->getNewPersistenceIdentifier($formDefinitionInformation['persistenceIdentifier'])
293  );
294  }
295  }
296 
297  $filePersistenceSlot->defineInvocation(
299  null
300  );
301 
302  if (count($messages) > 0) {
303  $customMessage = 'The following issues occurred during performing updates:'
304  . '<br><ul><li>' . implode('</li><li>', $messages) . '</li></ul>';
305  return false;
306  }
307 
308  return true;
309  }
310 
314  protected function getFormDefinitionsInformation(): array
315  {
316  $formDefinitionsInformation = array_merge(
319  );
320 
321  $formDefinitionsInformation = $this->enrichFormDefinitionsInformationWithDataFromReferences($formDefinitionsInformation);
322 
323  return $formDefinitionsInformation;
324  }
325 
329  protected function getFormDefinitionsInformationFromStorages(): array
330  {
331  $formDefinitionsInformation = [];
332 
333  foreach ($this->persistenceManager->retrieveYamlFilesFromStorageFolders() as $file) {
334  $persistenceIdentifier = $file->getCombinedIdentifier();
335 
336  $formDefinition = $this->getFormDefinition($file);
337  if (empty($formDefinition)) {
338  continue;
339  }
340 
341  $formDefinitionsInformation[$persistenceIdentifier] = $this->setFormDefinitionInformationData(
342  $persistenceIdentifier,
343  $formDefinition,
344  $file,
345  'storage'
346  );
347  }
348 
349  return $formDefinitionsInformation;
350  }
351 
356  {
357  $formDefinitionsInformation = [];
358 
359  foreach ($this->persistenceManager->retrieveYamlFilesFromExtensionFolders() as $persistenceIdentifier => $_) {
360  try {
361  $file = $this->resourceFactory->retrieveFileOrFolderObject($persistenceIdentifier);
362  } catch (\Exception $exception) {
363  continue;
364  }
365 
366  $formDefinition = $this->getFormDefinition($file);
367  if (empty($formDefinition)) {
368  continue;
369  }
370 
371  $formDefinitionsInformation[$persistenceIdentifier] = $this->setFormDefinitionInformationData(
372  $persistenceIdentifier,
373  $formDefinition,
374  $file,
375  'extension'
376  );
377  }
378 
379  return $formDefinitionsInformation;
380  }
381 
390  string $persistenceIdentifier,
391  array $formDefinition,
392  File $file,
393  string $localtion
394  ): array {
395  return [
396  'location' => $localtion,
397  'persistenceIdentifier' => $persistenceIdentifier,
398  'prototypeName' => $formDefinition['prototypeName'],
399  'formIdentifier' => $formDefinition['identifier'],
400  'file' => $file,
401  'referencesForOldFileExtension' => [],
402  'referencesForNewFileExtension' => [],
403  'hasNewFileExtension' => $this->hasNewFileExtension($persistenceIdentifier),
404  'hasReferencesForOldFileExtension' => false,
405  'hasReferencesForNewFileExtension' => false,
406  'referencesForOldFileExtensionNeedsFlexformUpdates' => false,
407  'referencesForNewFileExtensionNeedsFlexformUpdates' => false,
408  ];
409  }
410 
415  protected function enrichFormDefinitionsInformationWithDataFromReferences(array $formDefinitionsInformation): array
416  {
417  foreach ($this->getAllFlexformFieldsFromFormPlugins() as $pluginData) {
418  if (empty($pluginData['pi_flexform'])) {
419  continue;
420  }
421  $flexform = GeneralUtility::xml2array($pluginData['pi_flexform']);
422  $referencedPersistenceIdentifier = $this->getPersistenceIdentifierFromFlexform($flexform);
423  $referenceHasNewFileExtension = $this->hasNewFileExtension($referencedPersistenceIdentifier);
424  $possibleOldReferencedPersistenceIdentifier = $this->getOldPersistenceIdentifier($referencedPersistenceIdentifier);
425  $possibleNewReferencedPersistenceIdentifier = $this->getNewPersistenceIdentifier($referencedPersistenceIdentifier);
426 
427  $referenceData = [
428  'scope' => null,
429  'ttContentUid' => (int)$pluginData['uid'],
430  'flexform' => $flexform,
431  'sheetIdentifiersWhichNeedsUpdate' => [],
432  ];
433 
434  $targetPersistenceIdentifier = null;
435  if (array_key_exists($referencedPersistenceIdentifier, $formDefinitionsInformation)) {
436  $targetPersistenceIdentifier = $referencedPersistenceIdentifier;
437  if ($referenceHasNewFileExtension) {
438  $referenceData['scope'] = 'referencesForNewFileExtension';
439  } else {
440  $referenceData['scope'] = 'referencesForOldFileExtension';
441  }
442  } else {
443  if ($referenceHasNewFileExtension) {
444  if (array_key_exists($possibleOldReferencedPersistenceIdentifier, $formDefinitionsInformation)) {
445  $targetPersistenceIdentifier = $possibleOldReferencedPersistenceIdentifier;
446  $referenceData['scope'] = 'referencesForNewFileExtension';
447  } else {
448  // There is no existing file for this reference
449  continue;
450  }
451  } else {
452  if (array_key_exists($possibleNewReferencedPersistenceIdentifier, $formDefinitionsInformation)) {
453  $targetPersistenceIdentifier = $possibleNewReferencedPersistenceIdentifier;
454  $referenceData['scope'] = 'referencesForOldFileExtension';
455  } else {
456  // There is no existing file for this reference
457  continue;
458  }
459  }
460  }
461 
462  $referenceData['sheetIdentifiersWhichNeedsUpdate'] = $this->getSheetIdentifiersWhichNeedsUpdate(
463  $flexform,
464  $formDefinitionsInformation,
465  $targetPersistenceIdentifier,
466  $possibleOldReferencedPersistenceIdentifier,
467  $possibleNewReferencedPersistenceIdentifier
468  );
469 
470  $scope = $referenceData['scope'];
471 
472  $formDefinitionsInformation[$targetPersistenceIdentifier][$scope][] = $referenceData;
473  if ($scope === 'referencesForOldFileExtension') {
474  $formDefinitionsInformation[$targetPersistenceIdentifier]['hasReferencesForOldFileExtension'] = true;
475  $formDefinitionsInformation[$targetPersistenceIdentifier]['referencesForOldFileExtensionNeedsFlexformUpdates'] = !empty($referenceData['sheetIdentifiersWhichNeedsUpdate']);
476  } else {
477  $formDefinitionsInformation[$targetPersistenceIdentifier]['hasReferencesForNewFileExtension'] = true;
478  $formDefinitionsInformation[$targetPersistenceIdentifier]['referencesForNewFileExtensionNeedsFlexformUpdates'] = !empty($referenceData['sheetIdentifiersWhichNeedsUpdate']);
479  }
480  }
481 
482  return $formDefinitionsInformation;
483  }
484 
494  array $flexform,
495  array $formDefinitionsInformation,
496  string $targetPersistenceIdentifier,
497  string $possibleOldReferencedPersistenceIdentifier,
498  string $possibleNewReferencedPersistenceIdentifier
499  ): array {
500  $sheetIdentifiersWhichNeedsUpdate = [];
501 
502  $sheetIdentifiers = $this->getSheetIdentifiersForFinisherOverrides($flexform);
503  foreach ($sheetIdentifiers as $currentSheetIdentifier => $finisherIdentifier) {
504  $sheetIdentifierForOldPersistenceIdentifier = $this->buildExpectedSheetIdentifier(
505  $possibleOldReferencedPersistenceIdentifier,
506  $formDefinitionsInformation[$targetPersistenceIdentifier]['prototypeName'],
507  $formDefinitionsInformation[$targetPersistenceIdentifier]['formIdentifier'],
508  $finisherIdentifier
509  );
510 
511  $sheetIdentifierForNewPersistenceIdentifier = $this->buildExpectedSheetIdentifier(
512  $possibleNewReferencedPersistenceIdentifier,
513  $formDefinitionsInformation[$targetPersistenceIdentifier]['prototypeName'],
514  $formDefinitionsInformation[$targetPersistenceIdentifier]['formIdentifier'],
515  $finisherIdentifier
516  );
517 
518  if (
519  $currentSheetIdentifier === $sheetIdentifierForOldPersistenceIdentifier
520  && !array_key_exists($sheetIdentifierForNewPersistenceIdentifier, $sheetIdentifiers)
521  ) {
522  $sheetIdentifiersWhichNeedsUpdate[$currentSheetIdentifier] = $sheetIdentifierForNewPersistenceIdentifier;
523  }
524  }
525 
526  return $sheetIdentifiersWhichNeedsUpdate;
527  }
528 
533  protected function getSheetIdentifiersForFinisherOverrides(array $flexform): array
534  {
535  $sheetIdentifiers = [];
536  foreach ($this->getFinisherSheetsFromFlexform($flexform) as $sheetIdentifier => $sheetData) {
537  $firstSheetItemOptionPath = array_shift(array_keys($sheetData['lDEF']));
538  preg_match('#^settings\.finishers\.(.*)\..+$#', $firstSheetItemOptionPath, $matches);
539  if (!isset($matches[1])) {
540  continue;
541  }
542  $finisherIdentifier = $matches[1];
543  $sheetIdentifiers[$sheetIdentifier] = $finisherIdentifier;
544  }
545 
546  return $sheetIdentifiers;
547  }
548 
553  protected function getFinisherSheetsFromFlexform(array $flexform): array
554  {
555  if (!isset($flexform['data'])) {
556  return [];
557  }
558 
559  return array_filter(
560  $flexform['data'],
561  function ($key) {
562  return $key !== 'sDEF' && strlen($key) === 32;
563  },
564  ARRAY_FILTER_USE_KEY
565  );
566  }
567 
572  protected function getPersistenceIdentifierFromFlexform(array $flexform): string
573  {
574  return $flexform['data']['sDEF']['lDEF']['settings.persistenceIdentifier']['vDEF'] ?? '';
575  }
576 
584  array $referenceData,
585  array $sheetIdentifiersWhichNeedsUpdate,
586  string $newPersistenceIdentifier = ''
587  ): string {
588  $flexform = $referenceData['flexform'];
589  if (!empty($newPersistenceIdentifier)) {
590  $flexform['data']['sDEF']['lDEF']['settings.persistenceIdentifier']['vDEF'] = $newPersistenceIdentifier;
591  }
592 
593  foreach ($sheetIdentifiersWhichNeedsUpdate as $oldSheetIdentifier => $newSheetIdentifier) {
594  $flexform['data'][$newSheetIdentifier] = $flexform['data'][$oldSheetIdentifier];
595  unset($flexform['data'][$oldSheetIdentifier]);
596  }
597 
598  return $this->flexFormTools->flexArray2Xml($flexform, true);
599  }
600 
605  protected function hasNewFileExtension(string $persistenceIdentifier): bool
606  {
608  $persistenceIdentifier,
610  );
611  }
612 
617  protected function looksLikeAFormDefinition(array $formDefinition): bool
618  {
619  return isset($formDefinition['identifier'], $formDefinition['type']) && $formDefinition['type'] === 'Form';
620  }
621 
626  protected function getOldPersistenceIdentifier(string $persistenceIdentifier): string
627  {
628  return preg_replace(
629  '
630  #^(.*)(\.form\.yaml)$#',
631  '${1}.yaml',
632  $persistenceIdentifier
633  );
634  }
635 
640  protected function getNewPersistenceIdentifier(string $persistenceIdentifier): string
641  {
642  return preg_replace(
643  '#(?<!\.form).yaml$#',
644  '.form.yaml',
645  $persistenceIdentifier
646  );
647  }
648 
656  protected function buildExpectedSheetIdentifier(
657  string $persistenceIdentifier,
658  string $prototypeName,
659  string $formIdentifier,
660  string $finisherIdentifier
661  ): string {
662  return md5(
663  implode('', [
664  $persistenceIdentifier,
665  $prototypeName,
666  $formIdentifier,
667  $finisherIdentifier
668  ])
669  );
670  }
671 
676  protected function getFormDefinition(File $file): array
677  {
678  try {
679  $rawYamlContent = $file->getContents();
680  $formDefinition = $this->extractMetaDataFromCouldBeFormDefinition($rawYamlContent);
681 
682  if (!$this->looksLikeAFormDefinition($formDefinition)) {
683  $formDefinition = [];
684  }
685  } catch (\Exception $exception) {
686  $formDefinition = [];
687  }
688 
689  return $formDefinition;
690  }
691 
696  protected function extractMetaDataFromCouldBeFormDefinition(string $maybeRawFormDefinition): array
697  {
698  $metaDataProperties = ['identifier', 'type', 'label', 'prototypeName'];
699  $metaData = [];
700  foreach (explode("\n", $maybeRawFormDefinition) as $line) {
701  if (empty($line) || $line[0] === ' ') {
702  continue;
703  }
704 
705  list($key, $value) = explode(':', $line);
706  if (
707  empty($key)
708  || empty($value)
709  || !in_array($key, $metaDataProperties)
710  ) {
711  continue;
712  }
713 
714  $value = trim($value, ' \'"');
715  $metaData[$key] = $value;
716  }
717 
718  return $metaData;
719  }
720 
724  protected function getAllFlexformFieldsFromFormPlugins(): array
725  {
726  $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
727  ->getQueryBuilderForTable('tt_content');
728  $queryBuilder->getRestrictions()
729  ->removeAll()
730  ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
731 
732  $records = $queryBuilder
733  ->select('uid', 'pi_flexform')
734  ->from('tt_content')
735  ->where(
736  $queryBuilder->expr()->eq(
737  'CType',
738  $queryBuilder->createNamedParameter('form_formframework', \PDO::PARAM_STR)
739  )
740  )
741  ->execute()
742  ->fetchAll();
743 
744  return $records;
745  }
746 
752  protected function updateContentReference(
753  int $uid,
754  string $flexform,
755  bool $updateRefindex = false
756  ) {
757  $this->connection->update(
758  'tt_content',
759  ['pi_flexform' => $flexform],
760  ['uid' => $uid]
761  );
762 
763  if (!$updateRefindex) {
764  return;
765  }
766 
767  $this->referenceIndex->updateRefIndexTable(
768  'tt_content',
769  $uid
770  );
771  }
772 
776  protected function getObjectManager(): ObjectManager
777  {
778  return GeneralUtility::makeInstance(ObjectManager::class);
779  }
780 }
extractMetaDataFromCouldBeFormDefinition(string $maybeRawFormDefinition)
generateNewFlexformForReference(array $referenceData, array $sheetIdentifiersWhichNeedsUpdate, string $newPersistenceIdentifier='')
buildExpectedSheetIdentifier(string $persistenceIdentifier, string $prototypeName, string $formIdentifier, string $finisherIdentifier)
updateContentReference(int $uid, string $flexform, bool $updateRefindex=false)
getSheetIdentifiersWhichNeedsUpdate(array $flexform, array $formDefinitionsInformation, string $targetPersistenceIdentifier, string $possibleOldReferencedPersistenceIdentifier, string $possibleNewReferencedPersistenceIdentifier)
static makeInstance($className,... $constructorArguments)
getOldPersistenceIdentifier(string $persistenceIdentifier)
setFormDefinitionInformationData(string $persistenceIdentifier, array $formDefinition, File $file, string $localtion)
static pathinfo($path, $options=null)
static xml2array($string, $NSprefix='', $reportDocTag=false)
enrichFormDefinitionsInformationWithDataFromReferences(array $formDefinitionsInformation)
if(TYPO3_MODE==='BE') $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_tsfebeuserauth.php']['frontendEditingController']['default']
performUpdate(array &$dbQueries, &$customMessage)
getNewPersistenceIdentifier(string $persistenceIdentifier)
static endsWith($haystack, $needle)