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();
 }