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