Example #1
0
	function testGetItemPath() {
		$ds = DIRECTORY_SEPARATOR;
		$loader = new SS_ClassLoader();
		
		$loader->pushManifest($this->testManifest1);
		$this->assertEquals(
			$this->baseManifest1 . $ds . 'module' . $ds . 'classes' . $ds . 'ClassA.php',
			$loader->getItemPath('ClassA')
		);
		$this->assertEquals(
			false,
			$loader->getItemPath('UnknownClass')
		);
		$this->assertEquals(
			false,
			$loader->getItemPath('OtherClassA')
		);
		
		$loader->pushManifest($this->testManifest2);
		$this->assertEquals(
			false,
			$loader->getItemPath('ClassA')
		);
		$this->assertEquals(
			false,
			$loader->getItemPath('UnknownClass')
		);
		$this->assertEquals(
			$this->baseManifest2 . $ds . 'module' . $ds . 'classes' . $ds . 'OtherClassA.php',
			$loader->getItemPath('OtherClassA')
		);
	}
Example #2
0
 public function testGetItemPath()
 {
     $loader = new SS_ClassLoader();
     $loader->pushManifest($this->testManifest1);
     $this->assertEquals(realpath($this->baseManifest1 . '/module/classes/ClassA.php'), realpath($loader->getItemPath('ClassA')));
     $this->assertEquals(false, $loader->getItemPath('UnknownClass'));
     $this->assertEquals(false, $loader->getItemPath('OtherClassA'));
     $loader->pushManifest($this->testManifest2);
     $this->assertEquals(false, $loader->getItemPath('ClassA'));
     $this->assertEquals(false, $loader->getItemPath('UnknownClass'));
     $this->assertEquals(realpath($this->baseManifest2 . '/module/classes/OtherClassA.php'), realpath($loader->getItemPath('OtherClassA')));
 }
 function executeInSubprocess($includeStderr = false)
 {
     // Get the path to the ErrorControlChain class
     $classpath = SS_ClassLoader::instance()->getItemPath('ErrorControlChain');
     $suppression = $this->suppression ? 'true' : 'false';
     // Start building a PHP file that will execute the chain
     $src = '<' . "?php\nrequire_once '{$classpath}';\n\n\$chain = new ErrorControlChain();\n\n\$chain->setSuppression({$suppression});\n\n\$chain\n";
     // For each step, use reflection to pull out the call, stick in the the PHP source we're building
     foreach ($this->steps as $step) {
         $func = new ReflectionFunction($step['callback']);
         $source = file($func->getFileName());
         $start_line = $func->getStartLine() - 1;
         $end_line = $func->getEndLine();
         $length = $end_line - $start_line;
         $src .= implode("", array_slice($source, $start_line, $length)) . "\n";
     }
     // Finally add a line to execute the chain
     $src .= "->execute();";
     // Now stick it in a temporary file & run it
     $codepath = TEMP_FOLDER . '/ErrorControlChainTest_' . sha1($src) . '.php';
     if ($includeStderr) {
         $null = '&1';
     } else {
         $null = is_writeable('/dev/null') ? '/dev/null' : 'NUL';
     }
     file_put_contents($codepath, $src);
     exec("php {$codepath} 2>{$null}", $stdout, $errcode);
     unlink($codepath);
     return array(implode("\n", $stdout), $errcode);
 }
