public function testRelativeFixturePath() { $relPath = ltrim(FRAMEWORK_DIR . '/tests/testing/YamlFixtureTest.yml', '/'); $obj = Injector::inst()->create('SilverStripe\\Dev\\YamlFixture', $relPath); $this->assertEquals(Director::baseFolder() . '/' . $relPath, $obj->getFixtureFile()); $this->assertNull($obj->getFixtureString()); }
/** * @param $locale */ public function __construct($locale = null) { $this->defaultLocale = $locale ? $locale : i18n::get_lang_from_locale(i18n::config()->get('default_locale')); $this->basePath = Director::baseFolder(); $this->baseSavePath = Director::baseFolder(); parent::__construct(); }
/** * Check if jQuery UI locale settings exists for the current locale * @return boolean */ function regionalSettingsExist() { $lang = $this->getLang(); $localeFile = THIRDPARTY_DIR . "/jquery-ui/datepicker/i18n/jquery.ui.datepicker-{$lang}.js"; if (file_exists(Director::baseFolder() . '/' . $localeFile)) { $this->jqueryLocaleFile = $localeFile; return true; } else { // file goes before internal en_US settings, // but both will validate return $lang == 'en'; } }
protected function init() { parent::init(); // Special case for dev/build: Defer permission checks to DatabaseAdmin->init() (see #4957) $requestedDevBuild = stripos($this->getRequest()->getURL(), 'dev/build') === 0 && stripos($this->getRequest()->getURL(), 'dev/build/defaults') === false; // We allow access to this controller regardless of live-status or ADMIN permission only // if on CLI. Access to this controller is always allowed in "dev-mode", or of the user is ADMIN. $canAccess = $requestedDevBuild || Director::isDev() || Director::is_cli() || Permission::check("ADMIN"); if (!$canAccess) { Security::permissionFailure($this); return; } // check for valid url mapping // lacking this information can cause really nasty bugs, // e.g. when running Director::test() from a FunctionalTest instance global $_FILE_TO_URL_MAPPING; if (Director::is_cli()) { if (isset($_FILE_TO_URL_MAPPING)) { $testPath = BASE_PATH; $matched = false; while ($testPath && $testPath != "/" && !preg_match('/^[A-Z]:\\\\$/', $testPath)) { if (isset($_FILE_TO_URL_MAPPING[$testPath])) { $matched = true; break; } $testPath = dirname($testPath); } if (!$matched) { echo 'Warning: You probably want to define ' . 'an entry in $_FILE_TO_URL_MAPPING that covers "' . Director::baseFolder() . '"' . "\n"; } } else { echo 'Warning: You probably want to define $_FILE_TO_URL_MAPPING in ' . 'your _ss_environment.php as instructed on the "sake" page of the doc.silverstripe.org wiki' . "\n"; } } // Backwards compat: Default to "draft" stage, which is important // for tasks like dev/build which call DataObject->requireDefaultRecords(), // but also for other administrative tasks which have assumptions about the default stage. Versioned::set_stage(Versioned::DRAFT); }
/** * Updates the database schema, creating tables & fields as necessary. * * @param boolean $quiet Don't show messages * @param boolean $populate Populate the database, as well as setting up its schema * @param bool $testMode */ public function doBuild($quiet = false, $populate = true, $testMode = false) { if ($quiet) { DB::quiet(); } else { $conn = DB::get_conn(); // Assumes database class is like "MySQLDatabase" or "MSSQLDatabase" (suffixed with "Database") $dbType = substr(get_class($conn), 0, -8); $dbVersion = $conn->getVersion(); $databaseName = method_exists($conn, 'currentDatabase') ? $conn->getSelectedDatabase() : ""; if (Director::is_cli()) { echo sprintf("\n\nBuilding database %s using %s %s\n\n", $databaseName, $dbType, $dbVersion); } else { echo sprintf("<h2>Building database %s using %s %s</h2>", $databaseName, $dbType, $dbVersion); } } // Set up the initial database if (!DB::is_active()) { if (!$quiet) { echo '<p><b>Creating database</b></p>'; } // Load parameters from existing configuration global $databaseConfig; if (empty($databaseConfig) && empty($_REQUEST['db'])) { user_error("No database configuration available", E_USER_ERROR); } $parameters = !empty($databaseConfig) ? $databaseConfig : $_REQUEST['db']; // Check database name is given if (empty($parameters['database'])) { user_error("No database name given; please give a value for \$databaseConfig['database']", E_USER_ERROR); } $database = $parameters['database']; // Establish connection and create database in two steps unset($parameters['database']); DB::connect($parameters); DB::create_database($database); } // Build the database. Most of the hard work is handled by DataObject $dataClasses = ClassInfo::subclassesFor('SilverStripe\\ORM\\DataObject'); array_shift($dataClasses); if (!$quiet) { if (Director::is_cli()) { echo "\nCREATING DATABASE TABLES\n\n"; } else { echo "\n<p><b>Creating database tables</b></p>\n\n"; } } // Initiate schema update $dbSchema = DB::get_schema(); $dbSchema->schemaUpdate(function () use($dataClasses, $testMode, $quiet) { foreach ($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness if (!class_exists($dataClass)) { continue; } // Check if this class should be excluded as per testing conventions $SNG = singleton($dataClass); if (!$testMode && $SNG instanceof TestOnly) { continue; } // Log data if (!$quiet) { if (Director::is_cli()) { echo " * {$dataClass}\n"; } else { echo "<li>{$dataClass}</li>\n"; } } // Instruct the class to apply its schema to the database $SNG->requireTable(); } }); ClassInfo::reset_db_cache(); if ($populate) { if (!$quiet) { if (Director::is_cli()) { echo "\nCREATING DATABASE RECORDS\n\n"; } else { echo "\n<p><b>Creating database records</b></p>\n\n"; } } foreach ($dataClasses as $dataClass) { // Check if class exists before trying to instantiate - this sidesteps any manifest weirdness // Test_ indicates that it's the data class is part of testing system if (strpos($dataClass, 'Test_') === false && class_exists($dataClass)) { if (!$quiet) { if (Director::is_cli()) { echo " * {$dataClass}\n"; } else { echo "<li>{$dataClass}</li>\n"; } } singleton($dataClass)->requireDefaultRecords(); } } // Remap obsolete class names $schema = DataObject::getSchema(); foreach ($this->config()->classname_value_remapping as $oldClassName => $newClassName) { $baseDataClass = $schema->baseDataClass($newClassName); $badRecordCount = DataObject::get($baseDataClass)->filter(["ClassName" => $oldClassName])->count(); if ($badRecordCount > 0) { if (Director::is_cli()) { echo " * Correcting {$badRecordCount} obsolete classname values for {$newClassName}\n"; } else { echo "<li>Correcting {$badRecordCount} obsolete classname values for {$newClassName}</li>\n"; } $table = $schema->baseDataTable($baseDataClass); DB::prepared_query("UPDATE \"{$table}\" SET \"ClassName\" = ? WHERE \"ClassName\" = ?", [$newClassName, $oldClassName]); } } } touch(TEMP_FOLDER . '/database-last-generated-' . str_replace(array('\\', '/', ':'), '.', Director::baseFolder())); if (isset($_REQUEST['from_installer'])) { echo "OK"; } if (!$quiet) { echo Director::is_cli() ? "\n Database build completed!\n\n" : "<p>Database build completed!</p>"; } ClassInfo::reset_db_cache(); }
/** * Map a fixture path to a physical file * * @param string $fixtureFilePath * @return string */ protected function resolveFixturePath($fixtureFilePath) { // Support fixture paths relative to the test class, rather than relative to webroot // String checking is faster than file_exists() calls. $isRelativeToFile = strpos('/', $fixtureFilePath) === false || preg_match('/^(\\.){1,2}/', $fixtureFilePath); if ($isRelativeToFile) { $resolvedPath = realpath($this->getCurrentAbsolutePath() . '/' . $fixtureFilePath); if ($resolvedPath) { return $resolvedPath; } } // Check if file exists relative to base dir $resolvedPath = realpath(Director::baseFolder() . '/' . $fixtureFilePath); if ($resolvedPath) { return $resolvedPath; } return $fixtureFilePath; }
public function setUp() { parent::setUp(); $this->tempPath = Director::baseFolder() . DIRECTORY_SEPARATOR . 'silverstripe-cache'; }
/** * Given a filesystem reference relative to the site root, return the full file-system path. * * @param string $file * * @return string */ public static function getAbsFile($file) { return self::is_absolute($file) ? $file : Director::baseFolder() . '/' . $file; }
/** * Return the most recent modification time of anything in the folder. * * @param string $folder The folder, relative to the site root * @param array $extensionList An option array of file extensions to limit the search to * @return string Same as filemtime() format. */ public static function folderModTime($folder, $extensionList = null) { $modTime = 0; if (!Filesystem::isAbsolute($folder)) { $folder = Director::baseFolder() . '/' . $folder; } $items = scandir($folder); foreach ($items as $item) { if ($item[0] != '.') { // Recurse into folders if (is_dir("{$folder}/{$item}")) { $modTime = max($modTime, self::folderModTime("{$folder}/{$item}", $extensionList)); // Check files } else { $extension = null; if ($extensionList) { $extension = strtolower(substr($item, strrpos($item, '.') + 1)); } if (!$extensionList || in_array($extension, $extensionList)) { $modTime = max($modTime, filemtime("{$folder}/{$item}")); } } } } //if(!$recursiveCall) self::$cache_folderModTime[$cacheID] = $modTime; return $modTime; }
/** * Includes all available language files for a certain defined locale. * * @param string $locale All resources from any module in locale $locale will be loaded * @param Boolean $clean Clean old caches? */ public static function include_by_locale($locale, $clean = false) { if ($clean) { self::flush(); } // Get list of module => path pairs, and then just the names $modules = ClassLoader::instance()->getManifest()->getModules(); $moduleNames = array_keys($modules); // Remove the "project" module from the list - we'll add it back specially later if needed global $project; if (($idx = array_search($project, $moduleNames)) !== false) { array_splice($moduleNames, $idx, 1); } // Get the order from the config syste, $order = i18n::config()->get('module_priority'); // Find all modules that don't have their order specified by the config system $unspecified = array_diff($moduleNames, $order); // If the placeholder "other_modules" exists in the order array, replace it by the unspecified modules if (($idx = array_search('other_modules', $order)) !== false) { array_splice($order, $idx, 1, $unspecified); } else { // Otherwise just jam them on the front array_splice($order, 0, 0, $unspecified); } // Put the project module back in at the begining if it wasn't specified by the config system if (!in_array($project, $order)) { array_unshift($order, $project); } $sortedModules = array(); foreach ($order as $module) { if (isset($modules[$module])) { $sortedModules[$module] = $modules[$module]; } } $sortedModules = array_reverse($sortedModules, true); // Loop in reverse order, meaning the translator with the highest priority goes first $translatorsByPrio = array_reverse(self::get_translators(), true); foreach ($translatorsByPrio as $priority => $translators) { /** @var Zend_Translate $translator */ foreach ($translators as $name => $translator) { /** @var i18nTranslateAdapterInterface|Zend_Translate_Adapter $adapter */ $adapter = $translator->getAdapter(); // Load translations from modules foreach ($sortedModules as $module) { $filename = $adapter->getFilenameForLocale($locale); $filepath = "{$module}/lang/" . $filename; if ($filename && !file_exists($filepath)) { continue; } $adapter->addTranslation(array('content' => $filepath, 'locale' => $locale)); } // Load translations from themes // TODO Replace with theme listing once implemented in TemplateManifest $themesBase = Director::baseFolder() . '/themes'; if (is_dir($themesBase)) { foreach (scandir($themesBase) as $theme) { if (strpos($theme, Config::inst()->get('SilverStripe\\View\\SSViewer', 'theme')) === 0 && file_exists("{$themesBase}/{$theme}/lang/")) { $filename = $adapter->getFilenameForLocale($locale); $filepath = "{$themesBase}/{$theme}/lang/" . $filename; if ($filename && !file_exists($filepath)) { continue; } $adapter->addTranslation(array('content' => $filepath, 'locale' => $locale)); } } } // Add empty translations to ensure the locales are "registered" with isAvailable(), // and the next invocation of include_by_locale() doesn't cause a new reparse. $adapter->addTranslation(array('content' => array($locale => $locale), 'locale' => $locale, 'usetranslateadapter' => true)); } } }
/** * @param string $fixture Absolute file path, or relative path to {@link Director::baseFolder()} */ public function __construct($fixture) { if (false !== strpos($fixture, "\n")) { $this->fixtureString = $fixture; } else { if (!Director::is_absolute($fixture)) { $fixture = Director::baseFolder() . '/' . $fixture; } if (!file_exists($fixture)) { throw new InvalidArgumentException('YamlFixture::__construct(): Fixture path "' . $fixture . '" not found'); } $this->fixtureFile = $fixture; } parent::__construct(); }