/** * Constructs the container and set up default services and properties */ public function __construct() { parent::__construct(); //Shared services $this['twig'] = $this->share(function ($c) { $envOptions = array_merge(array('cache' => $c['twig.compilation_cache']), $c['twig.environment_options']); $twig = new Twig_Environment($c['twig.loader'], $envOptions); if (isset($envOptions['debug']) && $envOptions['debug']) { $twig->addExtension(new Twig_Extension_Debug()); } return $twig; }); $this['twig.loader'] = $this->share(function ($c) { return new $c['twig.loader_class']($c['twig.template_paths']); }); //Dynamic props $this['twig.compilation_cache'] = BASE_PATH . '/twig-cache'; $this['twig.template_paths'] = THEMES_PATH . '/' . SSViewer::current_theme() . '/twig'; //Default config foreach (self::$config as $key => $value) { $this[$key] = $value; } //Extensions if (is_array(self::$extensions)) { foreach (self::$extensions as $value) { $this->extend($value[0], $value[1]); } } //Shared if (is_array(self::$shared)) { foreach (self::$shared as $value) { $this[$value[0]] = $this->share($value[1]); } } }
public function init() { parent::init(); // We don't want this showing up in every ajax-response, it should always be present in a CMS-environment if (!Director::is_ajax()) { Requirements::javascriptTemplate("cms/javascript/tinymce.template.js", array("ContentCSS" => (SSViewer::current_theme() ? "themes/" . SSViewer::current_theme() : project()) . "/css/editor.css", "BaseURL" => Director::absoluteBaseURL(), "Lang" => i18n::get_tinymce_lang())); } Requirements::javascript('cms/javascript/CMSMain.js'); Requirements::javascript('cms/javascript/CMSMain_left.js'); Requirements::javascript('cms/javascript/CMSMain_right.js'); Requirements::javascript('sapphire/javascript/UpdateURL.js'); /** * HACK ALERT: Project-specific requirements * * We need a better way of including all of the CSS that *might* be used by this application. * Perhaps the ajax responses can include some instructions to go get more CSS / JavaScript? */ Requirements::css("survey/css/SurveyFilter.css"); Requirements::javascript("survey/javascript/SurveyResponses.js"); Requirements::javascript("survey/javascript/FormResponses.js"); Requirements::javascript("parents/javascript/NotifyMembers.js"); Requirements::css("tourism/css/SurveyCMSMain.css"); Requirements::javascript("tourism/javascript/QuotasReport.js"); Requirements::javascript("sapphire/javascript/ReportField.js"); Requirements::javascript("ptraining/javascript/BookingList.js"); Requirements::javascript("forum/javascript/ForumAccess.js"); Requirements::javascript('gallery/javascript/GalleryPage_CMS.js'); }
function setUp() { parent::setUp(); $this->alternateBasePath = $this->getCurrentAbsolutePath() . "/_fakewebroot"; $this->alternateBaseSavePath = TEMP_FOLDER . '/i18nTextCollectorTest_webroot'; FileSystem::makeFolder($this->alternateBaseSavePath); Director::setBaseFolder($this->alternateBasePath); // Push a template loader running from the fake webroot onto the stack. $templateManifest = new SS_TemplateManifest($this->alternateBasePath, false, true); $templateManifest->regenerate(false); SS_TemplateLoader::instance()->pushManifest($templateManifest); $this->_oldTheme = SSViewer::current_theme(); SSViewer::set_theme('testtheme1'); $this->originalLocale = i18n::get_locale(); // Override default adapter to avoid cached translations between tests. // Emulates behaviour in i18n::get_translators() $this->origAdapter = i18n::get_translator('core'); $adapter = new Zend_Translate(array( 'adapter' => 'i18nRailsYamlAdapter', 'locale' => i18n::default_locale(), 'disableNotices' => true, )); i18n::register_translator($adapter, 'core'); $adapter->removeCache(); i18n::include_by_locale('en'); }
/** * looked-up the email template_paths. * if not set, will look up both theme folder and project folder * in both cases, email folder exsits or Email folder exists * return an array containing all folders pointing to the bunch of email templates * * @return array */ public static function template_paths() { if (!isset(self::$template_paths)) { if (class_exists('SiteConfig') && ($config = SiteConfig::current_site_config()) && $config->Theme) { $theme = $config->Theme; } elseif (SSViewer::current_custom_theme()) { $theme = SSViewer::current_custom_theme(); } elseif (SSViewer::current_theme()) { $theme = SSViewer::current_theme(); } else { $theme = false; } if ($theme) { if (file_exists("../" . THEMES_DIR . "/" . $theme . "/templates/email")) { self::$template_paths[] = THEMES_DIR . "/" . $theme . "/templates/email"; } if (file_exists("../" . THEMES_DIR . "/" . $theme . "/templates/Email")) { self::$template_paths[] = THEMES_DIR . "/" . $theme . "/templates/Email"; } } $project = project(); if (file_exists("../" . $project . '/templates/email')) { self::$template_paths[] = $project . '/templates/email'; } if (file_exists("../" . $project . '/templates/Email')) { self::$template_paths[] = $project . '/templates/Email'; } } else { if (is_string(self::$template_paths)) { self::$template_paths = array(self::$template_paths); } } return self::$template_paths; }
/** * When an error page is published, create a static HTML page with its * content, so the page can be shown even when SilverStripe is not * functioning correctly before publishing this page normally. * @param string|int $fromStage Place to copy from. Can be either a stage name or a version number. * @param string $toStage Place to copy to. Must be a stage name. * @param boolean $createNewVersion Set this to true to create a new version number. By default, the existing version number will be copied over. */ function doPublish() { parent::doPublish(); // Run the page (reset the theme, it might've been disabled by LeftAndMain::init()) $oldTheme = SSViewer::current_theme(); SSViewer::set_theme(SSViewer::current_custom_theme()); $response = Director::test(Director::makeRelative($this->Link())); SSViewer::set_theme($oldTheme); $errorContent = $response->getBody(); // Make the base tag dynamic. // $errorContent = preg_replace('/<base[^>]+href="' . str_replace('/','\\/', Director::absoluteBaseURL()) . '"[^>]*>/i', '<base href="$BaseURL" />', $errorContent); // Check we have an assets base directory, creating if it we don't if (!file_exists(ASSETS_PATH)) { mkdir(ASSETS_PATH, 02775); } // if the page is published in a language other than default language, // write a specific language version of the HTML page $filePath = self::get_filepath_for_errorcode($this->ErrorCode, $this->Locale); if ($fh = fopen($filePath, "w")) { fwrite($fh, $errorContent); fclose($fh); } else { $fileErrorText = sprintf(_t("ErrorPage.ERRORFILEPROBLEM", "Error opening file \"%s\" for writing. Please check file permissions."), $errorFile); FormResponse::status_message($fileErrorText, 'bad'); FormResponse::respond(); return; } }
/** * Set the global options for all pdfs * @param array $options A list with all possible options can be found here http://wkhtmltopdf.org/usage/wkhtmltopdf.txt */ public function setGlobalOptions($options = null) { if (!$options) { $css = BASE_PATH . '/themes/' . SSViewer::current_theme() . '/css/pdf.css'; $header = BASE_PATH . '/mysite/templates/Pdf/header.html'; $footer = BASE_PATH . '/mysite/templates/Pdf/footer.html'; $options = array('no-outline', 'enable-javascript', 'enable-smart-shrinking', 'encoding' => 'UTF-8', 'dpi' => 150, 'image-dpi' => 150, 'image-quality' => 100, 'user-style-sheet' => $css, 'orientation' => 'Portrait', 'page-height' => '297mm', 'page-width' => '210mm', 'page-size' => 'A4', 'margin-bottom' => 30, 'margin-left' => 10, 'margin-right' => 10, 'margin-top' => 30, 'header-html' => $header, 'footer-html' => $footer); } $this->globalOptions = $options; }
/** * Return the relative URL of an icon for the file type, * based on the {@link appCategory()} value. * Images are searched for in "sapphire/images/app_icons/". * * @return String */ public function getIcon($file) { $ext = $this->getExt($file); if (!Director::fileExists("themes/" . SSViewer::current_theme() . "/images/icons/file_extension_{$ext}.png")) { $ext = $this->appCategory($file); } if (!Director::fileExists("themes/" . SSViewer::current_theme() . "/images/icons/file_extension_{$ext}.png")) { $ext = "generic"; } return "themes/" . SSViewer::current_theme() . "/images/icons/file_extension_{$ext}.png"; }
/** * Determines the theme names that should be considered * @return array List of theme names to use */ protected function findThemes() { $themes = array($currentTheme = SSViewer::current_theme()); if (self::$include_subthemes) { foreach (scandir(THEMES_PATH) as $theme) { if (preg_match("/^{$currentTheme}_.+\$/i", $theme)) { $themes[] = $theme; } } } return $themes; }
/** * Returns a relative path to current theme directory. * * @return mixed */ public function ThemeDir() { if ($theme = SSViewer::current_theme()) { return THEMES_DIR . "/{$theme}"; } elseif ($theme = SSViewer::current_custom_theme()) { return THEMES_DIR . "/{$theme}"; } elseif ($theme = SiteConfig::current_site_config()->Theme) { return THEMES_DIR . "/{$theme}"; } else { throw new Exception("cannot detect theme"); } }
public static function get_css_folder() { if (Config::inst()->get("TypographyTestPage", "css_folder")) { $folder = Config::inst()->get("TypographyTestPage", "css_folder"); } else { $folder = "themes/" . SSViewer::current_theme() . "/css/"; } $fullFolder = Director::baseFolder() . '/' . $folder; if (!file_exists($fullFolder)) { user_error("could not find the default CSS folder {$fullFolder}"); $folder = ''; } return $folder; }
function setUp() { parent::setUp(); $this->mainSession = new TestSession(); // Disable theme, if necessary if ($this->stat('disable_themes')) { $this->originalTheme = SSViewer::current_theme(); SSViewer::set_theme(null); } // Switch to draft site, if necessary if ($this->stat('use_draft_site')) { $this->useDraftSite(); } }
public function doExport($data, $form) { $data = $form->getData(); $links = array(); $siteTitle = SiteConfig::current_site_config()->Title; // If the queued jobs module is installed, then queue up an export // job rather than performing the export. if (class_exists('QueuedJobService')) { $job = new SiteExportJob($form->getRecord()); $job->theme = $data['ExportSiteTheme']; $job->baseUrl = $data['ExportSiteBaseUrl']; $job->baseUrlType = $data['ExportSiteBaseUrlType']; $job->email = $data['ExportSiteCompleteEmail']; singleton('QueuedJobService')->queueJob($job); return new SS_HTTPResponse($form->dataFieldByName('SiteExports')->FieldHolder(), 200, 'The site export job has been queued.'); } // First generate a temp directory to store the export content in. $temp = TEMP_FOLDER; $temp .= sprintf('/siteexport_%s', date('Y-m-d-His')); mkdir($temp); $exporter = new SiteExporter(); $exporter->root = $form->getRecord(); $exporter->theme = $data['ExportSiteTheme']; $exporter->baseUrl = $data['ExportSiteBaseUrl']; $exporter->makeRelative = $data['ExportSiteBaseUrlType'] == 'rewrite'; $exporter->exportTo($temp); // Then place the exported content into an archive, stored in the assets // root, and create a site export for it. $filename = preg_replace('/[^a-zA-Z0-9-.+]/', '-', sprintf('%s-%s.zip', $siteTitle, date('c'))); $dir = Folder::findOrMake(self::EXPORTS_DIR); $dirname = ASSETS_PATH . '/' . self::EXPORTS_DIR; $pathname = "{$dirname}/{$filename}"; SiteExportUtils::zip_directory($temp, "{$dirname}/{$filename}"); Filesystem::removeFolder($temp); $file = new File(); $file->ParentID = $dir->ID; $file->Title = $siteTitle . ' ' . date('c'); $file->Filename = $dir->Filename . $filename; $file->write(); $export = new SiteExport(); $export->ParentClass = $form->getRecord()->class; $export->ParentID = $form->getRecord()->ID; $export->Theme = SSViewer::current_theme(); $export->BaseUrlType = ucfirst($data['ExportSiteBaseUrlType']); $export->BaseUrl = $data['ExportSiteBaseUrl']; $export->ArchiveID = $file->ID; $export->write(); return new SS_HTTPResponse($form->dataFieldByName('SiteExports')->FieldHolder(), 200, 'The site export has been generated.'); }
function requireDefaultRecords() { parent::requireDefaultRecords(); // If css file does not exist on current theme, copy from module $copyfrom = BASE_PATH . "/" . CONTENTBLOCKS_MODULE_DIR . "/css/block.css"; $theme = SSViewer::current_theme(); $copyto = BASE_PATH . "/themes/" . $theme . "/css/block.css"; if (!file_exists($copyto)) { if (file_exists($copyfrom)) { copy($copyfrom, $copyto); echo '<li style="green: green">block.css copied to: ' . $copyto . '</li>'; } else { echo '<li style="red">The default css file was not found: ' . $copyfrom . '</li>'; } } }
function requireDefaultRecords() { parent::requireDefaultRecords(); // Run on dev buld // If templates does not exist on current theme, copy from module $theme = SSViewer::current_theme(); $copyto = "../themes/" . $theme . "/templates/" . CONTENTBLOCKS_TEMPLATE_DIR . "/"; if (!file_exists($copyto)) { $copyfrom = BASE_PATH . "/" . CONTENTBLOCKS_MODULE_DIR . "/templates/" . CONTENTBLOCKS_TEMPLATE_DIR . "/"; if (file_exists($copyfrom)) { $this->recurse_copy($copyfrom, $copyto); echo '<li style="color: green">BlockTemplates copied to: ' . $copyto . '</li>'; } else { echo "The default template archive was not found: " . $copyfrom; } } }
/** * Tests for {@link SSViewer::current_theme()} for different behaviour * of user defined themes via {@link SiteConfig} and default theme * when no user themes are defined. */ function testCurrentTheme() { $config = SiteConfig::current_site_config(); $oldTheme = $config->Theme; $config->Theme = ''; $config->write(); SSViewer::set_theme('mytheme'); $this->assertEquals('mytheme', SSViewer::current_theme(), 'Current theme is the default - user has not defined one'); $config->Theme = 'myusertheme'; $config->write(); // Pretent to load the page $c = new ContentController(); $c->init(); $this->assertEquals('myusertheme', SSViewer::current_theme(), 'Current theme is a user defined one'); // Set the theme back to the original $config->Theme = $oldTheme; $config->write(); }
public function getFiles() { $files = LanguageAdmin::$modules; $valid_dirs = array(); $yaml_files = new ArrayList(); foreach ($files as $file) { if (is_dir($_SERVER["DOCUMENT_ROOT"] . "/" . $file)) { if (file_exists($_SERVER["DOCUMENT_ROOT"] . "/" . $file . "/_config.php") || $file == "themes") { $valid_dirs[] = $file; $temp = ""; if ($file == "themes") { $theme = SiteConfig::current_site_config()->Theme; if ($theme == "") { $theme = SSViewer::current_theme(); } $temp = glob($_SERVER["DOCUMENT_ROOT"] . "/themes/{$theme}/lang/*.yml"); //die(print_r($temp)); } else { $temp = glob($_SERVER["DOCUMENT_ROOT"] . "/" . $file . '/lang/*.yml'); } if (is_array($temp)) { foreach ($temp as $key => $value) { $info = pathinfo($value); $lang = new ViewableData(); $lang->__set("Locale", $info["filename"]); $lang->__set("Path", $value); $lang->__set("Module", $file); $locales = ""; if (SiteTree::has_extension("Translatable")) { $locales = Translatable::get_allowed_locales(); } else { $locales = array("it_IT"); } if (in_array($info["filename"], $locales)) { $yaml_files->push($lang); } } } } } } return $yaml_files; }
public static function setupRequirements($cssArray = array(), $jsArray = array()) { $siteConfig = SiteConfig::current_site_config(); // Don't combine files if in admin to prevent error on "login as someone else" screen $inAdmin = is_subclass_of(Controller::curr(), "LeftAndMain"); // Setup requirements if (isset(Page_Controller::$themeFolderAndSubfolder) && Page_Controller::$themeFolderAndSubfolder) { self::$themeFolderAndSubfolder = Page_Controller::$themeFolderAndSubfolder; } else { $currentTheme = SSViewer::current_theme(); self::$themeFolderAndSubfolder = 'themes/' . $currentTheme; } //Set a custom combined folder under themes so relative paths to images within CSS and JavaScript files don't break Requirements::set_combined_files_folder(self::$themeFolderAndSubfolder . '/combined'); // CSS array if (count($cssArray)) { foreach ($cssArray as $css) { Requirements::css($css); } if (!$inAdmin) { Requirements::combine_files("combined-" . $siteConfig->ID . ".css", $cssArray); } } // Javascript array if (count($jsArray)) { foreach ($jsArray as $js) { Requirements::javascript($js); } if (!$inAdmin) { Requirements::combine_files("combined-" . $siteConfig->ID . ".js", $jsArray); } } if (!$inAdmin) { Requirements::process_combined_files(); } // Google analytics if (!Director::isDev()) { if (isset($siteConfig->GoogleAnalyticsCode)) { Requirements::insertHeadTags($siteConfig->GoogleAnalyticsCode); } } // End Google analytics }
/** * Perform the crunch work of compiling less files on initilisation, * but only do this when we are running on dev (and the file is in * need of updating). * */ public function onBeforeInit() { // Only check and compile when on dev if (Director::isDev()) { $files = LessCompilerConfig::config()->file_mappings; $root_path = LessCompilerConfig::config()->root_path; $temp_folder = TEMP_FOLDER; if (is_array($files)) { $theme_dir = Controller::join_links("themes", SSViewer::current_theme()); $base_theme = Controller::join_links($theme_dir, SSViewer::current_theme()); $options = array('cache_dir' => $temp_folder); if (LessCompilerConfig::config()->compress) { $options['compress'] = true; } // First loop through all files and deal with inputs foreach ($files as $input => $output) { if ($input && $output) { // Does output and input contain a path if (strpos($input, '/') === false) { $input = Controller::join_links($theme_dir, "less", $input); } if (strpos($output, '/') === false) { $output = Controller::join_links($theme_dir, "css", $output); } // Now append the full system path to the input // and output file. $input = Controller::join_links(BASE_PATH, $input); $output = Controller::join_links(BASE_PATH, $output); // Finally try to compile our less files try { $css_file_name = Less_Cache::Get(array($input => $root_path), $options); $css = file_get_contents(Controller::join_links($temp_folder, $css_file_name)); $output_file = fopen($output, "w"); fwrite($output_file, $css); fclose($output_file); } catch (exception $e) { error_log($e->getMessage()); } } } } } }
function testStaticPublisherTheme() { //This will be the name of the default theme of this particular project $default_theme = SSViewer::current_theme(); $p1 = new Page(); $p1->URLSegment = strtolower(__CLASS__) . '-page-1'; $p1->HomepageForDomain = ''; $p1->write(); $p1->doPublish(); $current_theme = SSViewer::current_custom_theme(); $this->assertEquals($current_theme, $default_theme, 'After a standard publication, the theme is correct'); //The CMS sometimes sets the theme to null. Check that the $current_custom_theme is still the default SSViewer::set_theme(null); $current_theme = SSViewer::current_custom_theme(); $this->assertEquals($current_theme, $default_theme, 'After a setting the theme to null, the default theme is correct'); //We can set the static_publishing theme to something completely different: //Static publishing will use this one instead of the current_custom_theme if it is not false StaticPublisher::set_static_publisher_theme('otherTheme'); $current_theme = StaticPublisher::static_publisher_theme(); $this->assertNotEquals($current_theme, $default_theme, 'The static publisher theme overrides the custom theme'); }
/** * 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 $load_plugins If true (default), load extra translations from registered plugins * @param boolean $force_load If true (not default), we force the inclusion. Generally this should be off * for performance, but enabling this is useful for interfaces like * CustomTranslationAdmin which need to load more than the usual locales, * and may need to reload them. */ static function include_by_locale($locale, $load_plugins = true, $force_load = false) { if (!self::validate_locale($locale)) { throw new InvalidArgumentException(sprintf('Invalid locale "%s"', $locale)); } global $lang; $base = Director::baseFolder(); $topLevel = scandir($base); foreach ($topLevel as $module) { // $topLevel is the website root, some servers are configured not to allow excess website root's parent level // and we don't need to check website root's parent level and website root level for its lang folder, so // we skip these 2 levels checking. if ($module[0] == '.') { continue; } if (is_dir("{$base}/{$module}") && file_exists("{$base}/{$module}/_config.php") && file_exists($file = "{$base}/{$module}/lang/{$locale}.php")) { if ($force_load) { include $file; } else { include_once $file; } } } // Load translations from themes $themesBase = $base . '/themes'; foreach (scandir($themesBase) as $theme) { if (strpos($theme, SSViewer::current_theme()) === 0 && file_exists($file = "{$themesBase}/{$theme}/lang/{$locale}.php")) { if ($force_load) { include $file; } else { include_once $file; } } } // Finally, load any translations from registered plugins if ($load_plugins) { self::plugins_load($locale); } }
/** * @uses LeftAndMainExtension->init() * @uses LeftAndMainExtension->accessedCMS() * @uses CMSMenu */ function init() { parent::init(); SSViewer::setOption('rewriteHashlinks', false); // set language $member = Member::currentUser(); if (!empty($member->Locale)) { i18n::set_locale($member->Locale); } if (!empty($member->DateFormat)) { i18n::set_date_format($member->DateFormat); } if (!empty($member->TimeFormat)) { i18n::set_time_format($member->TimeFormat); } // can't be done in cms/_config.php as locale is not set yet CMSMenu::add_link('Help', _t('LeftAndMain.HELP', 'Help', 'Menu title'), self::$help_link); // Allow customisation of the access check by a extension // Also all the canView() check to execute Controller::redirect() if (!$this->canView() && !$this->response->isFinished()) { // When access /admin/, we should try a redirect to another part of the admin rather than be locked out $menu = $this->MainMenu(); foreach ($menu as $candidate) { if ($candidate->Link && $candidate->Link != $this->Link() && $candidate->MenuItem->controller && singleton($candidate->MenuItem->controller)->canView()) { return $this->redirect($candidate->Link); } } if (Member::currentUser()) { Session::set("BackURL", null); } // if no alternate menu items have matched, return a permission error $messageSet = array('default' => _t('LeftAndMain.PERMDEFAULT', "Please choose an authentication method and enter your credentials to access the CMS."), 'alreadyLoggedIn' => _t('LeftAndMain.PERMALREADY', "I'm sorry, but you can't access that part of the CMS. If you want to log in as someone else, do so below"), 'logInAgain' => _t('LeftAndMain.PERMAGAIN', "You have been logged out of the CMS. If you would like to log in again, enter a username and password below.")); return Security::permissionFailure($this, $messageSet); } // Don't continue if there's already been a redirection request. if ($this->redirectedTo()) { return; } // Audit logging hook if (empty($_REQUEST['executeForm']) && !$this->request->isAjax()) { $this->extend('accessedCMS'); } // Set the members html editor config HtmlEditorConfig::set_active(Member::currentUser()->getHtmlEditorConfigForCMS()); // Set default values in the config if missing. These things can't be defined in the config // file because insufficient information exists when that is being processed $htmlEditorConfig = HtmlEditorConfig::get_active(); $htmlEditorConfig->setOption('language', i18n::get_tinymce_lang()); if (!$htmlEditorConfig->getOption('content_css')) { $cssFiles = array(); $cssFiles[] = FRAMEWORK_ADMIN_DIR . '/css/editor.css'; // Use theme from the site config if (class_exists('SiteConfig') && ($config = SiteConfig::current_site_config()) && $config->Theme) { $theme = $config->Theme; } elseif (SSViewer::current_theme()) { $theme = SSViewer::current_theme(); } else { $theme = false; } if ($theme) { $cssFiles[] = THEMES_DIR . "/{$theme}/css/editor.css"; } else { if (project()) { $cssFiles[] = project() . '/css/editor.css'; } } // Remove files that don't exist foreach ($cssFiles as $k => $cssFile) { if (!file_exists(BASE_PATH . '/' . $cssFile)) { unset($cssFiles[$k]); } } $htmlEditorConfig->setOption('content_css', implode(',', $cssFiles)); } // Using uncompressed files as they'll be processed by JSMin in the Requirements class. // Not as effective as other compressors or pre-compressed+finetuned files, // but overall the unified minification into a single file brings more performance benefits // than a couple of saved bytes (after gzip) in individual files. // We also re-compress already compressed files through JSMin as this causes weird runtime bugs. Requirements::combine_files('lib.js', array(THIRDPARTY_DIR . '/jquery/jquery.js', FRAMEWORK_DIR . '/javascript/jquery-ondemand/jquery.ondemand.js', FRAMEWORK_ADMIN_DIR . '/javascript/lib.js', THIRDPARTY_DIR . '/jquery-ui/jquery-ui.js', THIRDPARTY_DIR . '/json-js/json2.js', THIRDPARTY_DIR . '/jquery-entwine/dist/jquery.entwine-dist.js', THIRDPARTY_DIR . '/jquery-cookie/jquery.cookie.js', THIRDPARTY_DIR . '/jquery-query/jquery.query.js', THIRDPARTY_DIR . '/jquery-form/jquery.form.js', FRAMEWORK_ADMIN_DIR . '/thirdparty/jquery-notice/jquery.notice.js', FRAMEWORK_ADMIN_DIR . '/thirdparty/jsizes/lib/jquery.sizes.js', FRAMEWORK_ADMIN_DIR . '/thirdparty/jlayout/lib/jlayout.border.js', FRAMEWORK_ADMIN_DIR . '/thirdparty/jlayout/lib/jquery.jlayout.js', FRAMEWORK_ADMIN_DIR . '/thirdparty/history-js/scripts/uncompressed/history.js', FRAMEWORK_ADMIN_DIR . '/thirdparty/history-js/scripts/uncompressed/history.adapter.jquery.js', FRAMEWORK_ADMIN_DIR . '/thirdparty/history-js/scripts/uncompressed/history.html4.js', THIRDPARTY_DIR . '/jstree/jquery.jstree.js', FRAMEWORK_ADMIN_DIR . '/thirdparty/chosen/chosen/chosen.jquery.js', FRAMEWORK_ADMIN_DIR . '/thirdparty/jquery-hoverIntent/jquery.hoverIntent.js', FRAMEWORK_ADMIN_DIR . '/javascript/jquery-changetracker/lib/jquery.changetracker.js', FRAMEWORK_DIR . '/javascript/TreeDropdownField.js', FRAMEWORK_DIR . '/javascript/DateField.js', FRAMEWORK_DIR . '/javascript/HtmlEditorField.js', FRAMEWORK_DIR . '/javascript/TabSet.js', FRAMEWORK_DIR . '/javascript/i18n.js', FRAMEWORK_ADMIN_DIR . '/javascript/ssui.core.js', FRAMEWORK_DIR . '/javascript/GridField.js')); if (Director::isDev()) { Requirements::javascript(FRAMEWORK_ADMIN_DIR . '/javascript/leaktools.js'); } HTMLEditorField::include_js(); Requirements::combine_files('leftandmain.js', array_unique(array_merge(array(FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.js', FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.Panel.js', FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.Tree.js', FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.Ping.js', FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.Content.js', FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.EditForm.js', FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.Menu.js', FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.AddForm.js', FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.Preview.js', FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.BatchActions.js', FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.FieldHelp.js', FRAMEWORK_ADMIN_DIR . '/javascript/LeftAndMain.TreeDropdownField.js'), Requirements::add_i18n_javascript(FRAMEWORK_DIR . '/javascript/lang', true, true), Requirements::add_i18n_javascript(FRAMEWORK_ADMIN_DIR . '/javascript/lang', true, true)))); // TODO Confuses jQuery.ondemand through document.write() if (Director::isDev()) { Requirements::javascript(THIRDPARTY_DIR . '/jquery-entwine/src/jquery.entwine.inspector.js'); } Requirements::css(FRAMEWORK_ADMIN_DIR . '/thirdparty/jquery-notice/jquery.notice.css'); Requirements::css(THIRDPARTY_DIR . '/jquery-ui-themes/smoothness/jquery-ui.css'); Requirements::css(FRAMEWORK_ADMIN_DIR . '/thirdparty/chosen/chosen/chosen.css'); Requirements::css(THIRDPARTY_DIR . '/jstree/themes/apple/style.css'); Requirements::css(FRAMEWORK_DIR . '/css/TreeDropdownField.css'); Requirements::css(FRAMEWORK_ADMIN_DIR . '/css/screen.css'); Requirements::css(FRAMEWORK_DIR . '/css/GridField.css'); // Browser-specific requirements $ie = isset($_SERVER['HTTP_USER_AGENT']) ? strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') : false; if ($ie) { $version = substr($_SERVER['HTTP_USER_AGENT'], $ie + 5, 3); if ($version == 7) { Requirements::css(FRAMEWORK_ADMIN_DIR . '/css/ie7.css'); } else { if ($version == 8) { Requirements::css(FRAMEWORK_ADMIN_DIR . '/css/ie8.css'); } } } // Custom requirements foreach (self::$extra_requirements['javascript'] as $file) { Requirements::javascript($file[0]); } foreach (self::$extra_requirements['css'] as $file) { Requirements::css($file[0], $file[1]); } foreach (self::$extra_requirements['themedcss'] as $file) { Requirements::themedCSS($file[0], $file[1]); } $dummy = null; $this->extend('init', $dummy); // The user's theme shouldn't affect the CMS, if, for example, they have replaced // TableListField.ss or Form.ss. SSViewer::set_theme(null); }
function setUp() { // Mark test as being run $this->originalIsRunningTest = self::$is_running_test; self::$is_running_test = true; // i18n needs to be set to the defaults or tests fail i18n::set_locale(i18n::default_locale()); i18n::set_date_format(null); i18n::set_time_format(null); // Remove password validation $this->originalMemberPasswordValidator = Member::password_validator(); $this->originalRequirements = Requirements::backend(); Member::set_password_validator(null); Cookie::set_report_errors(false); RootURLController::reset(); Translatable::reset(); Versioned::reset(); DataObject::reset(); SiteTree::reset(); Hierarchy::reset(); if (Controller::has_curr()) { Controller::curr()->setSession(new Session(array())); } $this->originalTheme = SSViewer::current_theme(); // Save nested_urls state, so we can restore it later $this->originalNestedURLsState = SiteTree::nested_urls(); $className = get_class($this); $fixtureFile = eval("return {$className}::\$fixture_file;"); $prefix = defined('SS_DATABASE_PREFIX') ? SS_DATABASE_PREFIX : 'ss_'; // Set up fixture if ($fixtureFile || $this->usesDatabase || !self::using_temp_db()) { if (substr(DB::getConn()->currentDatabase(), 0, strlen($prefix) + 5) != strtolower(sprintf('%stmpdb', $prefix))) { //echo "Re-creating temp database... "; self::create_temp_db(); //echo "done.\n"; } singleton('DataObject')->flushCache(); self::empty_temp_db(); foreach ($this->requireDefaultRecordsFrom as $className) { $instance = singleton($className); if (method_exists($instance, 'requireDefaultRecords')) { $instance->requireDefaultRecords(); } if (method_exists($instance, 'augmentDefaultRecords')) { $instance->augmentDefaultRecords(); } } if ($fixtureFile) { $fixtureFiles = is_array($fixtureFile) ? $fixtureFile : array($fixtureFile); $i = 0; foreach ($fixtureFiles as $fixtureFilePath) { $fixture = new YamlFixture($fixtureFilePath); $fixture->saveIntoDatabase(); $this->fixtures[] = $fixture; // backwards compatibility: Load first fixture into $this->fixture if ($i == 0) { $this->fixture = $fixture; } $i++; } } $this->logInWithPermission("ADMIN"); } // Set up email $this->originalMailer = Email::mailer(); $this->mailer = new TestMailer(); Email::set_mailer($this->mailer); Email::send_all_emails_to(null); // Preserve memory settings $this->originalMemoryLimit = ini_get('memory_limit'); }
/** * @uses LeftAndMainDecorator->init() * @uses LeftAndMainDecorator->accessedCMS() * @uses CMSMenu */ function init() { parent::init(); SSViewer::setOption('rewriteHashlinks', false); // set language $member = Member::currentUser(); if (!empty($member->Locale)) { i18n::set_locale($member->Locale); } if (!empty($member->DateFormat)) { i18n::set_date_format($member->DateFormat); } if (!empty($member->TimeFormat)) { i18n::set_time_format($member->TimeFormat); } // can't be done in cms/_config.php as locale is not set yet CMSMenu::add_link('Help', _t('LeftAndMain.HELP', 'Help', PR_HIGH, 'Menu title'), self::$help_link); // set reading lang if (Object::has_extension('SiteTree', 'Translatable') && !$this->isAjax()) { Translatable::choose_site_locale(array_keys(Translatable::get_existing_content_languages('SiteTree'))); } // Allow customisation of the access check by a decorator // Also all the canView() check to execute Director::redirect() if (!$this->canView() && !$this->response->isFinished()) { // When access /admin/, we should try a redirect to another part of the admin rather than be locked out $menu = $this->MainMenu(); foreach ($menu as $candidate) { if ($candidate->Link && $candidate->Link != $this->Link() && $candidate->MenuItem->controller && singleton($candidate->MenuItem->controller)->canView()) { return Director::redirect($candidate->Link); } } if (Member::currentUser()) { Session::set("BackURL", null); } // if no alternate menu items have matched, return a permission error $messageSet = array('default' => _t('LeftAndMain.PERMDEFAULT', "Please choose an authentication method and enter your credentials to access the CMS."), 'alreadyLoggedIn' => _t('LeftAndMain.PERMALREADY', "I'm sorry, but you can't access that part of the CMS. If you want to log in as someone else, do so below"), 'logInAgain' => _t('LeftAndMain.PERMAGAIN', "You have been logged out of the CMS. If you would like to log in again, enter a username and password below.")); return Security::permissionFailure($this, $messageSet); } // Don't continue if there's already been a redirection request. if (Director::redirected_to()) { return; } // Audit logging hook if (empty($_REQUEST['executeForm']) && !$this->isAjax()) { $this->extend('accessedCMS'); } // Set the members html editor config HtmlEditorConfig::set_active(Member::currentUser()->getHtmlEditorConfigForCMS()); // Set default values in the config if missing. These things can't be defined in the config // file because insufficient information exists when that is being processed $htmlEditorConfig = HtmlEditorConfig::get_active(); $htmlEditorConfig->setOption('language', i18n::get_tinymce_lang()); if (!$htmlEditorConfig->getOption('content_css')) { $cssFiles = 'cms/css/editor.css'; // Use theme from the site config if (($config = SiteConfig::current_site_config()) && $config->Theme) { $theme = $config->Theme; } elseif (SSViewer::current_theme()) { $theme = SSViewer::current_theme(); } else { $theme = false; } if ($theme) { $cssFiles .= ',' . THEMES_DIR . "/{$theme}/css/editor.css"; } else { if (project()) { $cssFiles .= ',' . project() . '/css/editor.css'; } } $htmlEditorConfig->setOption('content_css', $cssFiles); } Requirements::css(CMS_DIR . '/css/typography.css'); Requirements::css(CMS_DIR . '/css/layout.css'); Requirements::css(CMS_DIR . '/css/cms_left.css'); Requirements::css(CMS_DIR . '/css/cms_right.css'); Requirements::css(SAPPHIRE_DIR . '/css/Form.css'); if (isset($_REQUEST['debug_firebug'])) { // Firebug is a useful console for debugging javascript // Its available as a Firefox extension or a javascript library // for easy inclusion in other browsers (just append ?debug_firebug=1 to the URL) Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/firebug-lite/firebug.js'); } else { // By default, we include fake-objects for all firebug calls // to avoid javascript errors when referencing console.log() etc in javascript code Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/firebug-lite/firebugx.js'); } Requirements::javascript(SAPPHIRE_DIR . '/javascript/prototypefix/intro.js'); Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/prototype/prototype.js'); Requirements::javascript(SAPPHIRE_DIR . '/javascript/prototypefix/outro.js'); Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery/jquery.js'); Requirements::javascript(SAPPHIRE_DIR . '/javascript/jquery_improvements.js'); Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-ui/jquery-ui.js'); //import all of jquery ui Requirements::javascript(CMS_DIR . '/thirdparty/jquery-layout/jquery.layout.js'); Requirements::javascript(CMS_DIR . '/thirdparty/jquery-layout/jquery.layout.state.js'); Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/json-js/json2.js'); Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-metadata/jquery.metadata.js'); Requirements::javascript(CMS_DIR . '/javascript/jquery-fitheighttoparent/jquery.fitheighttoparent.js'); Requirements::javascript(CMS_DIR . '/javascript/ssui.core.js'); // @todo Load separately so the CSS files can be inlined Requirements::css(SAPPHIRE_DIR . '/thirdparty/jquery-ui-themes/smoothness/jquery.ui.all.css'); // entwine Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-entwine/dist/jquery.entwine-dist.js'); // Required for TreeTools panel above tree Requirements::javascript(SAPPHIRE_DIR . '/javascript/TabSet.js'); Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/behaviour/behaviour.js'); Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-cookie/jquery.cookie.js'); Requirements::javascript(CMS_DIR . '/thirdparty/jquery-notice/jquery.notice.js'); Requirements::javascript(SAPPHIRE_DIR . '/javascript/jquery-ondemand/jquery.ondemand.js'); Requirements::javascript(CMS_DIR . '/javascript/jquery-changetracker/lib/jquery.changetracker.js'); Requirements::add_i18n_javascript(SAPPHIRE_DIR . '/javascript/lang'); Requirements::add_i18n_javascript(CMS_DIR . '/javascript/lang'); Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/scriptaculous/effects.js'); Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/scriptaculous/dragdrop.js'); Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/scriptaculous/controls.js'); Requirements::javascript(THIRDPARTY_DIR . '/tree/tree.js'); Requirements::css(THIRDPARTY_DIR . '/tree/tree.css'); Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.js'); Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.Tree.js'); Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.EditForm.js'); Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.AddForm.js'); Requirements::javascript(CMS_DIR . '/javascript/LeftAndMain.BatchActions.js'); // navigator Requirements::css(SAPPHIRE_DIR . '/css/SilverStripeNavigator.css'); Requirements::javascript(SAPPHIRE_DIR . '/javascript/SilverStripeNavigator.js'); Requirements::themedCSS('typography'); foreach (self::$extra_requirements['javascript'] as $file) { Requirements::javascript($file[0]); } foreach (self::$extra_requirements['css'] as $file) { Requirements::css($file[0], $file[1]); } foreach (self::$extra_requirements['themedcss'] as $file) { Requirements::themedCSS($file[0], $file[1]); } Requirements::css(CMS_DIR . '/css/unjquery.css'); // Javascript combined files Requirements::combine_files('base.js', array('sapphire/thirdparty/prototype/prototype.js', 'sapphire/thirdparty/behaviour/behaviour.js', 'sapphire/thirdparty/jquery/jquery.js', 'sapphire/thirdparty/jquery-livequery/jquery.livequery.js', 'sapphire/javascript/jquery-ondemand/jquery.ondemand.js', 'sapphire/thirdparty/jquery-ui/jquery-ui.js', 'sapphire/thirdparty/firebug-lite/firebug.js', 'sapphire/thirdparty/firebug-lite/firebugx.js', 'sapphire/javascript/i18n.js')); Requirements::combine_files('leftandmain.js', array('sapphire/thirdparty/scriptaculous/effects.js', 'sapphire/thirdparty/scriptaculous/dragdrop.js', 'sapphire/thirdparty/scriptaculous/controls.js', 'cms/javascript/LeftAndMain.js', 'sapphire/javascript/tree/tree.js', 'sapphire/javascript/TreeSelectorField.js', 'cms/javascript/ThumbnailStripField.js')); $dummy = null; $this->extend('init', $dummy); // The user's theme shouldn't affect the CMS, if, for example, they have replaced // TableListField.ss or Form.ss. SSViewer::set_theme(null); }
/** * @param string $theme */ static function set_theme($theme) { self::$current_theme = $theme; }
/** * Register the given "themeable stylesheet" as required. * Themeable stylesheets have globally unique names, just like templates and PHP files. * Because of this, they can be replaced by similarly named CSS files in the theme directory. * * @param $name String The identifier of the file. For example, css/MyFile.css would have the identifier "MyFile" * @param $media String Comma-separated list of media-types (e.g. "screen,projector") */ static function themedCSS($name, $media = null) { global $_CSS_MANIFEST; $theme = SSViewer::current_theme(); if ($theme && isset($_CSS_MANIFEST[$name]) && isset($_CSS_MANIFEST[$name]['themes']) && isset($_CSS_MANIFEST[$name]['themes'][$theme])) { Requirements::css($_CSS_MANIFEST[$name]['themes'][$theme], $media); } else { if (isset($_CSS_MANIFEST[$name]) && isset($_CSS_MANIFEST[$name]['unthemed'])) { Requirements::css($_CSS_MANIFEST[$name]['unthemed'], $media); } } // Normal requirements fails quietly when there is no css - we should do the same // else user_error("themedCSS - No CSS file '$name.css' found.", E_USER_WARNING); }
/** * Given a file name (a php class name, without the .php ext, or a template name, including the .ss extension) * this helper function determines the module where this file is located * * @param string $name php class name or template file name (including *.ss extension) * @return string Module where the file is located */ public static function get_owner_module($name) { // if $name is a template file if(substr($name,-3) == '.ss') { global $_TEMPLATE_MANIFEST; $templateManifest = $_TEMPLATE_MANIFEST[substr($name,0,-3)]; if(is_array($templateManifest) && isset($templateManifest['themes'])) { $absolutePath = $templateManifest['themes'][SSViewer::current_theme()]; } else { $absolutePath = $templateManifest; } $path = str_replace('\\','/',Director::makeRelative(current($absolutePath))); ereg('/([^/]+)/',$path,$module); } // $name is assumed to be a PHP class else { global $_CLASS_MANIFEST; if(strpos($name,'_') !== false) $name = strtok($name,'_'); if(isset($_CLASS_MANIFEST[$name])) { $path = str_replace('\\','/',Director::makeRelative($_CLASS_MANIFEST[$name])); ereg('/([^/]+)/', $path, $module); } } return (isset($module)) ? $module[1] : false; }
/** * 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)); } } }
/** * Return the url of the avatar or gravatar of the selected user. * Checks to see if the current user has an avatar, if they do use it * otherwise query gravatar.com * * @return String */ function getFormattedAvatar() { $default = "forum/images/forummember_holder.gif"; if (file_exists('themes/' . SSViewer::current_theme() . '_forum/images/forummember_holder.gif')) { $default = 'themes/' . SSViewer::current_theme() . '_forum/images/forummember_holder.gif'; } // if they have uploaded an image if ($this->owner->AvatarID) { $avatar = DataObject::get_by_id("Image", $this->owner->AvatarID); if (!$avatar) { return $default; } $resizedAvatar = $avatar->SetWidth(80); if (!$resizedAvatar) { return $default; } return $resizedAvatar->URL; } if ($holder = DataObject::get_one("ForumHolder", "\"AllowGravatars\" = 1")) { // ok. no image but can we find a gravatar. Will return the default image as defined above if not. return "http://www.gravatar.com/avatar/" . md5($this->owner->Email) . "?default=" . urlencode($default) . "&size=80"; } return $default; }
/** * @param string $theme The "base theme" name (without underscores). */ public static function set_theme($theme) { self::$current_theme = $theme; //Static publishing needs to have a theme set, otherwise it defaults to the content controller theme if (!is_null($theme)) { self::$current_custom_theme = $theme; } }
/** * Tests for {@link SSViewer::current_theme()} for different behaviour * of user defined themes via {@link SiteConfig} and default theme * when no user themes are defined. */ public function testCurrentTheme() { //TODO: SiteConfig moved to CMS SSViewer::set_theme('mytheme'); $this->assertEquals('mytheme', SSViewer::current_theme(), 'Current theme is the default - user has not defined one'); }