"0xffffff",
"docBg1" => "0xffffff",
"docBg2" => "0xffffff",
"xText" => "0x33485c",
"yText" => "0x33485c",
"title" => "0x333333",
"misc" => "0x999999",
"altBorder" => "0xffffff",
"altBg" => "0xffffff",
"altText" => "0x666666",
"graphBorder" => "0xcccccc",
"graphBg1" => "0xf6f6f6",
"graphBg2" => "0xf6f6f6",
"graphLines" => "0xcccccc",
"graphText" => "0x333333",
"graphTextShadow" => "0xf9f9f9",
"barBorder" => "0xeeeeee",
"barBorderHilite" => "0x333333",
"legendBorder" => "0xffffff",
"legendBg1" => "0xffffff",
"legendBg2" => "0xffffff",
"legendText" => "0x444444",
"legendColorKeyBorder" => "0x777777",
"scrollBar" => "0xcccccc",
"scrollBarBorder" => "0xeeeeee",
"scrollBarTrack" => "0xeeeeee",
"scrollBarTrackBorder" => "0xcccccc",
);
/**
* Colors used in pie charts
*
* @var array
*/
protected $pieChartColors = array(
"docBorder" => "0xffffff",
"docBg1" => "0xffffff",
"docBg2" => "0xffffff",
"title" => "0x333333",
"subtitle" => "0x666666",
"misc" => "0x999999",
"altBorder" => "0xffffff",
"altBg" => "0xffffff",
"altText" => "0x666666",
"graphText" => "0x33485c",
"graphTextShadow" => "0xf9f9f9",
"pieBorder" => "0xffffff",
"pieBorderHilite" => "0x333333",
"legendBorder" => "0xffffff",
"legendBg1" => "0xffffff",
"legendBg2" => "0xffffff",
"legendText" => "0x444444",
"legendColorKeyBorder" => "0x777777",
"scrollBar" => "0xdfdfdf",
"scrollBarBorder" => "0xfafafa",
"scrollBarTrack" => "0xeeeeee",
"scrollBarTrackBorder" => "0xcccccc",
);
/**
* Does this theme support group tabs
*
* @var bool
*/
protected $group_tabs;
/**
* Cache built of all css files locations
*
* @var array
*/
private $_cssCache = array();
/**
* Cache built of all image files locations
*
* @var array
*/
private $_imageCache = array();
/**
* Cache built of all javascript files locations
*
* @var array
*/
private $_jsCache = array();
/**
* Cache built of all template files locations
*
* @var array
*/
private $_templateCache = array();
/**
* Size of the caches after the are initialized in the constructor
*
* @var array
*/
private $_initialCacheSize = array(
'cssCache' => 0,
'imageCache' => 0,
'jsCache' => 0,
'templateCache' => 0,
);
/**
* Controls whether or not to clear the cache on destroy; defaults to false
*/
private $_clearCacheOnDestroy = false;
private $imageExtensions = array(
'gif',
'png',
'jpg',
'tif',
'bmp',
);
/**
* Constructor
*
* Sets the theme properties from the defaults passed to it, and loads the file path cache from an external cache
*
* @param $defaults string defaults for the current theme
*/
public function __construct(
$defaults
)
{
// apply parent theme's properties first
if ( isset($defaults['parentTheme']) ) {
$themedef = array();
include("themes/{$defaults['parentTheme']}/themedef.php");
foreach ( $themedef as $key => $value ) {
if ( property_exists(__CLASS__,$key) ) {
// For all arrays ( except colors and fonts ) you can just specify the items
// to change instead of all of the values
if ( is_array($this->$key) && !in_array($key,array('colors','fonts')) )
$this->$key = array_merge($this->$key,$value);
else
$this->$key = $value;
}
}
}
foreach ( $defaults as $key => $value ) {
if ( property_exists(__CLASS__,$key) ) {
// For all arrays ( except colors and fonts ) you can just specify the items
// to change instead of all of the values
if ( is_array($this->$key) && !in_array($key,array('colors','fonts')) )
$this->$key = array_merge($this->$key,$value);
else
$this->$key = $value;
}
}
if ( !inDeveloperMode() ) {
if ( sugar_is_file($GLOBALS['sugar_config']['cache_dir'].$this->getFilePath().'/pathCache.php') ) {
$caches = unserialize(sugar_file_get_contents($GLOBALS['sugar_config']['cache_dir'].$this->getFilePath().'/pathCache.php'));
if ( isset($caches['jsCache']) )
$this->_jsCache = $caches['jsCache'];
if ( isset($caches['cssCache']) )
$this->_cssCache = $caches['cssCache'];
if ( isset($caches['imageCache']) )
$this->_imageCache = $caches['imageCache'];
if ( isset($caches['templateCache']) )
$this->_templateCache = $caches['templateCache'];
}
}
$this->_initialCacheSize = array(
'jsCache' => count($this->_jsCache),
'cssCache' => count($this->_cssCache),
'imageCache' => count($this->_imageCache),
'templateCache' => count($this->_templateCache),
);
}
/**
* Destructor
* Here we'll write out the internal file path caches to an external cache of some sort.
*/
public function __destruct()
{
// Bug 28309 - Set the current directory to one which we expect it to be (i.e. the root directory of the install
set_include_path(realpath(dirname(__FILE__) . '/../..') . PATH_SEPARATOR . get_include_path());
chdir(realpath(dirname(__FILE__) . '/../..'));
// clear out the cache on destroy if we are asked to
if ( $this->_clearCacheOnDestroy ) {
if (is_file($GLOBALS['sugar_config']['cache_dir'].$this->getFilePath().'/pathCache.php'))
unlink($GLOBALS['sugar_config']['cache_dir'].$this->getFilePath().'/pathCache.php');
}
elseif ( !inDeveloperMode() ) {
// only update the caches if they have been changed in this request
if ( count($this->_jsCache) != $this->_initialCacheSize['jsCache']
|| count($this->_cssCache) != $this->_initialCacheSize['cssCache']
|| count($this->_imageCache) != $this->_initialCacheSize['imageCache']
|| count($this->_templateCache) != $this->_initialCacheSize['templateCache']
) {
sugar_file_put_contents(
create_cache_directory($this->getFilePath().'/pathCache.php'),
serialize(
array(
'jsCache' => $this->_jsCache,
'cssCache' => $this->_cssCache,
'imageCache' => $this->_imageCache,
'templateCache' => $this->_templateCache,
)
)
);
}
}
}
/**
* Specifies what is returned when the object is cast to a string, in this case it will be the
* theme directory name.
*
* @return string theme directory name
*/
public function __toString()
{
return $this->dirName;
}
/**
* Generic public accessor method for all the properties of the theme ( which are kept protected )
*
* @return string
*/
public function __get(
$key
)
{
if ( isset($this->$key) )
return $this->$key;
}
public function __isset($key){
return isset($this->$key);
}
/**
* Clears out the caches used for this themes
*/
public function clearCache()
{
$this->_clearCacheOnDestroy = true;
}
/**
* Return array of all valid fields that can be specified in the themedef.php file
*
* @return array
*/
public static function getThemeDefFields()
{
return array(
'name',
'description',
'directionality',
'dirName',
'parentTheme',
'version',
'colors',
'fonts',
'barChartColors',
'pieChartColors',
'group_tabs',
'ignoreParentFiles',
);
}
/**
* Returns the file path of the current theme
*
* @return string
*/
public function getFilePath()
{
return 'themes/'.$this->dirName;
}
/**
* Returns the image path of the current theme
*
* @return string
*/
public function getImagePath()
{
return $this->getFilePath().'/images';
}
/**
* Returns the css path of the current theme
*
* @return string
*/
public function getCSSPath()
{
return $this->getFilePath().'/css';
}
/**
* Returns the javascript path of the current theme
*
* @return string
*/
public function getJSPath()
{
return $this->getFilePath().'/js';
}
/**
* Returns the tpl path of the current theme
*
* @return string
*/
public function getTemplatePath()
{
return $this->getFilePath().'/tpls';
}
/**
* Returns the file path of the theme defaults
*
* @return string
*/
public final function getDefaultFilePath()
{
return 'themes/default';
}
/**
* Returns the image path of the theme defaults
*
* @return string
*/
public final function getDefaultImagePath()
{
return $this->getDefaultFilePath().'/images';
}
/**
* Returns the css path of the theme defaults
*
* @return string
*/
public final function getDefaultCSSPath()
{
return $this->getDefaultFilePath().'/css';
}
/**
* Returns the template path of the theme defaults
*
* @return string
*/
public final function getDefaultTemplatePath()
{
return $this->getDefaultFilePath().'/tpls';
}
/**
* Returns the javascript path of the theme defaults
*
* @return string
*/
public final function getDefaultJSPath()
{
return $this->getDefaultFilePath().'/js';
}
/**
* Returns CSS for the current theme.
*
* @param $color string optional, specifies the css color file to use if the theme supports it; defaults to cookie value or theme default
* @param $font string optional, specifies the css font file to use if the theme supports it; defaults to cookie value or theme default
* @return string HTML code
*/
public function getCSS(
$color = null,
$font = null
)
{
// include style.css file
$html = '';
$html .= '';
$html .= '';
// for BC during upgrade
if ( !empty($this->colors) ) {
if ( isset($_SESSION['authenticated_user_theme_color']) && in_array($_SESSION['authenticated_user_theme_color'], $this->colors))
$color = $_SESSION['authenticated_user_theme_color'];
else
$color = $this->colors[0];
$html .= '';
}
if ( !empty($this->fonts) ) {
if ( isset($_SESSION['authenticated_user_theme_font']) && in_array($_SESSION['authenticated_user_theme_font'], $this->fonts))
$font = $_SESSION['authenticated_user_theme_font'];
else
$font = $this->fonts[0];
$html .= '';
}
return $html;
}
/**
* Returns javascript for the current theme
*
* @return string HTML code
*/
public function getJS()
{
$styleJS = $this->getJSURL('style.js');
return <<
EOHTML;
}
/**
* Returns the path for the tpl file in the current theme. If not found in the current theme, will revert
* to looking in the base theme.
*
* @param string $templateName tpl file name
* @return string path of tpl file to include
*/
public function getTemplate(
$templateName
)
{
if ( isset($this->_templateCache[$templateName]) )
return $this->_templateCache[$templateName];
$templatePath = '';
if (sugar_is_file('custom/'.$this->getTemplatePath().'/'.$templateName))
$templatePath = 'custom/'.$this->getTemplatePath().'/'.$templateName;
elseif (sugar_is_file($this->getTemplatePath().'/'.$templateName))
$templatePath = $this->getTemplatePath().'/'.$templateName;
elseif (isset($this->parentTheme)
&& SugarThemeRegistry::get($this->parentTheme) instanceOf SugarTheme
&& ($filename = SugarThemeRegistry::get($this->parentTheme)->getTemplate($templateName)) != '')
$templatePath = $filename;
elseif (sugar_is_file('custom/'.$this->getDefaultTemplatePath().'/'.$templateName))
$templatePath = 'custom/'.$this->getDefaultTemplatePath().'/'.$templateName;
elseif (sugar_is_file($this->getDefaultTemplatePath().'/'.$templateName))
$templatePath = $this->getDefaultTemplatePath().'/'.$templateName;
else {
$GLOBALS['log']->warn("Template $templateName not found");
return false;
}
$this->_imageCache[$templateName] = $templatePath;
return $templatePath;
}
/**
* Returns an image tag for the given image.
*
* @param string $image image name
* @param string $other_attributes optional, other attributes to add to the image tag, not cached
* @param string $width optional, defaults to the actual image's width
* @param string $height optional, defaults to the actual image's height
* @return string HTML image tag
*/
public function getImage(
$imageName,
$other_attributes = '',
$width = null,
$height = null,
$ext = '.gif'
)
{
static $cached_results = array();
$imageName .= $ext;
if(!empty($cached_results[$imageName]))
return $cached_results[$imageName]."$other_attributes />";
$imageURL = $this->getImageURL($imageName,false);
if ( empty($imageURL) )
return false;
$size = getimagesize($imageURL);
if ( is_null($width) )
$width = $size[0];
if ( is_null($height) )
$height = $size[1];
// Cache everything but the other attributes....
$cached_results[$imageName] = "";
}
/**
* Returns the URL for an image in the current theme. If not found in the current theme, will revert
* to looking in the base theme.
*
* @param string $imageName image file name
* @param bool $addJSPath call getJSPath() with the results to add some unique image tracking support
* @return string path to image
*/
public function getImageURL(
$imageName,
$addJSPath = true
)
{
if ( isset($this->_imageCache[$imageName]) ) {
if ( $addJSPath )
return getJSPath($this->_imageCache[$imageName]);
else
return $this->_imageCache[$imageName];
}
$imagePath = '';
if (($filename = $this->_getImageFileName('custom/'.$this->getImagePath().'/'.$imageName)) != '')
$imagePath = $filename;
elseif (($filename = $this->_getImageFileName($this->getImagePath().'/'.$imageName)) != '')
$imagePath = $filename;
elseif (isset($this->parentTheme)
&& SugarThemeRegistry::get($this->parentTheme) instanceOf SugarTheme
&& ($filename = SugarThemeRegistry::get($this->parentTheme)->getImageURL($imageName,false)) != '')
$imagePath = $filename;
elseif (($filename = $this->_getImageFileName('custom/'.$this->getDefaultImagePath().'/'.$imageName)) != '')
$imagePath = $filename;
elseif (($filename = $this->_getImageFileName($this->getDefaultImagePath().'/'.$imageName)) != '')
$imagePath = $filename;
else {
$GLOBALS['log']->warn("Image $imageName not found");
return false;
}
$this->_imageCache[$imageName] = $imagePath;
if ( $addJSPath )
return getJSPath($imagePath);
return $imagePath;
}
/**
* Checks for an image using all of the accepted image extensions
*
* @param string $imageName image file name
* @return string path to image
*/
protected function _getImageFileName(
$imageName
)
{
// return now if the extension matches that of which we are looking for
if ( sugar_is_file($imageName) )
return $imageName;
$pathParts = pathinfo($imageName);
foreach ( $this->imageExtensions as $extension )
if ( isset($pathParts['extension']) )
if ( ( $extension != $pathParts['extension'] )
&& sugar_is_file($pathParts['dirname'].'/'.$pathParts['filename'].'.'.$extension) )
return $pathParts['dirname'].'/'.$pathParts['filename'].'.'.$extension;
return '';
}
/**
* Returns the URL for the css file in the current theme. If not found in the current theme, will revert
* to looking in the base theme.
*
* @param string $cssFileName css file name
* @param bool $addJSPath call getJSPath() with the results to add some unique image tracking support
* @return string path of css file to include
*/
public function getCSSURL(
$cssFileName,
$addJSPath = true
)
{
if ( isset($this->_cssCache[$cssFileName])) {
if ( $addJSPath )
return getJSPath($this->_cssCache[$cssFileName]);
else
return $this->_cssCache[$cssFileName];
}
$cssFileContents = '';
if (isset($this->parentTheme)
&& SugarThemeRegistry::get($this->parentTheme) instanceOf SugarTheme
&& ($filename = SugarThemeRegistry::get($this->parentTheme)->getCSSURL($cssFileName,false)) != '')
$cssFileContents .= file_get_contents($filename);
else {
if (sugar_is_file($this->getDefaultCSSPath().'/'.$cssFileName))
$cssFileContents .= file_get_contents($this->getDefaultCSSPath().'/'.$cssFileName);
if (sugar_is_file('custom/'.$this->getDefaultCSSPath().'/'.$cssFileName))
$cssFileContents .= file_get_contents('custom/'.$this->getDefaultCSSPath().'/'.$cssFileName);
}
if (sugar_is_file($this->getCSSPath().'/'.$cssFileName))
$cssFileContents .= file_get_contents($this->getCSSPath().'/'.$cssFileName);
if (sugar_is_file('custom/'.$this->getCSSPath().'/'.$cssFileName))
$cssFileContents .= file_get_contents('custom/'.$this->getCSSPath().'/'.$cssFileName);
if (empty($cssFileContents)) {
$GLOBALS['log']->warn("CSS File $cssFileName not found");
return false;
}
// fix any image references that may be defined in css files
$cssFileContents = str_ireplace("entryPoint=getImage&",
"entryPoint=getImage&themeName={$this->dirName}&",
$cssFileContents);
// create the cached file location
$cssFilePath = create_cache_directory($this->getCSSPath()."/$cssFileName");
// if this is the style.css file, prepend the base.css and calendar-win2k-cold-1.css
// files before the theme styles
if ( $cssFileName == 'style.css' && !isset($this->parentTheme) ) {
if ( inDeveloperMode() )
$cssFileContents = file_get_contents('include/javascript/yui/build/base/base.css') . $cssFileContents;
else
$cssFileContents = file_get_contents('include/javascript/yui/build/base/base-min.css') . $cssFileContents;
}
// minify the css
if ( !inDeveloperMode() && !sugar_is_file($cssFilePath) ) {
$cssFileContents = cssmin::minify($cssFileContents);
}
// now write the css to cache
sugar_file_put_contents($cssFilePath,$cssFileContents);
$this->_cssCache[$cssFileName] = $cssFilePath;
if ( $addJSPath )
return getJSPath($cssFilePath);
return $cssFilePath;
}
/**
* Returns the URL for an image in the current theme. If not found in the current theme, will revert
* to looking in the base theme.
*
* @param string $jsFileName js file name
* @param bool $addJSPath call getJSPath() with the results to add some unique image tracking support
* @return string path to js file
*/
public function getJSURL(
$jsFileName,
$addJSPath = true
)
{
if ( isset($this->_jsCache[$jsFileName])) {
if ( $addJSPath )
return getJSPath($this->_jsCache[$jsFileName]);
else
return $this->_jsCache[$jsFileName];
}
$jsFileContents = '';
if (isset($this->parentTheme)
&& SugarThemeRegistry::get($this->parentTheme) instanceOf SugarTheme
&& ($filename = SugarThemeRegistry::get($this->parentTheme)->getJSURL($jsFileName,false)) != '' && !in_array($jsFileName,$this->ignoreParentFiles))
$jsFileContents .= file_get_contents($filename);
else {
if (sugar_is_file($this->getDefaultJSPath().'/'.$jsFileName))
$jsFileContents .= file_get_contents($this->getDefaultJSPath().'/'.$jsFileName);
if (sugar_is_file('custom/'.$this->getDefaultJSPath().'/'.$jsFileName))
$jsFileContents .= file_get_contents('custom/'.$this->getDefaultJSPath().'/'.$jsFileName);
}
if (sugar_is_file($this->getJSPath().'/'.$jsFileName))
$jsFileContents .= file_get_contents($this->getJSPath().'/'.$jsFileName);
if (sugar_is_file('custom/'.$this->getJSPath().'/'.$jsFileName))
$jsFileContents .= file_get_contents('custom/'.$this->getJSPath().'/'.$jsFileName);
if (empty($jsFileContents)) {
$GLOBALS['log']->warn("Javascript File $jsFileName not found");
return false;
}
// create the cached file location
$jsFilePath = create_cache_directory($this->getJSPath()."/$jsFileName");
// minify the js
if ( !inDeveloperMode()&& !sugar_is_file(str_replace('.js','-min.js',$jsFilePath)) ) {
$jsFileContents = JSMin::minify($jsFileContents);
$jsFilePath = str_replace('.js','-min.js',$jsFilePath);
}
// now write the js to cache
sugar_file_put_contents($jsFilePath,$jsFileContents);
$this->_jsCache[$jsFileName] = $jsFilePath;
if ( $addJSPath )
return getJSPath($jsFilePath);
return $jsFilePath;
}
/**
* Returns an array of all of the images available for the current theme
*
* @return array
*/
public function getAllImages()
{
// first, lets get all the paths of where to look
$pathsToSearch = array($this->getImagePath());
$theme = $this;
while (isset($theme->parentTheme) && SugarThemeRegistry::get($theme->parentTheme) instanceOf SugarTheme ) {
$theme = SugarThemeRegistry::get($theme->parentTheme);
$pathsToSearch[] = $theme->getImagePath();
}
$pathsToSearch[] = $this->getDefaultImagePath();
// now build the array
$imageArray = array();
foreach ( $pathsToSearch as $path )
{
if (!sugar_is_dir($path)) $path = "custom/$path";
if (sugar_is_dir($path) && is_readable($path) && $dir = opendir($path)) {
while (($file = readdir($dir)) !== false) {
if ($file == ".."
|| $file == "."
|| $file == ".svn"
|| $file == "CVS"
|| $file == "Attic"
)
continue;
if ( !isset($imageArray[$file]) )
$imageArray[$file] = $this->getImageURL($file,false);
}
closedir($dir);
}
}
ksort($imageArray);
return $imageArray;
}
}
/**
* Registry for all the current classes in the system
*/
class SugarThemeRegistry
{
/**
* Array of all themes and thier object
*
* @var array
*/
private static $_themes = array();
/**
* Name of the current theme; corresponds to an index key in SugarThemeRegistry::$_themes
*
* @var string
*/
private static $_currentTheme;
/**
* Disable the constructor since this will be a singleton
*/
private function __construct() {}
/**
* Adds a new theme to the registry
*
* @param $themedef array
*/
public static function add(
array $themedef
)
{
// make sure the we know the sugar version
if ( !isset($GLOBALS['sugar_version']) ) {
include('sugar_version.php');
$GLOBALS['sugar_version'] = $sugar_version;
}
// Assume theme is designed for 5.5.x if not specified otherwise
if ( !isset($themedef['version']) )
$themedef['version']['regex_matches'] = array('5\.5\.*');
// Check to see if theme is valid for this version of Sugar; return false if not
$version_ok = false;
if( isset($themedef['version']['exact_matches']) ){
$matches_empty = false;
foreach( $themedef['version']['exact_matches'] as $match ){
if( $match == $GLOBALS['sugar_version'] ){
$version_ok = true;
}
}
}
if( !$version_ok && isset($themedef['version']['regex_matches']) ){
$matches_empty = false;
foreach( $themedef['version']['regex_matches'] as $match ){
if( preg_match( "/$match/", $GLOBALS['sugar_version'] ) ){
$version_ok = true;
}
}
}
if ( !$version_ok )
return false;
$theme = new SugarTheme($themedef);
self::$_themes[$theme->dirName] = $theme;
}
/**
* Removes a new theme from the registry
*
* @param $themeName string
*/
public static function remove(
$themeName
)
{
if ( self::exists($themeName) )
unset(self::$_themes[$themeName]);
}
/**
* Returns a theme object in the registry specified by the given $themeName
*
* @param $themeName string
*/
public static function get(
$themeName
)
{
if ( isset(self::$_themes[$themeName]) )
return self::$_themes[$themeName];
}
/**
* Returns the current theme object
*
* @return SugarTheme object
*/
public static function current()
{
if ( !isset(self::$_currentTheme) )
self::buildRegistry();
return self::$_themes[self::$_currentTheme];
}
/**
* Returns the default theme object
*
* @return SugarTheme object
*/
public static function getDefault()
{
if ( !isset(self::$_currentTheme) )
self::buildRegistry();
if ( isset($GLOBALS['sugar_config']['default_theme']) && self::exists($GLOBALS['sugar_config']['default_theme']) ) {
return self::get($GLOBALS['sugar_config']['default_theme']);
}
return self::get(array_pop(array_keys(self::availableThemes())));
}
/**
* Returns true if a theme object specified by the given $themeName exists in the registry
*
* @param $themeName string
* @return bool
*/
public static function exists(
$themeName
)
{
return (self::get($themeName) !== null);
}
/**
* Sets the given $themeName to be the current theme
*
* @param $themeName string
*/
public static function set(
$themeName
)
{
if ( !self::exists($themeName) )
return false;
self::$_currentTheme = $themeName;
// set some of the expected globals
$GLOBALS['barChartColors'] = self::current()->barChartColors;
$GLOBALS['pieChartColors'] = self::current()->pieChartColors;
}
/**
* Builds the theme registry
*/
public static function buildRegistry()
{
self::$_themes = array();
$dirs = array("themes/","custom/themes/");
// check for a default themedef file
$themedefDefault = array();
if ( sugar_is_file("custom/themes/default/themedef.php") ) {
$themedef = array();
require("custom/themes/default/themedef.php");
$themedefDefault = $themedef;
}
foreach ($dirs as $dirPath ) {
if (sugar_is_dir('./'.$dirPath) && is_readable('./'.$dirPath) && $dir = opendir('./'.$dirPath)) {
while (($file = readdir($dir)) !== false) {
if ($file == ".."
|| $file == "."
|| $file == ".svn"
|| $file == "CVS"
|| $file == "Attic"
|| $file == "default"
|| !sugar_is_dir("./$dirPath".$file)
|| !sugar_is_file("./{$dirPath}{$file}/themedef.php")
)
continue;
$themedef = array();
require("./{$dirPath}{$file}/themedef.php");
$themedef = array_merge($themedef,$themedefDefault);
$themedef['dirName'] = $file;
// check for theme already existing in the registry
// if so, then it will override the current one
if ( self::exists($themedef['dirName']) ) {
$existingTheme = self::get($themedef['dirName']);
foreach ( SugarTheme::getThemeDefFields() as $field )
if ( !isset($themedef[$field]) )
$themedef[$field] = $existingTheme->$field;
self::remove($themedef['dirName']);
}
if ( isset($themedef['name']) ) {
self::add($themedef);
}
}
closedir($dir);
}
}
// default to setting the default theme as the current theme
if ( !isset($GLOBALS['sugar_config']['default_theme']) || !self::set($GLOBALS['sugar_config']['default_theme']) ) {
if ( count(self::availableThemes()) == 0 )
sugar_die('No valid themes are found on this instance');
else
self::set(array_pop(array_keys(self::availableThemes())));
}
}
/**
* Returns an array of available themes. Designed to be absorbed into get_select_options_with_id()
*
* @return array
*/
public static function availableThemes()
{
$themelist = array();
$disabledThemes = array();
if ( isset($GLOBALS['sugar_config']['disabled_themes']) )
$disabledThemes = explode(',',$GLOBALS['sugar_config']['disabled_themes']);
foreach ( self::$_themes as $themename => $themeobject ) {
if ( in_array($themename,$disabledThemes) )
continue;
$themelist[$themeobject->dirName] = $themeobject->name;
}
asort($themelist, SORT_STRING);
return $themelist;
}
/**
* Returns an array of un-available themes. Designed used with the theme selector in the admin panel
*
* @return array
*/
public static function unAvailableThemes()
{
$themelist = array();
$disabledThemes = array();
if ( isset($GLOBALS['sugar_config']['disabled_themes']) )
$disabledThemes = explode(',',$GLOBALS['sugar_config']['disabled_themes']);
foreach ( self::$_themes as $themename => $themeobject ) {
if ( in_array($themename,$disabledThemes) )
$themelist[$themeobject->dirName] = $themeobject->name;
}
return $themelist;
}
/**
* Returns an array of all themes found in the current installation
*
* @return array
*/
public static function allThemes()
{
$themelist = array();
foreach ( self::$_themes as $themename => $themeobject )
$themelist[$themeobject->dirName] = $themeobject->name;
return $themelist;
}
/**
* Clears out the cached path locations for all themes
*/
public static function clearAllCaches()
{
foreach ( self::$_themes as $themeobject ) {
$themeobject->clearCache();
}
}
}