Example #4
0
 /**
  * Pushes a class and template manifest instance that include tests onto the
  * top of the loader stacks.
  */
 public static function use_test_manifest()
 {
     $classManifest = new SS_ClassManifest(BASE_PATH, true, isset($_GET['flush']));
     SS_ClassLoader::instance()->pushManifest($classManifest);
     SapphireTest::set_test_class_manifest($classManifest);
     SS_TemplateLoader::instance()->pushManifest(new SS_TemplateManifest(BASE_PATH, true, isset($_GET['flush'])));
 }
 public function __construct($allowed_types = array())
 {
     $this->addComponent(new GridFieldAddNewMultiClass());
     $this->addComponent(new GridFieldToolbarHeader());
     $this->addComponent(new GridFieldTitleHeader());
     $this->addComponent(new GridFieldEditableColumns());
     $this->addComponent(new GridFieldEditButton());
     $this->addComponent(new GridFieldDeleteAction(false));
     $this->addComponent(new GridFieldDetailForm());
     // Multi-Class Add Button
     /////////////////////////
     $classes = array();
     if (empty($allowed_types)) {
         $allowed_types = SS_ClassLoader::instance()->getManifest()->getDescendantsOf('FlexiFormHandler');
     }
     foreach ($allowed_types as $className) {
         $class = singleton($className);
         $classes[$className] = "{$class->Label()}";
     }
     $component = $this->getComponentByType('GridFieldAddNewMultiClass');
     $component->setClasses($classes);
     // Inline Editing
     // ///////////////
     $component = $this->getComponentByType('GridFieldDataColumns');
     $component->setDisplayFields(array('Selected' => array('title' => 'Selected', 'callback' => function ($record, $column_name, $grid) {
         return new CheckboxField_Readonly($column_name);
     }), 'HandlerName' => array('title' => 'Name', 'field' => 'ReadonlyField'), 'Label' => array('title' => 'Type', 'field' => 'ReadonlyField'), 'DescriptionPreview' => array('title' => 'Description', 'field' => 'ReadonlyField'), 'FormCount' => array('title' => 'Form Count', 'field' => 'ReadonlyField')));
 }
 /**
  * Set up the simplest initial query
  */
 public function initialiseQuery()
 {
     //@todo could probably use ClassInfo::hasTable() instead here
     // Get the tables to join to.
     // Don't get any subclass tables - let lazy loading do that.
     $tableClasses = ClassInfo::ancestry($this->dataClass, true);
     // Error checking
     if (!$tableClasses) {
         if (!SS_ClassLoader::instance()->hasManifest()) {
             user_error("DataObjects have been requested before the manifest is loaded. Please ensure you are not" . " querying the database in _config.php.", E_USER_ERROR);
         } else {
             user_error("DataList::create Can't find data classes (classes linked to tables) for" . " {$this->dataClass}. Please ensure you run dev/build after creating a new DataObject.", E_USER_ERROR);
         }
     }
     //Base table is not an ancestor in OrientDB
     $baseClass = array_pop($tableClasses);
     // Build our intial query
     $this->query = new OrientSQLQuery(array());
     $this->query->setDistinct(false);
     if ($sort = singleton($this->dataClass)->stat('default_sort')) {
         $this->sort($sort);
     }
     //TODO: sometimes we want to set from to be the @RID
     $this->query->setFrom("{$baseClass}");
     $obj = Injector::inst()->get($baseClass);
     $obj->extend('augmentDataQueryCreation', $this->query, $this);
 }
 public function fire()
 {
     $this->info('Used cache location: ' . TEMP_FOLDER);
     SS_ClassLoader::instance()->getManifest()->regenerate();
     $this->info('regenerated manifest!');
     ClassInfo::reset_db_cache();
     $this->info('resetted db cache!');
 }
 /**
  * Get a list of all page types available in the CMS
  *
  * @return array
  */
 protected function getPageTypes()
 {
     $types = array();
     foreach (SS_ClassLoader::instance()->getManifest()->getDescendantsOf("SiteTree") as $class) {
         $types[$class] = $class;
     }
     return $types;
 }
 /**
  * The callback that Phockito will call every time there's a new double created
  *
  * @param string $double - The class name of the new double
  * @param string $of - The class new of the doubled class or interface
  * @param bool $isDoubleOfInterface - True if $of is an interface, False if it's a class
  */
 static function register_double($double, $of, $isDoubleOfInterface = false)
 {
     $manifest = SS_ClassLoader::instance()->getManifest();
     if (!$manifest instanceof PhockitoClassManifestUpdater) {
         $manifest = new PhockitoClassManifestUpdater($manifest);
         SS_ClassLoader::instance()->pushManifest($manifest, true);
     }
     $manifest->addDouble($double, $of, $isDoubleOfInterface);
 }
 public function tearDown()
 {
     SS_TemplateLoader::instance()->popManifest();
     SS_ClassLoader::instance()->popManifest();
     i18n::set_locale($this->originalLocale);
     Config::inst()->update('Director', 'alternate_base_folder', null);
     Config::inst()->update('SSViewer', 'theme', $this->_oldTheme);
     i18n::register_translator($this->origAdapter, 'core');
     parent::tearDown();
 }
 public function tearDown()
 {
     SS_TemplateLoader::instance()->popManifest();
     SS_ClassLoader::instance()->popManifest();
     i18n::set_locale($this->originalLocale);
     Director::setBaseFolder(null);
     SSViewer::set_theme($this->_oldTheme);
     i18n::register_translator($this->origAdapter, 'core');
     parent::tearDown();
 }
