[TASK] Doctrine: Migrate exec_INSERTquery
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Tests / Testbase.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests;
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
17 use TYPO3\CMS\Core\Core\Bootstrap;
18 use TYPO3\CMS\Core\Database\ConnectionPool;
19 use TYPO3\CMS\Core\Utility\ArrayUtility;
20 use TYPO3\CMS\Core\Utility\GeneralUtility;
21 use TYPO3\CMS\Extbase\Object\ObjectManager;
22 use TYPO3\CMS\Install\Service\SqlExpectedSchemaService;
23 use TYPO3\CMS\Install\Service\SqlSchemaMigrationService;
24
25 /**
26 * This is a helper class used by unit, functional and acceptance test
27 * environment builders.
28 * It contains methods to create test environments.
29 *
30 * This class is for internal use only and may change wihtout further notice.
31 *
32 * Use the classes "UnitTestCase", "FunctionalTestCase" or "AcceptanceCoreEnvironment"
33 * to indirectly benefit from this class in own extensions.
34 */
35 class Testbase
36 {
37 /**
38 * This class must be called in CLI environment as a security measure
39 * against path disclosures and other stuff. Check this within
40 * constructor to make sure this check can't be circumvented.
41 */
42 public function __construct()
43 {
44 // Ensure cli only as security measure
45 if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') {
46 die('This script supports command line usage only. Please check your command.');
47 }
48 }
49
50 /**
51 * Makes sure error messages during the tests get displayed no matter what is set in php.ini.
52 *
53 * @return void
54 */
55 public function enableDisplayErrors()
56 {
57 @ini_set('display_errors', 1);
58 }
59
60 /**
61 * Defines a list of basic constants that are used by GeneralUtility and other
62 * helpers during tests setup. Those are sanitized in SystemEnvironmentBuilder
63 * to be not defined again.
64 *
65 * @return void
66 * @see SystemEnvironmentBuilder::defineBaseConstants()
67 */
68 public function defineBaseConstants()
69 {
70 // A null, a tabulator, a linefeed, a carriage return, a substitution, a CR-LF combination
71 defined('NUL') ?: define('NUL', chr(0));
72 defined('TAB') ?: define('TAB', chr(9));
73 defined('LF') ?: define('LF', chr(10));
74 defined('CR') ?: define('CR', chr(13));
75 defined('SUB') ?: define('SUB', chr(26));
76 defined('CRLF') ?: define('CRLF', CR . LF);
77
78 if (!defined('TYPO3_OS')) {
79 // Operating system identifier
80 // Either "WIN" or empty string
81 $typoOs = '';
82 if (!stristr(PHP_OS, 'darwin') && !stristr(PHP_OS, 'cygwin') && stristr(PHP_OS, 'win')) {
83 $typoOs = 'WIN';
84 }
85 define('TYPO3_OS', $typoOs);
86 }
87 }
88
89 /**
90 * Defines the PATH_site and PATH_thisScript constant and sets $_SERVER['SCRIPT_NAME'].
91 * For unit tests only
92 *
93 * @return void
94 */
95 public function defineSitePath()
96 {
97 define('PATH_site', $this->getWebRoot());
98 define('PATH_thisScript', PATH_site . 'typo3/cli_dispatch.phpsh');
99 $_SERVER['SCRIPT_NAME'] = PATH_thisScript;
100
101 if (!file_exists(PATH_thisScript)) {
102 $this->exitWithMessage('Unable to determine path to entry script. Please check your path or set an environment variable \'TYPO3_PATH_WEB\' to your root path.');
103 }
104 }
105
106 /**
107 * Defines the constant ORIGINAL_ROOT for the path to the original TYPO3 document root.
108 * For functional / acceptance tests only
109 * If ORIGINAL_ROOT already is defined, this method is a no-op.
110 *
111 * @return void
112 */
113 public function defineOriginalRootPath()
114 {
115 if (!defined('ORIGINAL_ROOT')) {
116 define('ORIGINAL_ROOT', $this->getWebRoot());
117 }
118
119 if (!file_exists(ORIGINAL_ROOT . 'typo3/cli_dispatch.phpsh')) {
120 $this->exitWithMessage('Unable to determine path to entry script. Please check your path or set an environment variable \'TYPO3_PATH_WEB\' to your root path.');
121 }
122 }
123
124 /**
125 * Define TYPO3_MODE to BE
126 *
127 * @return void
128 */
129 public function defineTypo3ModeBe()
130 {
131 define('TYPO3_MODE', 'BE');
132 }
133
134 /**
135 * Sets the environment variable TYPO3_CONTEXT to testing.
136 *
137 * @return void
138 */
139 public function setTypo3TestingContext()
140 {
141 putenv('TYPO3_CONTEXT=Testing');
142 }
143
144 /**
145 * Creates directories, recursively if required.
146 *
147 * @param string $directory Absolute path to directories to create
148 * @return void
149 * @throws Exception
150 */
151 public function createDirectory($directory)
152 {
153 if (is_dir($directory)) {
154 return;
155 }
156 @mkdir($directory, 0777, true);
157 clearstatcache();
158 if (!is_dir($directory)) {
159 throw new Exception('Directory "' . $directory . '" could not be created', 1404038665);
160 }
161 }
162
163 /**
164 * Checks whether given test instance exists in path and is younger than some minutes.
165 * Used in functional tests
166 *
167 * @param string $instancePath Absolute path to test instance
168 * @return bool
169 */
170 public function recentTestInstanceExists($instancePath)
171 {
172 if (@file_get_contents($instancePath . '/last_run.txt') <= (time() - 300)) {
173 return false;
174 } else {
175 // Test instance exists and is pretty young -> re-use
176 return true;
177 }
178 }
179
180 /**
181 * Remove test instance folder structure if it exists.
182 * This may happen if a functional test before threw a fatal or is too old
183 *
184 * @param string $instancePath Absolute path to test instance
185 * @return void
186 * @throws Exception
187 */
188 public function removeOldInstanceIfExists($instancePath)
189 {
190 if (is_dir($instancePath)) {
191 $success = GeneralUtility::rmdir($instancePath, true);
192 if (!$success) {
193 throw new Exception(
194 'Can not remove folder: ' . $instancePath,
195 1376657210
196 );
197 }
198 }
199 }
200
201 /**
202 * Create last_run.txt file within instance path containing timestamp of "now".
203 * Used in functional tests to reuse an instance for multiple tests in one test case.
204 *
205 * @param string $instancePath Absolute path to test instance
206 * @return void
207 */
208 public function createLastRunTextfile($instancePath)
209 {
210 // Store the time instance was created
211 file_put_contents($instancePath . '/last_run.txt', time());
212 }
213
214 /**
215 * Link TYPO3 CMS core from "parent" instance.
216 * For functional and acceptance tests.
217 *
218 * @param string $instancePath Absolute path to test instance
219 * @throws Exception
220 * @return void
221 */
222 public function setUpInstanceCoreLinks($instancePath)
223 {
224 $linksToSet = array(
225 ORIGINAL_ROOT . 'typo3' => $instancePath . '/typo3',
226 ORIGINAL_ROOT . 'index.php' => $instancePath . '/index.php'
227 );
228 foreach ($linksToSet as $from => $to) {
229 $success = symlink($from, $to);
230 if (!$success) {
231 throw new Exception(
232 'Creating link failed: from ' . $from . ' to: ' . $to,
233 1376657199
234 );
235 }
236 }
237 }
238
239 /**
240 * Link test extensions to the typo3conf/ext folder of the instance.
241 * For functional and acceptance tests.
242 *
243 * @param string $instancePath Absolute path to test instance
244 * @param array $extensionPaths Contains paths to extensions relative to document root
245 * @throws Exception
246 * @return void
247 */
248 public function linkTestExtensionsToInstance($instancePath, array $extensionPaths)
249 {
250 foreach ($extensionPaths as $extensionPath) {
251 $absoluteExtensionPath = ORIGINAL_ROOT . $extensionPath;
252 if (!is_dir($absoluteExtensionPath)) {
253 throw new Exception(
254 'Test extension path ' . $absoluteExtensionPath . ' not found',
255 1376745645
256 );
257 }
258 $destinationPath = $instancePath . '/typo3conf/ext/' . basename($absoluteExtensionPath);
259 $success = symlink($absoluteExtensionPath, $destinationPath);
260 if (!$success) {
261 throw new Exception(
262 'Can not link extension folder: ' . $absoluteExtensionPath . ' to ' . $destinationPath,
263 1376657142
264 );
265 }
266 }
267 }
268
269 /**
270 * Link paths inside the test instance, e.g. from a fixture fileadmin subfolder to the
271 * test instance fileadmin folder.
272 * For functional and acceptance tests.
273 *
274 * @param string $instancePath Absolute path to test instance
275 * @param array $pathsToLinkInTestInstance Contains paths as array of source => destination in key => value pairs of folders relative to test instance root
276 * @throws Exception if a source path could not be found and on failing creating the symlink
277 * @return void
278 */
279 public function linkPathsInTestInstance($instancePath, array $pathsToLinkInTestInstance)
280 {
281 foreach ($pathsToLinkInTestInstance as $sourcePathToLinkInTestInstance => $destinationPathToLinkInTestInstance) {
282 $sourcePath = $instancePath . '/' . ltrim($sourcePathToLinkInTestInstance, '/');
283 if (!file_exists($sourcePath)) {
284 throw new Exception(
285 'Path ' . $sourcePath . ' not found',
286 1376745645
287 );
288 }
289 $destinationPath = $instancePath . '/' . ltrim($destinationPathToLinkInTestInstance, '/');
290 $success = symlink($sourcePath, $destinationPath);
291 if (!$success) {
292 throw new Exception(
293 'Can not link the path ' . $sourcePath . ' to ' . $destinationPath,
294 1389969623
295 );
296 }
297 }
298 }
299
300 /**
301 * Database settings for functional and acceptance tests can be either set by
302 * environment variables (recommended), or from an existing LocalConfiguration as fallback.
303 * The method fetches these.
304 *
305 * An unique name will be added to the database name later.
306 *
307 * @throws Exception
308 * @return array [DB][host], [DB][username], ...
309 */
310 public function getOriginalDatabaseSettingsFromEnvironmentOrLocalConfiguration()
311 {
312 $databaseName = trim(getenv('typo3DatabaseName'));
313 $databaseHost = trim(getenv('typo3DatabaseHost'));
314 $databaseUsername = trim(getenv('typo3DatabaseUsername'));
315 $databasePassword = trim(getenv('typo3DatabasePassword'));
316 $databasePort = trim(getenv('typo3DatabasePort'));
317 $databaseSocket = trim(getenv('typo3DatabaseSocket'));
318 if ($databaseName || $databaseHost || $databaseUsername || $databasePassword || $databasePort || $databaseSocket) {
319 // Try to get database credentials from environment variables first
320 $originalConfigurationArray = [
321 'DB' => [
322 'Connections' => [
323 'Default' => [
324 'driver' => 'mysqli'
325 ],
326 ],
327 ],
328 ];
329 if ($databaseName) {
330 $originalConfigurationArray['DB']['Connections']['Default']['dbname'] = $databaseName;
331 }
332 if ($databaseHost) {
333 $originalConfigurationArray['DB']['Connections']['Default']['host'] = $databaseHost;
334 }
335 if ($databaseUsername) {
336 $originalConfigurationArray['DB']['Connections']['Default']['user'] = $databaseUsername;
337 }
338 if ($databasePassword) {
339 $originalConfigurationArray['DB']['Connections']['Default']['password'] = $databasePassword;
340 }
341 if ($databasePort) {
342 $originalConfigurationArray['DB']['Connections']['Default']['port'] = $databasePort;
343 }
344 if ($databaseSocket) {
345 $originalConfigurationArray['DB']['Connections']['Default']['unix_socket'] = $databaseSocket;
346 }
347 } elseif (file_exists(ORIGINAL_ROOT . 'typo3conf/LocalConfiguration.php')) {
348 // See if a LocalConfiguration file exists in "parent" instance to get db credentials from
349 $originalConfigurationArray = require ORIGINAL_ROOT . 'typo3conf/LocalConfiguration.php';
350 } else {
351 throw new Exception(
352 'Database credentials for tests are neither set through environment'
353 . ' variables, and can not be found in an existing LocalConfiguration file',
354 1397406356
355 );
356 }
357 return $originalConfigurationArray;
358 }
359
360 /**
361 * Maximum length of database names is 64 chars in mysql. Test this is not exceeded
362 * after a suffix has been added.
363 *
364 * @param string $originalDatabaseName Base name of the database
365 * @param array $configuration "LocalConfiguration" array with DB settings
366 * @throws Exception
367 */
368 public function testDatabaseNameIsNotTooLong($originalDatabaseName, array $configuration)
369 {
370 // Maximum database name length for mysql is 64 characters
371 if (strlen($configuration['DB']['Connections']['Default']['dbname']) > 64) {
372 $suffixLength = strlen($configuration['DB']['Connections']['Default']['dbname']) - strlen($originalDatabaseName);
373 $maximumOriginalDatabaseName = 64 - $suffixLength;
374 throw new Exception(
375 'The name of the database that is used for the functional test (' . $originalDatabaseName . ')' .
376 ' exceeds the maximum length of 64 character allowed by MySQL. You have to shorten your' .
377 ' original database name to ' . $maximumOriginalDatabaseName . ' characters',
378 1377600104
379 );
380 }
381 }
382
383 /**
384 * Create LocalConfiguration.php file of the test instance.
385 * For functional and acceptance tests.
386 *
387 * @param string $instancePath Absolute path to test instance
388 * @param array $configuration Base configuration array
389 * @param array $overruleConfiguration Overrule factory and base configuration
390 * @throws Exception
391 * @return void
392 */
393 public function setUpLocalConfiguration($instancePath, array $configuration, array $overruleConfiguration)
394 {
395 // Base of final LocalConfiguration is core factory configuration
396 $finalConfigurationArray = require ORIGINAL_ROOT . 'typo3/sysext/core/Configuration/FactoryConfiguration.php';
397 ArrayUtility::mergeRecursiveWithOverrule($finalConfigurationArray, $configuration);
398 ArrayUtility::mergeRecursiveWithOverrule($finalConfigurationArray, $overruleConfiguration);
399 $result = $this->writeFile(
400 $instancePath . '/typo3conf/LocalConfiguration.php',
401 '<?php' . chr(10) .
402 'return ' .
403 ArrayUtility::arrayExport(
404 $finalConfigurationArray
405 ) .
406 ';'
407 );
408 if (!$result) {
409 throw new Exception('Can not write local configuration', 1376657277);
410 }
411 }
412
413 /**
414 * Compile typo3conf/PackageStates.php containing default packages like core,
415 * a test specific list of additional core extensions, and a list of
416 * test extensions.
417 * For functional and acceptance tests.
418 *
419 * @param string $instancePath Absolute path to test instance
420 * @param array $defaultCoreExtensionsToLoad Default list of core extensions to load
421 * @param array $additionalCoreExtensionsToLoad Additional core extensions to load
422 * @param array $testExtensionPaths Paths to extensions relative to document root
423 * @throws Exception
424 */
425 public function setUpPackageStates(
426 $instancePath,
427 array $defaultCoreExtensionsToLoad,
428 array $additionalCoreExtensionsToLoad,
429 array $testExtensionPaths
430 ) {
431 $packageStates = array(
432 'packages' => array(),
433 'version' => 5,
434 );
435
436 // Register default list of extensions and set active
437 foreach ($defaultCoreExtensionsToLoad as $extensionName) {
438 $packageStates['packages'][$extensionName] = array(
439 'packagePath' => 'typo3/sysext/' . $extensionName . '/'
440 );
441 }
442
443 // Register additional core extensions and set active
444 foreach ($additionalCoreExtensionsToLoad as $extensionName) {
445 $packageStates['packages'][$extensionName] = array(
446 'packagePath' => 'typo3/sysext/' . $extensionName . '/'
447 );
448 }
449
450 // Activate test extensions that have been symlinked before
451 foreach ($testExtensionPaths as $extensionPath) {
452 $extensionName = basename($extensionPath);
453 $packageStates['packages'][$extensionName] = array(
454 'packagePath' => 'typo3conf/ext/' . $extensionName . '/'
455 );
456 }
457
458 $result = $this->writeFile(
459 $instancePath . '/typo3conf/PackageStates.php',
460 '<?php' . chr(10) .
461 'return ' .
462 ArrayUtility::arrayExport(
463 $packageStates
464 ) .
465 ';'
466 );
467
468 if (!$result) {
469 throw new Exception('Can not write PackageStates', 1381612729);
470 }
471 }
472
473 /**
474 * Populate $GLOBALS['TYPO3_DB'] and create test database
475 * For functional and acceptance tests
476 *
477 * @param string $databaseName Database name of this test instance
478 * @param string $originalDatabaseName Original database name before suffix was added
479 * @throws \TYPO3\CMS\Core\Tests\Exception
480 * @return void
481 */
482 public function setUpTestDatabase($databaseName, $originalDatabaseName)
483 {
484 Bootstrap::getInstance()->initializeTypo3DbGlobal();
485 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $database */
486 $database = $GLOBALS['TYPO3_DB'];
487 if (!$database->sql_pconnect()) {
488 throw new Exception(
489 'TYPO3 Fatal Error: The current username, password or host was not accepted when the'
490 . ' connection to the database was attempted to be established!',
491 1377620117
492 );
493 }
494
495 // Drop database if exists
496 $database->admin_query('DROP DATABASE IF EXISTS `' . $databaseName . '`');
497 $createDatabaseResult = $database->admin_query('CREATE DATABASE `' . $databaseName . '` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci');
498 if (!$createDatabaseResult) {
499 $user = $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['user'];
500 $host = $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['host'];
501 throw new Exception(
502 'Unable to create database with name ' . $databaseName . '. This is probably a permission problem.'
503 . ' For this instance this could be fixed executing:'
504 . ' GRANT ALL ON `' . $originalDatabaseName . '_%`.* TO `' . $user . '`@`' . $host . '`;',
505 1376579070
506 );
507 }
508 $database->setDatabaseName($databaseName);
509
510 // On windows, this still works, but throws a warning, which we need to discard.
511 @$database->sql_select_db();
512 }
513
514 /**
515 * Bootstrap basic TYPO3. This bootstraps TYPO3 far enough to initialize database afterwards.
516 * For functional and acceptance tests.
517 *
518 * @param string $instancePath Absolute path to test instance
519 * @return void
520 */
521 public function setUpBasicTypo3Bootstrap($instancePath)
522 {
523 $_SERVER['PWD'] = $instancePath;
524 $_SERVER['argv'][0] = 'index.php';
525
526 $classLoader = require rtrim(realpath($instancePath . '/typo3'), '\\/') . '/../vendor/autoload.php';
527 Bootstrap::getInstance()
528 ->initializeClassLoader($classLoader)
529 ->setRequestType(TYPO3_REQUESTTYPE_BE | TYPO3_REQUESTTYPE_CLI)
530 ->baseSetup()
531 ->loadConfigurationAndInitialize(true)
532 ->loadTypo3LoadedExtAndExtLocalconf(true)
533 ->setFinalCachingFrameworkCacheConfiguration()
534 ->defineLoggingAndExceptionConstants()
535 ->unsetReservedGlobalVariables();
536 }
537
538 /**
539 * Populate $GLOBALS['TYPO3_DB'] and truncate all tables.
540 * For functional and acceptance tests.
541 *
542 * @throws Exception
543 * @return void
544 */
545 public function initializeTestDatabaseAndTruncateTables()
546 {
547 Bootstrap::getInstance()->initializeTypo3DbGlobal();
548 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $database */
549 $database = $GLOBALS['TYPO3_DB'];
550 if (!$database->sql_pconnect()) {
551 throw new Exception(
552 'TYPO3 Fatal Error: The current username, password or host was not accepted when the'
553 . ' connection to the database was attempted to be established!',
554 1377620117
555 );
556 }
557 $database->setDatabaseName($GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['dbname']);
558 $database->sql_select_db();
559 foreach ($database->admin_get_tables() as $table) {
560 $database->admin_query('TRUNCATE ' . $table['Name'] . ';');
561 }
562 }
563
564 /**
565 * Load ext_tables.php files.
566 * For functional and acceptance tests.
567 *
568 * @return void
569 */
570 public function loadExtensionTables()
571 {
572 Bootstrap::getInstance()->loadExtensionTables();
573 }
574
575 /**
576 * Create tables and import static rows.
577 * For functional and acceptance tests.
578 *
579 * @return void
580 */
581 public function createDatabaseStructure()
582 {
583 /** @var SqlSchemaMigrationService $schemaMigrationService */
584 $schemaMigrationService = GeneralUtility::makeInstance(SqlSchemaMigrationService::class);
585 /** @var ObjectManager $objectManager */
586 $objectManager = GeneralUtility::makeInstance(ObjectManager::class);
587 /** @var SqlExpectedSchemaService $expectedSchemaService */
588 $expectedSchemaService = $objectManager->get(SqlExpectedSchemaService::class);
589
590 // Raw concatenated ext_tables.sql and friends string
591 $expectedSchemaString = $expectedSchemaService->getTablesDefinitionString(true);
592 $statements = $schemaMigrationService->getStatementArray($expectedSchemaString, true);
593 list($_, $insertCount) = $schemaMigrationService->getCreateTables($statements, true);
594
595 $fieldDefinitionsFile = $schemaMigrationService->getFieldDefinitions_fileContent($expectedSchemaString);
596 $fieldDefinitionsDatabase = $schemaMigrationService->getFieldDefinitions_database();
597 $difference = $schemaMigrationService->getDatabaseExtra($fieldDefinitionsFile, $fieldDefinitionsDatabase);
598 $updateStatements = $schemaMigrationService->getUpdateSuggestions($difference);
599
600 $schemaMigrationService->performUpdateQueries($updateStatements['add'], $updateStatements['add']);
601 $schemaMigrationService->performUpdateQueries($updateStatements['change'], $updateStatements['change']);
602 $schemaMigrationService->performUpdateQueries($updateStatements['create_table'], $updateStatements['create_table']);
603
604 foreach ($insertCount as $table => $count) {
605 $insertStatements = $schemaMigrationService->getTableInsertStatements($statements, $table);
606 foreach ($insertStatements as $insertQuery) {
607 $insertQuery = rtrim($insertQuery, ';');
608 /** @var \TYPO3\CMS\Core\Database\DatabaseConnection $database */
609 $database = $GLOBALS['TYPO3_DB'];
610 $database->admin_query($insertQuery);
611 }
612 }
613 }
614
615 /**
616 * Imports a data set represented as XML into the test database,
617 *
618 * @param string $path Absolute path to the XML file containing the data set to load
619 * @return void
620 * @throws Exception
621 */
622 public function importXmlDatabaseFixture($path)
623 {
624 if (!is_file($path)) {
625 throw new Exception(
626 'Fixture file ' . $path . ' not found',
627 1376746261
628 );
629 }
630
631 $fileContent = file_get_contents($path);
632 // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
633 $previousValueOfEntityLoader = libxml_disable_entity_loader(true);
634 $xml = simplexml_load_string($fileContent);
635 libxml_disable_entity_loader($previousValueOfEntityLoader);
636 $foreignKeys = array();
637
638 /** @var $table \SimpleXMLElement */
639 foreach ($xml->children() as $table) {
640 $insertArray = array();
641
642 /** @var $column \SimpleXMLElement */
643 foreach ($table->children() as $column) {
644 $columnName = $column->getName();
645 $columnValue = null;
646
647 if (isset($column['ref'])) {
648 list($tableName, $elementId) = explode('#', $column['ref']);
649 $columnValue = $foreignKeys[$tableName][$elementId];
650 } elseif (isset($column['is-NULL']) && ($column['is-NULL'] === 'yes')) {
651 $columnValue = null;
652 } else {
653 $columnValue = (string)$table->$columnName;
654 }
655
656 $insertArray[$columnName] = $columnValue;
657 }
658
659 $tableName = $table->getName();
660 $connection = (new ConnectionPool())->getConnectionForTable($tableName);
661 $connection->insert(
662 $tableName,
663 $insertArray
664 );
665 if (isset($table['id'])) {
666 $elementId = (string)$table['id'];
667 $foreignKeys[$tableName][$elementId] = $connection->lastInsertId();
668 }
669 }
670 }
671
672 /**
673 * Returns the absolute path the TYPO3 document root.
674 * This is the "original" document root, not the "instance" root for functional / acceptance tests.
675 *
676 * @return string the TYPO3 document root using Unix path separators
677 */
678 protected function getWebRoot()
679 {
680 if (getenv('TYPO3_PATH_WEB')) {
681 $webRoot = getenv('TYPO3_PATH_WEB');
682 } else {
683 $webRoot = getcwd();
684 }
685 return rtrim(strtr($webRoot, '\\', '/'), '/') . '/';
686 }
687
688 /**
689 * Send http headers, echo out a text message and exit with error code
690 *
691 * @param string $message
692 */
693 protected function exitWithMessage($message)
694 {
695 echo $message . LF;
696 exit(1);
697 }
698
699 /**
700 * Writes $content to the file $file. This is a simplified version
701 * of GeneralUtility::writeFile that does not fix permissions.
702 *
703 * @param string $file Filepath to write to
704 * @param string $content Content to write
705 * @return bool TRUE if the file was successfully opened and written to.
706 */
707 protected function writeFile($file, $content)
708 {
709 if ($fd = fopen($file, 'wb')) {
710 $res = fwrite($fd, $content);
711 fclose($fd);
712 if ($res === false) {
713 return false;
714 }
715 return true;
716 }
717 return false;
718 }
719 }