ENHANCEMENT Allow user theme selection through SiteConfig, falling back to SSViewer::set_theme() as a default if there are none selected

MINOR Unit tests for SSViewer::current_theme() and SiteConfig::getAvailableThemes()


git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/branches/2.4@98110 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Sean Harvey 2010-02-04 01:58:29 +00:00 committed by Sam Minnee
parent 19d1a64ef4
commit caff92709f
5 changed files with 91 additions and 10 deletions

View File

@ -153,7 +153,7 @@ class ManifestBuilder {
*
* @param string $baseDir Optional: Absolute path to theme directory for testing e.g. "/Users/sharvey/Sites/test24/themes"
* @param boolean $includeSubThemes If set to TRUE, sub-themes such as "blackcandy_blog" are included too
* @return array indexed array of theme directories
* @return array Listing of theme directories
*/
public static function get_themes($baseDir = null, $includeSubThemes = false) {
// If no base directory specified, the default is the project root
@ -168,7 +168,7 @@ class ManifestBuilder {
if(strpos($file, '_') === false) {
$include = true;
}
if($include) $themes[] = $file;
if($include) $themes[$file] = $file;
}
}
closedir($handle);

View File

@ -87,6 +87,11 @@ class SSViewer {
*/
protected static $current_theme = null;
/**
* @var string
*/
protected static $cached_theme = null;
/**
* Create a template from a string instead of a .ss file
*
@ -106,8 +111,18 @@ class SSViewer {
/**
* @return string
*/
static function current_theme() {
return self::$current_theme;
static function current_theme($cached = true) {
if($cached && self::$cached_theme) {
// First case is to return the cached user theme so we don't requery SiteConfig again
return self::$cached_theme;
} else {
// Need to refresh the cache from the SiteConfig
$theme = SiteConfig::current_site_config()->Theme;
self::$cached_theme = $theme;
}
// Fall back to the default SSViewer::set_theme() behaviour
if(!$theme) $theme = self::$current_theme;
return $theme;
}
/**
@ -141,13 +156,13 @@ class SSViewer {
else $templateFolder = null;
// Use the theme template if available
if(self::$current_theme && isset($_TEMPLATE_MANIFEST[$template]['themes'][self::$current_theme])) {
if(self::current_theme() && isset($_TEMPLATE_MANIFEST[$template]['themes'][self::current_theme()])) {
$this->chosenTemplates = array_merge(
$_TEMPLATE_MANIFEST[$template]['themes'][self::$current_theme],
$_TEMPLATE_MANIFEST[$template]['themes'][self::current_theme()],
$this->chosenTemplates
);
if(isset($_GET['debug_request'])) Debug::message("Found template '$template' from main theme '" . self::$current_theme . "': " . var_export($_TEMPLATE_MANIFEST[$template]['themes'][self::$current_theme], true));
if(isset($_GET['debug_request'])) Debug::message("Found template '$template' from main theme '" . self::current_theme() . "': " . var_export($_TEMPLATE_MANIFEST[$template]['themes'][self::current_theme()], true));
}
// Fall back to unthemed base templates
@ -257,8 +272,8 @@ class SSViewer {
*/
public static function getTemplateFileByType($identifier, $type) {
global $_TEMPLATE_MANIFEST;
if(self::$current_theme && isset($_TEMPLATE_MANIFEST[$identifier]['themes'][self::$current_theme][$type])) {
return $_TEMPLATE_MANIFEST[$identifier]['themes'][self::$current_theme][$type];
if(self::current_theme() && isset($_TEMPLATE_MANIFEST[$identifier]['themes'][self::current_theme()][$type])) {
return $_TEMPLATE_MANIFEST[$identifier]['themes'][self::current_theme()][$type];
} else if(isset($_TEMPLATE_MANIFEST[$identifier][$type])){
return $_TEMPLATE_MANIFEST[$identifier][$type];
} else {

View File

@ -17,6 +17,7 @@ class SiteConfig extends DataObject {
static $db = array(
"Title" => "Varchar(255)",
"Tagline" => "Varchar(255)",
"Theme" => "Varchar(255)",
"CanViewType" => "Enum('Anyone, LoggedInUsers, OnlyTheseUsers', 'Anyone')",
"CanEditType" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')",
"CanCreateTopLevelType" => "Enum('LoggedInUsers, OnlyTheseUsers', 'LoggedInUsers')",
@ -28,6 +29,12 @@ class SiteConfig extends DataObject {
"CreateTopLevelGroups" => "Group"
);
protected static $disabled_themes = array();
public static function disable_theme($theme) {
self::$disabled_themes[$theme] = $theme;
}
/**
* Get the fields that are sent to the CMS. In
* your decorators: updateEditFormFields(&$fields)
@ -39,7 +46,8 @@ class SiteConfig extends DataObject {
new TabSet("Root",
new Tab('Main',
$titleField = new TextField("Title", _t('SiteConfig.SITETITLE', "Site title")),
$taglineField = new TextField("Tagline", _t('SiteConfig.SITETAGLINE', "Site Tagline/Slogan"))
$taglineField = new TextField("Tagline", _t('SiteConfig.SITETAGLINE', "Site Tagline/Slogan")),
new DropdownField("Theme", _t('SiteConfig.THEME', 'Theme'), $this->getAvailableThemes(), '', null, _t('SiteConfig.DEFAULTTHEME', '(Use default theme)'))
),
new Tab('Access',
new HeaderField('WhoCanViewHeader', _t('SiteConfig.VIEWHEADER', "Who can view pages on this site?"), 2),
@ -89,6 +97,19 @@ class SiteConfig extends DataObject {
$this->extend('updateEditFormFields', $fields);
return $fields;
}
/**
* Get all available themes that haven't been marked as disabled.
* @param string $baseDir Optional alternative theme base directory for testing
* @return array of theme directory names
*/
public function getAvailableThemes($baseDir = null) {
$themes = ManifestBuilder::get_themes($baseDir);
foreach(self::$disabled_themes as $theme) {
if(isset($themes[$theme])) unset($themes[$theme]);
}
return $themes;
}
/**
* Get the actions that are sent to the CMS. In

View File

@ -1,6 +1,30 @@
<?php
class SSViewerTest extends SapphireTest {
/**
* 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();
$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();
}
/**
* Test that a template without a <head> tag still renders.
*/

View File

@ -53,6 +53,27 @@ class SiteConfigTest extends SapphireTest {
$this->assertFalse($pageEn->canEdit($translatorDe));
$this->assertTrue($pageEn->canEdit($translatorEn));
}
function testAvailableThemes() {
$config = SiteConfig::current_site_config();
$ds = DIRECTORY_SEPARATOR;
$testThemeBaseDir = TEMP_FOLDER . $ds . 'test-themes';
if(file_exists($testThemeBaseDir)) Filesystem::removeFolder($testThemeBaseDir);
mkdir($testThemeBaseDir);
mkdir($testThemeBaseDir . $ds . 'blackcandy');
mkdir($testThemeBaseDir . $ds . 'blackcandy_blog');
mkdir($testThemeBaseDir . $ds . 'darkshades');
mkdir($testThemeBaseDir . $ds . 'darkshades_blog');
$themes = $config->getAvailableThemes($testThemeBaseDir);
$this->assertContains('blackcandy', $themes, 'Test themes contain blackcandy theme');
$this->assertContains('darkshades', $themes, 'Test themes contain darkshades theme');
SiteConfig::disable_theme('darkshades');
$themes = $config->getAvailableThemes($testThemeBaseDir);
$this->assertFalse(in_array('darkshades', $themes), 'Darkshades was disabled - it is no longer available');
}
}
?>