Example #12
0
 /**
  * Pushes a class and template manifest instance that include tests onto the
  * top of the loader stacks.
  */
 public static function use_test_manifest()
 {
     $classManifest = new SS_ClassManifest(BASE_PATH, true, isset($_GET['flush']));
     SS_ClassLoader::instance()->pushManifest($classManifest, false);
     SapphireTest::set_test_class_manifest($classManifest);
     SS_TemplateLoader::instance()->pushManifest(new SS_TemplateManifest(BASE_PATH, project(), true, isset($_GET['flush'])));
     Config::inst()->pushConfigStaticManifest(new SS_ConfigStaticManifest(BASE_PATH, true, isset($_GET['flush'])));
     // Invalidate classname spec since the test manifest will now pull out new subclasses for each internal class
     // (e.g. Member will now have various subclasses of DataObjects that implement TestOnly)
     DataObject::clear_classname_spec_cache();
 }
 /**
  * @param $controller
  *
  * @return bool|string
  */
 protected function findControllerFilePath($controller)
 {
     $controller = strtolower($controller);
     $classes = SS_ClassLoader::instance()->getManifest()->getClasses();
     $filePath = isset($classes[$controller]) ? $classes[$controller] : '';
     if (!is_file($filePath)) {
         $this->error("{$filePath} does not exist");
         return false;
     }
     return $filePath;
 }
 /**
  * Inits bundle directory structure
  *
  * @param InputInterface  $input
  * @param OutputInterface $output
  */
 protected function initBundleDirectoryStructure(InputInterface $input, OutputInterface $output)
 {
     // Bootstrap SS so we can use module listing
     $frameworkPath = $this->container->getParameter('behat.silverstripe_extension.framework_path');
     $_GET['flush'] = 1;
     require_once $frameworkPath . '/core/Core.php';
     unset($_GET['flush']);
     $featuresPath = $input->getArgument('features');
     if (!$featuresPath) {
         throw new \InvalidArgumentException('Please specify a module name (e.g. "@mymodule")');
     }
     // Can't use 'behat.paths.base' since that's locked at this point to base folder (not module)
     $pathSuffix = $this->container->getParameter('behat.silverstripe_extension.context.path_suffix');
     $currentModuleName = null;
     $modules = \SS_ClassLoader::instance()->getManifest()->getModules();
     $currentModuleName = $this->container->getParameter('behat.silverstripe_extension.module');
     // get module from short notation if path starts from @
     if (preg_match('/^\\@([^\\/\\\\]+)(.*)$/', $featuresPath, $matches)) {
         $currentModuleName = $matches[1];
         // TODO Replace with proper module loader once AJShort's changes are merged into core
         if (!array_key_exists($currentModuleName, $modules)) {
             throw new \InvalidArgumentException(sprintf('Module "%s" not found', $currentModuleName));
         }
         $currentModulePath = $modules[$currentModuleName];
     }
     if (!$currentModuleName) {
         throw new \InvalidArgumentException('Can not find module to initialize suite.');
     }
     // TODO Retrieve from module definition once that's implemented
     if ($input->getOption('namespace')) {
         $namespace = $input->getOption('namespace');
     } else {
         $namespace = ucfirst($currentModuleName);
     }
     $namespace .= '\\' . $this->container->getParameter('behat.silverstripe_extension.context.namespace_suffix');
     $featuresPath = rtrim($currentModulePath . DIRECTORY_SEPARATOR . $pathSuffix, DIRECTORY_SEPARATOR);
     $basePath = $this->container->getParameter('behat.paths.base') . DIRECTORY_SEPARATOR;
     $bootstrapPath = $featuresPath . DIRECTORY_SEPARATOR . 'bootstrap';
     $contextPath = $bootstrapPath . DIRECTORY_SEPARATOR . 'Context';
     if (!is_dir($featuresPath)) {
         mkdir($featuresPath, 0777, true);
         mkdir($bootstrapPath, 0777, true);
         // touch($bootstrapPath.DIRECTORY_SEPARATOR.'_manifest_exclude');
         $output->writeln('<info>+d</info> ' . str_replace($basePath, '', realpath($featuresPath)) . ' <comment>- place your *.feature files here</comment>');
     }
     if (!is_dir($contextPath)) {
         mkdir($contextPath, 0777, true);
         $className = $this->container->getParameter('behat.context.class');
         file_put_contents($contextPath . DIRECTORY_SEPARATOR . $className . '.php', strtr($this->getFeatureContextSkelet(), array('%NAMESPACE%' => $namespace)));
         $output->writeln('<info>+f</info> ' . str_replace($basePath, '', realpath($contextPath)) . DIRECTORY_SEPARATOR . 'FeatureContext.php <comment>- place your feature related code here</comment>');
     }
 }
 /**
  * Updates the database schema, creating tables & fields as necessary.
  */
 public function build()
 {
     // The default time limit of 30 seconds is normally not enough
     increase_time_limit_to(600);
     // Get all our classes
     SS_ClassLoader::instance()->getManifest()->regenerate();
     if (isset($_GET['returnURL'])) {
         echo "<p>Setting up the database; you will be returned to your site shortly....</p>";
         $this->doBuild(true);
         echo "<p>Done!</p>";
         $this->redirect($_GET['returnURL']);
     } else {
         $this->doBuild(isset($_REQUEST['quiet']) || isset($_REQUEST['from_installer']), !isset($_REQUEST['dont_populate']));
     }
 }
