‪TYPO3CMS  ‪main
Generator.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
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 
19 
27 
34 {
43  protected ‪$tableHandler = [
44  TableHandler\StaticData::class,
45  TableHandler\InlineMn::class,
46  TableHandler\InlineMnGroup::class,
47  TableHandler\InlineMnSymmetric::class,
48  TableHandler\InlineMnSymmetricGroup::class,
49  TableHandler\General::class,
50  ];
51 
58  public function ‪create(): void
59  {
60  $recordFinder = GeneralUtility::makeInstance(RecordFinder::class);
61 
62  // Create should not be called if demo data exists already
63  if (count($recordFinder->findUidsOfStyleguideEntryPages())) {
64  throw new ‪Exception(
65  'Can not create a second styleguide demo record tree',
66  1597577827
67  );
68  }
69 
70  // Add entry page on top level
71  $newIdOfEntryPage = ‪StringUtility::getUniqueId('NEW');
72  $data = [
73  'pages' => [
74  $newIdOfEntryPage => [
75  'title' => 'styleguide TCA demo',
76  'pid' => 0 - $this->‪getUidOfLastTopLevelPage(),
77  // Mark this page as entry point
78  'tx_styleguide_containsdemo' => 'tx_styleguide',
79  // Have the "globus" icon for this page
80  'is_siteroot' => 1,
81  ],
82  ],
83  ];
84 
85  // Add rows of third party tables like be_users and fal
87 
88  $highestLanguageId = $recordFinder->findHighestLanguageId();
89  $styleguideDemoLanguageIds = range($highestLanguageId + 1, $highestLanguageId + 4);
90 
91  // Add a page for each main table below entry page
92  $mainTables = $this->‪getListOfStyleguideMainTables();
93  // Have the first main table inside entry page
94  $neighborPage = $newIdOfEntryPage;
95  foreach ($mainTables as $mainTable) {
96  // Add default language page
97  $newIdOfPage = ‪StringUtility::getUniqueId('NEW');
98  $data['pages'][$newIdOfPage] = [
99  'title' => str_replace('_', ' ', substr($mainTable, strlen('tx_styleguide_'))),
100  'tx_styleguide_containsdemo' => $mainTable,
101  'hidden' => 0,
102  'pid' => $neighborPage,
103  ];
104 
105  // Add page translations for all styleguide languages
106  if (!empty($styleguideDemoLanguageIds)) {
107  foreach ($styleguideDemoLanguageIds as $languageUid) {
108  $newIdOfLocalizedPage = ‪StringUtility::getUniqueId('NEW');
109  $data['pages'][$newIdOfLocalizedPage] = [
110  'title' => str_replace('_', ' ', substr($mainTable . ' - language ' . $languageUid, strlen('tx_styleguide_'))),
111  'tx_styleguide_containsdemo' => $mainTable,
112  'hidden' => 0,
113  'pid' => $neighborPage,
114  'sys_language_uid' => $languageUid,
115  'l10n_parent' => $newIdOfPage,
116  'l10n_source' => $newIdOfPage,
117  ];
118  }
119  }
120  // Have next page after this page
121  $neighborPage = '-' . $newIdOfPage;
122  }
123 
124  // Populate page tree via DataHandler
125  $this->‪executeDataHandler($data);
126 
127  // Create a site configuration on root page
129  $topPageUidList = $recordFinder->findUidsOfStyleguideEntryPages();
130  $topPageUid = $topPageUidList[0];
131 
132  $this->‪createSiteConfiguration($topPageUid);
133 
134  // Create data for each main table
135  foreach ($mainTables as $mainTable) {
136  $generator = null;
137  foreach ($this->tableHandler as $handlerName) {
138  $generator = GeneralUtility::makeInstance($handlerName);
139  if (!$generator instanceof ‪TableHandlerInterface) {
140  throw new ‪Exception(
141  'Table handler ' . $handlerName . ' must implement TableHandlerInterface',
142  1458302830
143  );
144  }
145  if ($generator->match($mainTable)) {
146  break;
147  }
148  $generator = null;
149  }
150  if (is_null($generator)) {
152  'No table handler found',
153  1458302901
154  );
155  }
156  $generator->handle($mainTable);
157  }
158  }
159 
164  public function delete(): void
165  {
166  $recordFinder = GeneralUtility::makeInstance(RecordFinder::class);
167 
168  $commands = [];
169 
170  // Delete page tree and all their records on this tree
171  $topUids = $recordFinder->findUidsOfStyleguideEntryPages();
172  if (!empty($topUids)) {
173  foreach ($topUids as $topUid) {
174  $commands['pages'][(int)$topUid]['delete'] = 1;
175  }
176  }
177 
178  // Delete demo users
179  $demoUserUids = $recordFinder->findUidsOfDemoBeUsers();
180  if (!empty($demoUserUids)) {
181  foreach ($demoUserUids as $demoUserUid) {
182  $commands['be_users'][(int)$demoUserUid]['delete'] = 1;
183  }
184  }
185 
186  // Delete demo groups
187  $demoGroupUids = $recordFinder->findUidsOfDemoBeGroups();
188  if (!empty($demoGroupUids)) {
189  foreach ($demoGroupUids as $demoUserGroup) {
190  $commands['be_groups'][(int)$demoUserGroup]['delete'] = 1;
191  }
192  }
193 
194  // Process commands to delete records
195  $this->‪executeDataHandler([], $commands);
196 
197  // Delete demo images in fileadmin again
198  $this->‪deleteFalFolder('styleguide');
199 
200  // Delete site configuration
201  if ($topUids[0] ?? false) {
202  $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByRootPageId($topUids[0]);
203  GeneralUtility::makeInstance(SiteWriter::class)->delete($site->getIdentifier());
204  }
205  }
206 
210  protected function ‪populateRowsOfThirdPartyTables(): void
211  {
212  $recordFinder = GeneralUtility::makeInstance(RecordFinder::class);
213 
214  $demoGroupUids = $recordFinder->findUidsOfDemoBeGroups();
215  if (empty($demoGroupUids)) {
216  // Add two be_groups and fetch their uids to assign the non-admin be_user to these groups
217  ‪$fields = [
218  'pid' => 0,
219  'hidden' => 1,
220  'tx_styleguide_isdemorecord' => 1,
221  'title' => 'styleguide demo group 1',
222  ];
223  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('be_groups');
224  $connection->insert('be_groups', ‪$fields);
225  ‪$fields['title'] = 'styleguide demo group 2';
226  $connection->insert('be_groups', ‪$fields);
227  $demoGroupUids = $recordFinder->findUidsOfDemoBeGroups();
228 
229  // If there were no groups, it is assumed (!) there are no users either. So they are just created.
230  // This may lead to duplicate demo users if a group was manually deleted, but the styleguide
231  // "delete" action would delete them all anyway and the next "create" action would create a new set.
232  // Also, it may lead to missing be_users if they were manually deleted, but be_groups not.
233  // These edge cases are ignored for now.
234 
235  // Add two be_users, one admin user, one non-admin user, both hidden and with a random password
236  $passwordHash = GeneralUtility::makeInstance(PasswordHashFactory::class)->getDefaultHashInstance('BE');
237  $random = GeneralUtility::makeInstance(Random::class);
238  ‪$fields = [
239  'pid' => 0,
240  'disable' => 1,
241  'admin' => 0,
242  'tx_styleguide_isdemorecord' => 1,
243  'username' => 'styleguide demo user 1',
244  'usergroup' => implode(',', $demoGroupUids),
245  'password' => $passwordHash->getHashedPassword($random->generateRandomBytes(10)),
246  ];
247  $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('be_users');
248  $connection->insert('be_users', ‪$fields);
249  ‪$fields['admin'] = 1;
250  ‪$fields['username'] = 'styleguide demo user 2';
251  ‪$fields['usergroup'] = '';
252  ‪$fields['password'] = $passwordHash->getHashedPassword($random->generateRandomBytes(10));
253  $connection->insert('be_users', ‪$fields);
254  }
255 
256  // Add 3 files from resources directory to default storage
257  $this->‪addToFal([
258  'bus_lane.jpg',
259  'telephone_box.jpg',
260  'underground.jpg',
261  ], 'EXT:styleguide/Resources/Public/Images/Pictures/', 'styleguide');
262  }
263 
286  protected function ‪getListOfStyleguideMainTables(): array
287  {
288  $prefixes = [
289  'tx_styleguide_',
290  'tx_styleguide_ctrl_',
291  'tx_styleguide_elements_',
292  'tx_styleguide_inline_',
293  ];
294  $result = [];
295  foreach (‪$GLOBALS['TCA'] as $tablename => $_) {
296  if ($tablename === 'tx_styleguide_staticdata') {
297  continue;
298  }
299  foreach ($prefixes as $prefix) {
300  if (!str_starts_with($tablename, $prefix)) {
301  continue;
302  }
303 
304  // See if string after $prefix is only one _ separated segment
305  $suffix = substr($tablename, strlen($prefix));
306  $suffixArray = explode('_', $suffix);
307  if (count($suffixArray) !== 1) {
308  continue;
309  }
310 
311  // Found a main table
312  $result[] = $tablename;
313 
314  // No need to scan other prefixes
315  break;
316  }
317  }
318  // Manual resorting - the "staticdata" table is used by other tables later.
319  // We resort this on top so it is handled first and other tables can rely on
320  // created data already. This is a bit hacky but a quick workaround.
321  array_unshift($result, 'tx_styleguide_staticdata');
322  return $result;
323  }
324 }
‪TYPO3\CMS\Styleguide\TcaDataGenerator\AbstractGenerator
Definition: AbstractGenerator.php:40
‪TYPO3\CMS\Styleguide\TcaDataGenerator\Generator\getListOfStyleguideMainTables
‪array getListOfStyleguideMainTables()
Definition: Generator.php:285
‪TYPO3\CMS\Core\Crypto\PasswordHashing\PasswordHashFactory
Definition: PasswordHashFactory.php:27
‪TYPO3\CMS\Styleguide\TcaDataGenerator\TableHandlerInterface
Definition: TableHandlerInterface.php:26
‪TYPO3\CMS\Styleguide\TcaDataGenerator\AbstractGenerator\addToFal
‪addToFal(array $files, string $from, string $to)
Definition: AbstractGenerator.php:175
‪TYPO3\CMS\Core\Site\SiteFinder
Definition: SiteFinder.php:31
‪$fields
‪$fields
Definition: pages.php:5
‪TYPO3\CMS\Styleguide\TcaDataGenerator\AbstractGenerator\createSiteConfiguration
‪createSiteConfiguration(int $topPageUid, string $base='http://localhost/', string $title='styleguide demo')
Definition: AbstractGenerator.php:44
‪TYPO3\CMS\Styleguide\TcaDataGenerator\AbstractGenerator\getUidOfLastTopLevelPage
‪int getUidOfLastTopLevelPage()
Definition: AbstractGenerator.php:151
‪TYPO3\CMS\Styleguide\TcaDataGenerator\GeneratorNotFoundException
Definition: GeneratorNotFoundException.php:25
‪TYPO3\CMS\Core\Configuration\SiteWriter
Definition: SiteWriter.php:39
‪TYPO3\CMS\Styleguide\TcaDataGenerator\Generator\populateRowsOfThirdPartyTables
‪populateRowsOfThirdPartyTables()
Definition: Generator.php:209
‪TYPO3\CMS\Styleguide\TcaDataGenerator
Definition: AbstractGenerator.php:18
‪TYPO3\CMS\Styleguide\TcaDataGenerator\Generator
Definition: Generator.php:34
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Styleguide\TcaDataGenerator\Exception
Definition: Exception.php:25
‪TYPO3\CMS\Styleguide\TcaDataGenerator\Generator\create
‪create()
Definition: Generator.php:57
‪TYPO3\CMS\Core\Crypto\Random
Definition: Random.php:27
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:24
‪TYPO3\CMS\Styleguide\TcaDataGenerator\AbstractGenerator\executeDataHandler
‪executeDataHandler(array $data=[], array $commands=[])
Definition: AbstractGenerator.php:212
‪TYPO3\CMS\Styleguide\TcaDataGenerator\Generator\$tableHandler
‪array $tableHandler
Definition: Generator.php:42
‪TYPO3\CMS\Styleguide\TcaDataGenerator\AbstractGenerator\deleteFalFolder
‪deleteFalFolder(string $path)
Definition: AbstractGenerator.php:198
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static getUniqueId(string $prefix='')
Definition: StringUtility.php:57