[TASK] Only show active packages in PackageStates.php
[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 * This class must be called in CLI environment as a security measure
38 * against path disclosures and other stuff. Check this within
39 * constructor to make sure this check can't be circumvented.
40 */
41 public function __construct()
42 {
43 // Ensure cli only as security measure
44 if (PHP_SAPI !== 'cli' && PHP_SAPI !== 'phpdbg') {
45 die('This script supports command line usage only. Please check your command.');
46 }
47 }
48
49 /**
50 * Makes sure error messages during the tests get displayed no matter what is set in php.ini.
51 *
52 * @return void
53 */
54 public function enableDisplayErrors()
55 {
56 @ini_set('display_errors', 1);
57 }
58
59 /**
60 * Defines a list of basic constants that are used by GeneralUtility and other
61 * helpers during tests setup. Those are sanitized in SystemEnvironmentBuilder
62 * to be not defined again.
63 *
64 * @return void
65 * @see SystemEnvironmentBuilder::defineBaseConstants()
66 */
67 public function defineBaseConstants()
68 {
69 // A null, a tabulator, a linefeed, a carriage return, a substitution, a CR-LF combination
70 defined('NUL') ?: define('NUL', chr(0));
71 defined('TAB') ?: define('TAB', chr(9));
72 defined('LF') ?: define('LF', chr(10));
73 defined('CR') ?: define('CR', chr(13));
74 defined('SUB') ?: define('SUB', chr(26));
75 defined('CRLF') ?: define('CRLF', CR . LF);
76
77 if (!defined('TYPO3_OS')) {
78 // Operating system identifier
79 // Either "WIN" or empty string
80 $typoOs = '';
81 if (!stristr(PHP_OS, 'darwin') && !stristr(PHP_OS, 'cygwin') && stristr(PHP_OS, 'win')) {
82 $typoOs = 'WIN';
83 }
84 define('TYPO3_OS', $typoOs);
85 }
86 }
87
88 /**
89 * Defines the PATH_site and PATH_thisScript constant and sets $_SERVER['SCRIPT_NAME'].
90 * For unit tests only
91 *
92 * @return void
93 */
94 public function defineSitePath()
95 {
96 define('PATH_site', $this->getWebRoot());
97 define('PATH_thisScript', PATH_site . 'typo3/cli_dispatch.phpsh');
98 $_SERVER['SCRIPT_NAME'] = PATH_thisScript;
99
100 if (!file_exists(PATH_thisScript)) {
101 $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.');
102 }
103 }
104
105 /**
106 * Defines the constant ORIGINAL_ROOT for the path to the original TYPO3 document root.
107 * For functional / acceptance tests only
108 * If ORIGINAL_ROOT already is defined, this method is a no-op.
109 *
110 * @return void
111 */
112 public function defineOriginalRootPath()
113 {
114 if (!defined('ORIGINAL_ROOT')) {
115 define('ORIGINAL_ROOT', $this->getWebRoot());
116 }
117
118 if (!file_exists(ORIGINAL_ROOT . 'typo3/cli_dispatch.phpsh')) {
119 $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.');
120 }
121 }
122
123 /**
124 * Define TYPO3_MODE to BE
125 *
126 * @return void
127 */
128 public function defineTypo3ModeBe()
129 {
130 define('TYPO3_MODE', 'BE');
131 }
132
133 /**
134 * Sets the environment variable TYPO3_CONTEXT to testing.
135 *
136 * @return void
137 */
138 public function setTypo3TestingContext()
139 {
140 putenv('TYPO3_CONTEXT=Testing');
141 }
142
143 /**
144 * Creates directories, recursively if required.
145 *
146 * @param string $directory Absolute path to directories to create
147 * @return void
148 * @throws Exception
149 */
150 public function createDirectory($directory)
151 {
152 if (is_dir($directory)) {
153 return;
154 }
155 @mkdir($directory, 0777, true);
156 clearstatcache();
157 if (!is_dir($directory)) {
158 throw new Exception('Directory "' . $directory . '" could not be created', 1404038665);
159 }
160 }
161
162 /**
163 * Checks whether given test instance exists in path and is younger than some minutes.
164 * Used in functional tests
165 *
166 * @param string $instancePath Absolute path to test instance
167 * @return bool
168 */
169 public function recentTestInstanceExists($instancePath)
170 {
171 if (@file_get_contents($instancePath . '/last_run.txt') <= (time() - 300)) {
172 return false;
173 } else {
174 // Test instance exists and is pretty young -> re-use
175 return true;
176 }
177 }
178
179 /**
180 * Remove test instance folder structure if it exists.
181 * This may happen if a functional test before threw a fatal or is too old
182 *
183 * @param string $instancePath Absolute path to test instance
184 * @return void
185 * @throws Exception
186 */
187 public function removeOldInstanceIfExists($instancePath)
188 {
189 if (is_dir($instancePath)) {
190 $success = GeneralUtility::rmdir($instancePath, true);
191 if (!$success) {
192 throw new Exception(
193 'Can not remove folder: ' . $instancePath,
194 1376657210
195 );
196 }
197 }
198 }
199
200 /**
201 * Create last_run.txt file within instance path containing timestamp of "now".
202 * Used in functional tests to reuse an instance for multiple tests in one test case.
203 *
204 * @param string $instancePath Absolute path to test instance
205 * @return void
206 */
207 public function createLastRunTextfile($instancePath)
208 {
209 // Store the time instance was created
210 file_put_contents($instancePath . '/last_run.txt', time());
211 }
212
213 /**
214 * Link TYPO3 CMS core from "parent" instance.
215 * For functional and acceptance tests.
216 *
217 * @param string $instancePath Absolute path to test instance
218 * @throws Exception
219 * @return void
220 */
221 public function setUpInstanceCoreLinks($instancePath)
222 {
223 $linksToSet = array(
224 ORIGINAL_ROOT . 'typo3' => $instancePath . '/typo3',
225 ORIGINAL_ROOT . 'index.php' => $instancePath . '/index.php'
226 );
227 foreach ($linksToSet as $from => $to) {
228 $success = symlink($from, $to);
229 if (!$success) {
230 throw new Exception(
231 'Creating link failed: from ' . $from . ' to: ' . $to,
232 1376657199
233 );
234 }
235 }
236 }
237
238 /**
239 * Link test extensions to the typo3conf/ext folder of the instance.
240 * For functional and acceptance tests.
241 *
242 * @param string $instancePath Absolute path to test instance
243 * @param array $extensionPaths Contains paths to extensions relative to document root
244 * @throws Exception
245 * @return void
246 */
247 public function linkTestExtensionsToInstance($instancePath, array $extensionPaths)
248 {
249 foreach ($extensionPaths as $extensionPath) {
250 $absoluteExtensionPath = ORIGINAL_ROOT . $extensionPath;
251 if (!is_dir($absoluteExtensionPath)) {
252 throw new Exception(
253 'Test extension path ' . $absoluteExtensionPath . ' not found',
254 1376745645
255 );
256 }
257 $destinationPath = $instancePath . '/typo3conf/ext/' . basename($absoluteExtensionPath);
258 $success = symlink($absoluteExtensionPath, $destinationPath);
259 if (!$success) {
260 throw new Exception(
261 'Can not link extension folder: ' . $absoluteExtensionPath . ' to ' . $destinationPath,
262 1376657142
263 );
264 }
265 }
266 }
267
268 /**
269 * Link paths inside the test instance, e.g. from a fixture fileadmin subfolder to the
270 * test instance fileadmin folder.
271 * For functional and acceptance tests.
272 *
273 * @param string $instancePath Absolute path to test instance
274 * @param array $pathsToLinkInTestInstance Contains paths as array of source => destination in key => value pairs of folders relative to test instance root
275 * @throws Exception if a source path could not be found and on failing creating the symlink
276 * @return void
277 */
278 public function linkPathsInTestInstance($instancePath, array $pathsToLinkInTestInstance)
279 {
280 foreach ($pathsToLinkInTestInstance as $sourcePathToLinkInTestInstance => $destinationPathToLinkInTestInstance) {
281 $sourcePath = $instancePath . '/' . ltrim($sourcePathToLinkInTestInstance, '/');
282 if (!file_exists($sourcePath)) {
283 throw new Exception(
284 'Path ' . $sourcePath . ' not found',
285 1376745645
286 );
287 }
288 $destinationPath = $instancePath . '/' . ltrim($destinationPathToLinkInTestInstance, '/');
289 $success = symlink($sourcePath, $destinationPath);
290 if (!$success) {
291 throw new Exception(
292 'Can not link the path ' . $sourcePath . ' to ' . $destinationPath,
293 1389969623
294 );
295 }
296 }
297 }
298
299 /**
300 * Database settings for functional and acceptance tests can be either set by
301 * environment variables (recommended), or from an existing LocalConfiguration as fallback.
302 * The method fetches these.
303 *
304 * An unique name will be added to the database name later.
305 *
306 * @throws Exception
307 * @return array [DB][host], [DB][username], ...
308 */
309 public function getOriginalDatabaseSettingsFromEnvironmentOrLocalConfiguration()
310 {
311 $databaseName = trim(getenv('typo3DatabaseName'));
312 $databaseHost = trim(getenv('typo3DatabaseHost'));
313 $databaseUsername = trim(getenv('typo3DatabaseUsername'));
314 $databasePassword = trim(getenv('typo3DatabasePassword'));
315 $databasePort = trim(getenv('typo3DatabasePort'));
316 $databaseSocket = trim(getenv('typo3DatabaseSocket'));
317 if ($databaseName || $databaseHost || $databaseUsername || $databasePassword || $databasePort || $databaseSocket) {
318 // Try to get database credentials from environment variables first
319 $originalConfigurationArray = [
320 'DB' => [
321 'Connections' => [
322 'Default' => [
323 'driver' => 'mysqli'
324 ],
325 ],
326 ],
327 ];
328 if ($databaseName) {
329 $originalConfigurationArray['DB']['Connections']['Default']['dbname'] = $databaseName;
330 }
331 if ($databaseHost) {
332 $originalConfigurationArray['DB']['Connections']['Default']['host'] = $databaseHost;
333 }
334 if ($databaseUsername) {
335 $originalConfigurationArray['DB']['Connections']['Default']['user'] = $databaseUsername;
336 }
337 if ($databasePassword) {
338 $originalConfigurationArray['DB']['Connections']['Default']['password'] = $databasePassword;
339 }
340 if ($databasePort) {
341 $originalConfigurationArray['DB']['Connections']['Default']['port'] = $databasePort;
342 }
343 if ($databaseSocket) {
344 $originalConfigurationArray['DB']['Connections']['Default']['unix_socket'] = $databaseSocket;
345 }
346 } elseif (file_exists(ORIGINAL_ROOT . 'typo3conf/LocalConfiguration.php')) {
347 // See if a LocalConfiguration file exists in "parent" instance to get db credentials from
348 $originalConfigurationArray = require ORIGINAL_ROOT . 'typo3conf/LocalConfiguration.php';
349 } else {
350 throw new Exception(
351 'Database credentials for tests are neither set through environment'
352 . ' variables, and can not be found in an existing LocalConfiguration file',
353 1397406356
354 );
355 }
356 return $originalConfigurationArray;
357 }
358
359 /**
360 * Maximum length of database names is 64 chars in mysql. Test this is not exceeded
361 * after a suffix has been added.
362 *
363 * @param string $originalDatabaseName Base name of the database
364 * @param array $configuration "LocalConfiguration" array with DB settings
365 * @throws Exception
366 */
367 public function testDatabaseNameIsNotTooLong($originalDatabaseName, array $configuration)
368 {
369 // Maximum database name length for mysql is 64 characters
370 if (strlen($configuration['DB']['Connections']['Default']['dbname']) > 64) {
371 $suffixLength = strlen($configuration['DB']['Connections']['Default']['dbname']) - strlen($originalDatabaseName);
372 $maximumOriginalDatabaseName = 64 - $suffixLength;
373 throw new Exception(
374 'The name of the database that is used for the functional test (' . $originalDatabaseName . ')' .
375 ' exceeds the maximum length of 64 character allowed by MySQL. You have to shorten your' .
376 ' original database name to ' . $maximumOriginalDatabaseName . ' characters',
377 1377600104
378 );
379 }
380 }
381
382 /**
383 * Create LocalConfiguration.php file of the test instance.
384 * For functional and acceptance tests.
385 *
386 * @param string $instancePath Absolute path to test instance
387 * @param array $configuration Base configuration array
388 * @param array $overruleConfiguration Overrule factory and base configuration
389 * @throws Exception
390 * @return void
391 */
392 public function setUpLocalConfiguration($instancePath, array $configuration, array $overruleConfiguration)
393 {
394 // Base of final LocalConfiguration is core factory configuration
395 $finalConfigurationArray = require ORIGINAL_ROOT . 'typo3/sysext/core/Configuration/FactoryConfiguration.php';
396 ArrayUtility::mergeRecursiveWithOverrule($finalConfigurationArray, $configuration);
397 ArrayUtility::mergeRecursiveWithOverrule($finalConfigurationArray, $overruleConfiguration);
398 $result = $this->writeFile(
399 $instancePath . '/typo3conf/LocalConfiguration.php',
400 '<?php' . chr(10) .
401 'return ' .
402 ArrayUtility::arrayExport(
403 $finalConfigurationArray
404 ) .
405 ';'
406 );
407 if (!$result) {
408 throw new Exception('Can not write local configuration', 1376657277);
409 }
410 }
411
412 /**
413 * Compile typo3conf/PackageStates.php containing default packages like core,
414 * a test specific list of additional core extensions, and a list of
415 * test extensions.
416 * For functional and acceptance tests.
417 *
418 * @param string $instancePath Absolute path to test instance
419 * @param array $defaultCoreExtensionsToLoad Default list of core extensions to load
420 * @param array $additionalCoreExtensionsToLoad Additional core extensions to load
421 * @param array $testExtensionPaths Paths to extensions relative to document root
422 * @throws Exception
423 */
424 public function setUpPackageStates(
425 $instancePath,
426 array $defaultCoreExtensionsToLoad,
427 array $additionalCoreExtensionsToLoad,
428 array $testExtensionPaths
429 ) {
430 $packageStates = array(
431 'packages' => array(),
432 'version' => 5,
433 );
434
435 // Register default list of extensions and set active
436 foreach ($defaultCoreExtensionsToLoad as $extensionName) {
437 $packageStates['packages'][$extensionName] = array(
438 'packagePath' => 'typo3/sysext/' . $extensionName . '/'
439 );
440 }
441
442 // Register additional core extensions and set active
443 foreach ($additionalCoreExtensionsToLoad as $extensionName) {
444 $packageStates['packages'][$extensionName] = array(
445 'packagePath' => 'typo3/sysext/' . $extensionName . '/'
446 );
447 }
448
449 // Activate test extensions that have been symlinked before
450 foreach ($testExtensionPaths as $extensionPath) {
451 $extensionName = basename($extensionPath);
452 $packageStates['packages'][$extensionName] = array(
453 'packagePath' => 'typo3conf/ext/' . $extensionName . '/'
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']['Connections']['Default']['user'];
499 $host = $GLOBALS['TYPO3_CONF_VARS']['DB']['Connections']['Default']['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']['Connections']['Default']['dbname']);
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 * Send http headers, echo out a text message and exit with error code
694 *
695 * @param string $message
696 */
697 protected function exitWithMessage($message)
698 {
699 echo $message . LF;
700 exit(1);
701 }
702
703 /**
704 * Writes $content to the file $file. This is a simplified version
705 * of GeneralUtility::writeFile that does not fix permissions.
706 *
707 * @param string $file Filepath to write to
708 * @param string $content Content to write
709 * @return bool TRUE if the file was successfully opened and written to.
710 */
711 protected function writeFile($file, $content)
712 {
713 if ($fd = fopen($file, 'wb')) {
714 $res = fwrite($fd, $content);
715 fclose($fd);
716 if ($res === false) {
717 return false;
718 }
719 return true;
720 }
721 return false;
722 }
723 }