Example #16
0
 /**
  * Updates the database schema, creating tables & fields as necessary.
  */
 function build()
 {
     // The default time limit of 30 seconds is normally not enough
     increase_time_limit_to(600);
     // Get all our classes
     SS_ClassLoader::instance()->getManifest()->regenerate();
     if (isset($_GET['returnURL'])) {
         echo "<p>Setting up the database; you will be returned to your site shortly....</p>";
         $this->doBuild(true);
         echo "<p>Done!</p>";
         Director::redirect($_GET['returnURL']);
     } else {
         if (!Director::is_cli() && Director::urlParam('Controller') == __CLASS__) {
             echo '<p style="color: red;"><i>db/build</i> has been deprecated. Please use <b>dev/build</b> instead.</p>';
         }
         $this->doBuild(isset($_REQUEST['quiet']) || isset($_REQUEST['from_installer']), !isset($_REQUEST['dont_populate']));
     }
 }
 /**
  * Gets the fields to configure the panel settings
  *
  * @return FieldList
  */
 public function getConfiguration()
 {
     $fields = parent::getConfiguration();
     $modeladmins = array();
     $models = $this->getManagedModelsFor($this->ModelAdminClass);
     foreach (SS_ClassLoader::instance()->getManifest()->getDescendantsOf("ModelAdmin") as $class) {
         $SNG = Injector::inst()->get($class);
         if ($SNG instanceof TestOnly) {
             continue;
         }
         $title = Config::inst()->get($class, "menu_title", Config::INHERITED);
         $modeladmins[$class] = $title ? $title : $class;
     }
     $fields->push(TextField::create("Count", _t('DashbordModelAdmin.COUNT', 'Number of records to display')));
     $fields->push(DropdownField::create("ModelAdminClass", _t('Dashboard.MODELADMINCLASS', 'Model admin tab'), $modeladmins)->addExtraClass('no-chzn')->setAttribute('data-lookupurl', $this->Link("modelsforpanel"))->setEmptyString("--- " . _t('Dashboard.PLEASESELECT', 'Please select') . " ---"));
     $fields->push(DropdownField::create("ModelAdminModel", _t('Dashboard.MODELADMINMODEL', 'Model'), $models)->addExtraClass('no-chzn'));
     return $fields;
 }
Example #18
0
 /**
  * Updates the database schema, creating tables & fields as necessary.
  */
 public function build()
 {
     // The default time limit of 30 seconds is normally not enough
     increase_time_limit_to(600);
     // Get all our classes
     SS_ClassLoader::instance()->getManifest()->regenerate();
     $url = $this->getReturnURL();
     if ($url) {
         echo "<p>Setting up the database; you will be returned to your site shortly....</p>";
         $this->doBuild(true);
         echo "<p>Done!</p>";
         $this->redirect($url);
     } else {
         $quiet = $this->request->requestVar('quiet') !== null;
         $fromInstaller = $this->request->requestVar('from_installer') !== null;
         $populate = $this->request->requestVar('dont_populate') === null;
         $this->doBuild($quiet || $fromInstaller, $populate);
     }
 }
 /**
  * @return array
  */
 public static function get_searchable_classes()
 {
     // First get any explicitly declared searchable classes
     $searchable = Config::inst()->get('ShopSearch', 'searchable');
     if (is_string($searchable) && strlen($searchable) > 0) {
         $searchable = array($searchable);
     } elseif (!is_array($searchable)) {
         $searchable = array();
     }
     // Add in buyables automatically if asked
     if (Config::inst()->get('ShopSearch', 'buyables_are_searchable')) {
         $buyables = SS_ClassLoader::instance()->getManifest()->getImplementorsOf('Buyable');
         if (is_array($buyables) && count($buyables) > 0) {
             foreach ($buyables as $c) {
                 $searchable[] = $c;
             }
         }
     }
     return array_unique($searchable);
 }
 /**
  * Processes data from container and console input.
  *
  * @param InputInterface  $input
  * @param OutputInterface $output
  *
  * @throws \RuntimeException
  */
 public function process(InputInterface $input, OutputInterface $output)
 {
     $featuresPath = $input->getArgument('features');
     // Can't use 'behat.paths.base' since that's locked at this point to base folder (not module)
     $pathSuffix = $this->container->getParameter('behat.silverstripe_extension.context.path_suffix');
     $currentModuleName = null;
     $modules = \SS_ClassLoader::instance()->getManifest()->getModules();
     // get module specified in behat.yml
     $currentModuleName = $this->container->getParameter('behat.silverstripe_extension.module');
     // get module from short notation if path starts from @
     if ($featuresPath && preg_match('/^\\@([^\\/\\\\]+)(.*)$/', $featuresPath, $matches)) {
         $currentModuleName = $matches[1];
         // TODO Replace with proper module loader once AJShort's changes are merged into core
         $currentModulePath = $modules[$currentModuleName];
         $featuresPath = str_replace('@' . $currentModuleName, $currentModulePath . DIRECTORY_SEPARATOR . $pathSuffix, $featuresPath);
         // get module from provided features path
     } elseif (!$currentModuleName && $featuresPath) {
         $path = realpath(preg_replace('/\\.feature\\:.*$/', '.feature', $featuresPath));
         foreach ($modules as $moduleName => $modulePath) {
             if (false !== strpos($path, realpath($modulePath))) {
                 $currentModuleName = $moduleName;
                 $currentModulePath = realpath($modulePath);
                 break;
             }
         }
         $featuresPath = $currentModulePath . DIRECTORY_SEPARATOR . $pathSuffix . DIRECTORY_SEPARATOR . $featuresPath;
         // if module is configured for profile and feature provided
     } elseif ($currentModuleName && $featuresPath) {
         $currentModulePath = $modules[$currentModuleName];
         $featuresPath = $currentModulePath . DIRECTORY_SEPARATOR . $pathSuffix . DIRECTORY_SEPARATOR . $featuresPath;
     }
     if ($input->getOption('namespace')) {
         $namespace = $input->getOption('namespace');
     } else {
         $namespace = ucfirst($currentModuleName);
     }
     if ($currentModuleName) {
         $this->container->get('behat.silverstripe_extension.context.class_guesser')->setNamespaceBase($namespace);
     }
     $this->container->get('behat.console.command')->setFeaturesPaths($featuresPath ? array($featuresPath) : array());
 }
Example #21
0
 /**
  * Set up the simplest intial query
  */
 function initialiseQuery()
 {
     // Get the tables to join to
     $tableClasses = ClassInfo::dataClassesFor($this->dataClass);
     // Error checking
     if (!$tableClasses) {
         if (!SS_ClassLoader::instance()->hasManifest()) {
             user_error("DataObjects have been requested before the manifest is loaded. Please ensure you are not querying the database in _config.php.", E_USER_ERROR);
         } else {
             user_error("DataObject::buildSQL: Can't find data classes (classes linked to tables) for {$this->dataClass}. Please ensure you run dev/build after creating a new DataObject.", E_USER_ERROR);
         }
     }
     $baseClass = array_shift($tableClasses);
     $select = array("\"{$baseClass}\".*");
     // Build our intial query
     $this->query = new SQLQuery(array());
     $this->query->distinct = true;
     if ($sort = singleton($this->dataClass)->stat('default_sort')) {
         $this->sort($sort);
     }
     $this->query->from("\"{$baseClass}\"");
     $this->selectAllFromTable($this->query, $baseClass);
     singleton($this->dataClass)->extend('augmentDataQueryCreation', $this->query, $this);
 }
 /**
  * Returns all classes contained in a certain folder.
  *
  * @todo Doesn't return additional classes that only begin
  *  with the filename, and have additional naming separated through underscores.
  *
  * @param string $folderPath Relative or absolute folder path
  * @return array Array of class names
  */
 public static function classes_for_folder($folderPath)
 {
     $absFolderPath = Director::getAbsFile($folderPath);
     $matchedClasses = array();
     $manifest = SS_ClassLoader::instance()->getManifest()->getClasses();
     foreach ($manifest as $class => $compareFilePath) {
         if (stripos($compareFilePath, $absFolderPath) === 0) {
             $matchedClasses[] = $class;
         }
     }
     return $matchedClasses;
 }
Example #23
0
 function getModule()
 {
     $classes = SS_ClassLoader::instance()->getManifest()->getClasses();
     $className = strtolower($this->className);
     if (($pos = strpos($className, '_')) !== false) {
         $className = substr($className, 0, $pos);
     }
     if (isset($classes[$className])) {
         if (preg_match('/^' . str_replace('/', '\\/', preg_quote(BASE_PATH)) . '\\/([^\\/]+)\\//', $classes[$className], $matches)) {
             return $matches[1];
         }
     }
 }
Example #24
0
 /**
  * Set up the simplest initial query
  */
 public function initialiseQuery()
 {
     // Get the tables to join to.
     // Don't get any subclass tables - let lazy loading do that.
     $tableClasses = ClassInfo::ancestry($this->dataClass, true);
     // Error checking
     if (!$tableClasses) {
         if (!SS_ClassLoader::instance()->hasManifest()) {
             user_error("DataObjects have been requested before the manifest is loaded. Please ensure you are not" . " querying the database in _config.php.", E_USER_ERROR);
         } else {
             user_error("DataObject::buildSQL: Can't find data classes (classes linked to tables) for" . " {$this->dataClass}. Please ensure you run dev/build after creating a new DataObject.", E_USER_ERROR);
         }
     }
     $baseClass = array_shift($tableClasses);
     // Build our intial query
     $this->query = new SQLQuery(array());
     $this->query->setDistinct(true);
     if ($sort = singleton($this->dataClass)->stat('default_sort')) {
         $this->sort($sort);
     }
     $this->query->setFrom("\"{$baseClass}\"");
     $obj = Injector::inst()->get($baseClass);
     $obj->extend('augmentDataQueryCreation', $this->query, $this);
 }
 /**
  * Pushes a class and template manifest instance that include tests onto the
  * top of the loader stacks.
  */
 public static function use_test_manifest()
 {
     $flush = true;
     if (isset($_GET['flush']) && $_GET['flush'] === '0') {
         $flush = false;
     }
     $classManifest = new SS_ClassManifest(BASE_PATH, true, $flush);
     SS_ClassLoader::instance()->pushManifest($classManifest, false);
     SapphireTest::set_test_class_manifest($classManifest);
     ThemeResourceLoader::instance()->addSet('$default', new ThemeManifest(BASE_PATH, project(), true, $flush));
     Config::inst()->pushConfigStaticManifest(new SS_ConfigStaticManifest(BASE_PATH, true, $flush));
     // Invalidate classname spec since the test manifest will now pull out new subclasses for each internal class
     // (e.g. Member will now have various subclasses of DataObjects that implement TestOnly)
     DataObject::reset();
 }
Example #26
0
/**
 * @deprecated 3.0 Please use {@link SS_ClassManifest::getItemPath()}.
 */
function getClassFile($className)
{
    Deprecation::notice('3.0', 'Use SS_ClassManifest::getItemPath() instead.');
    return SS_ClassLoader::instance()->getManifest()->getItemPath($className);
}
 /**
  * @return SS_ClassLoader
  */
 public static function instance()
 {
     return self::$instance ? self::$instance : (self::$instance = new self());
 }
Example #28
0
 /**
  * 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) {
         $cache = Zend_Translate::getCache();
         if ($cache) {
             $cache->clean(Zend_Cache::CLEANING_MODE_ALL);
         }
     }
     // Sort modules by inclusion priority, then alphabetically
     // TODO Should be handled by priority flags within modules
     $prios = array('sapphire' => 10, 'framework' => 10, 'admin' => 11, 'cms' => 12, 'mysite' => 90);
     $modules = SS_ClassLoader::instance()->getManifest()->getModules();
     ksort($modules);
     uksort($modules, function ($a, $b) use(&$prios) {
         $prioA = isset($prios[$a]) ? $prios[$a] : 50;
         $prioB = isset($prios[$b]) ? $prios[$b] : 50;
         return $prioA > $prioB;
     });
     // Loop in reverse order, meaning the translator with the highest priority goes first
     $translators = array_reverse(self::get_translators(), true);
     foreach ($translators as $priority => $translators) {
         foreach ($translators as $name => $translator) {
             $adapter = $translator->getAdapter();
             // Load translations from modules
             foreach ($modules 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, SSViewer::current_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));
         }
     }
 }
 /**
  * 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 = SS_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 = Config::inst()->get('i18n', '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 {
         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
     $translators = array_reverse(self::get_translators(), true);
     foreach ($translators as $priority => $translators) {
         foreach ($translators as $name => $translator) {
             $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('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));
         }
     }
 }
Example #30
0
require_once 'control/injector/Injector.php';
// Initialise the dependency injector as soon as possible, as it is
// subsequently used by some of the following code
$injector = new Injector(array('locator' => 'SilverStripeServiceConfigurationLocator'));
Injector::set_inst($injector);
///////////////////////////////////////////////////////////////////////////////
// MANIFEST
// Regenerate the manifest if ?flush is set, or if the database is being built.
// The coupling is a hack, but it removes an annoying bug where new classes
// referenced in _config.php files can be referenced during the build process.
$requestURL = isset($_REQUEST['url']) ? trim($_REQUEST['url'], '/') : false;
$flush = isset($_GET['flush']) || $requestURL === trim(BASE_URL . '/dev/build', '/');
global $manifest;
$manifest = new SS_ClassManifest(BASE_PATH, false, $flush);
// Register SilverStripe's class map autoload
$loader = SS_ClassLoader::instance();
$loader->registerAutoloader();
$loader->pushManifest($manifest);
// Fall back to Composer's autoloader (e.g. for PHPUnit), if composer is used
if (file_exists(BASE_PATH . '/vendor/autoload.php')) {
    require_once BASE_PATH . '/vendor/autoload.php';
}
// Now that the class manifest is up, load the static configuration
$configManifest = new SS_ConfigStaticManifest(BASE_PATH, false, $flush);
Config::inst()->pushConfigStaticManifest($configManifest);
// And then the yaml configuration
$configManifest = new SS_ConfigManifest(BASE_PATH, false, $flush);
Config::inst()->pushConfigYamlManifest($configManifest);
// Load template manifest
SS_TemplateLoader::instance()->pushManifest(new SS_TemplateManifest(BASE_PATH, project(), false, $flush));
// If in live mode, ensure deprecation, strict and notices are not reported