1158 lines
40 KiB
PHP
1158 lines
40 KiB
PHP
|
|
<?php
|
||
|
|
if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
|
||
|
|
/*********************************************************************************
|
||
|
|
* SugarCRM is a customer relationship management program developed by
|
||
|
|
* SugarCRM, Inc. Copyright (C) 2004-2010 SugarCRM Inc.
|
||
|
|
*
|
||
|
|
* This program is free software; you can redistribute it and/or modify it under
|
||
|
|
* the terms of the GNU Affero General Public License version 3 as published by the
|
||
|
|
* Free Software Foundation with the addition of the following permission added
|
||
|
|
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
|
||
|
|
* IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
|
||
|
|
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
|
||
|
|
*
|
||
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||
|
|
* FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
|
||
|
|
* details.
|
||
|
|
*
|
||
|
|
* You should have received a copy of the GNU Affero General Public License along with
|
||
|
|
* this program; if not, see http://www.gnu.org/licenses or write to the Free
|
||
|
|
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
||
|
|
* 02110-1301 USA.
|
||
|
|
*
|
||
|
|
* You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
|
||
|
|
* SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
|
||
|
|
*
|
||
|
|
* The interactive user interfaces in modified source and object code versions
|
||
|
|
* of this program must display Appropriate Legal Notices, as required under
|
||
|
|
* Section 5 of the GNU Affero General Public License version 3.
|
||
|
|
*
|
||
|
|
* In accordance with Section 7(b) of the GNU Affero General Public License version 3,
|
||
|
|
* these Appropriate Legal Notices must retain the display of the "Powered by
|
||
|
|
* SugarCRM" logo. If the display of the logo is not reasonably feasible for
|
||
|
|
* technical reasons, the Appropriate Legal Notices must display the words
|
||
|
|
* "Powered by SugarCRM".
|
||
|
|
********************************************************************************/
|
||
|
|
|
||
|
|
/*********************************************************************************
|
||
|
|
|
||
|
|
* Description: Contains a variety of utility functions used to display UI
|
||
|
|
* components such as form headers and footers. Intended to be modified on a per
|
||
|
|
* theme basis.
|
||
|
|
********************************************************************************/
|
||
|
|
|
||
|
|
if(!defined('JSMIN_AS_LIB'))
|
||
|
|
define('JSMIN_AS_LIB', true);
|
||
|
|
|
||
|
|
require_once("include/SugarTheme/cssmin.php");
|
||
|
|
require_once("jssource/jsmin.php");
|
||
|
|
require_once('include/utils/sugar_file_utils.php');
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Class that provides tools for working with a theme.
|
||
|
|
*/
|
||
|
|
class SugarTheme
|
||
|
|
{
|
||
|
|
/**
|
||
|
|
* Theme name
|
||
|
|
*
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
protected $name;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Theme description
|
||
|
|
*
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
protected $description;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Theme directory name
|
||
|
|
*
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
protected $dirName;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Parent theme name
|
||
|
|
*
|
||
|
|
* @var string
|
||
|
|
*/
|
||
|
|
protected $parentTheme;
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Colors sets provided by the theme
|
||
|
|
*
|
||
|
|
* @deprecated only here for BC during upgrades
|
||
|
|
* @var array
|
||
|
|
*/
|
||
|
|
protected $colors = array();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Font sets provided by the theme
|
||
|
|
*
|
||
|
|
* @deprecated only here for BC during upgrades
|
||
|
|
* @var array
|
||
|
|
*/
|
||
|
|
protected $fonts = array();
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Maximum sugar version this theme is for; defaults to 5.5.1 as all the themes without this
|
||
|
|
* parameter as assumed to work thru 5.5.1
|
||
|
|
*
|
||
|
|
* @var int
|
||
|
|
*/
|
||
|
|
protected $version = '5.5.1';
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Colors used in bar charts
|
||
|
|
*
|
||
|
|
* @var array
|
||
|
|
*/
|
||
|
|
protected $barChartColors = array(
|
||
|
|
"docBorder" => "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",
|
||
|
|
);
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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() ) {
|
||
|
|
// load stored theme cache from sugar cache if it's there
|
||
|
|
if ( $GLOBALS['external_cache_enabled']
|
||
|
|
&& $GLOBALS['external_cache_type'] != 'base-in-memory' ) {
|
||
|
|
$this->_jsCache = sugar_cache_retrieve('theme_'.$this->dirName.'_jsCache');
|
||
|
|
$this->_cssCache = sugar_cache_retrieve('theme_'.$this->dirName.'_cssCache');
|
||
|
|
$this->_imageCache = sugar_cache_retrieve('theme_'.$this->dirName.'_imageCache');
|
||
|
|
$this->_templateCache = sugar_cache_retrieve('theme_'.$this->dirName.'_templateCache');
|
||
|
|
}
|
||
|
|
// otherwise, see if we serialized them to a file
|
||
|
|
elseif ( sugar_is_file($GLOBALS['sugar_config']['cache_dir'].$this->getFilePath().'/pathCache.php') ) {
|
||
|
|
$caches = unserialize(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__) . '/../..'));
|
||
|
|
|
||
|
|
// Bug 30807/30808 - Re-setup the external cache since the object isn't there when calling this method.
|
||
|
|
$GLOBALS['external_cache_checked'] = false;
|
||
|
|
check_cache();
|
||
|
|
|
||
|
|
// 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');
|
||
|
|
if ( $GLOBALS['external_cache_enabled']
|
||
|
|
&& $GLOBALS['external_cache_type'] != 'base-in-memory' ) {
|
||
|
|
sugar_cache_clear('theme_'.$this->dirName.'_jsCache');
|
||
|
|
sugar_cache_clear('theme_'.$this->dirName.'_cssCache');
|
||
|
|
sugar_cache_clear('theme_'.$this->dirName.'_imageCache');
|
||
|
|
sugar_cache_clear('theme_'.$this->dirName.'_templateCache');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
elseif ( !inDeveloperMode() ) {
|
||
|
|
// push our cache into the sugar cache
|
||
|
|
if ( $GLOBALS['external_cache_enabled']
|
||
|
|
&& $GLOBALS['external_cache_type'] != 'base-in-memory' ) {
|
||
|
|
// only update the caches if they have been changed in this request
|
||
|
|
if ( count($this->_jsCache) != $this->_initialCacheSize['jsCache'] )
|
||
|
|
sugar_cache_put('theme_'.$this->dirName.'_jsCache',$this->_jsCache);
|
||
|
|
if ( count($this->_cssCache) != $this->_initialCacheSize['cssCache'] )
|
||
|
|
sugar_cache_put('theme_'.$this->dirName.'_cssCache',$this->_cssCache);
|
||
|
|
if ( count($this->_imageCache) != $this->_initialCacheSize['imageCache'] )
|
||
|
|
sugar_cache_put('theme_'.$this->dirName.'_imageCache',$this->_imageCache);
|
||
|
|
if ( count($this->_templateCache) != $this->_initialCacheSize['templateCache'] )
|
||
|
|
sugar_cache_put('theme_'.$this->dirName.'_templateCache',$this->_templateCache);
|
||
|
|
}
|
||
|
|
// fallback in case there is no useful external caching available
|
||
|
|
// only update the caches if they have been changed in this request
|
||
|
|
elseif ( 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,
|
||
|
|
)
|
||
|
|
)
|
||
|
|
);
|
||
|
|
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// clear out the cache if we are in developerMode
|
||
|
|
// ( so it will be freshly rebuilt for the next load )
|
||
|
|
elseif ( $GLOBALS['external_cache_enabled'] ) {
|
||
|
|
sugar_cache_clear('theme_'.$this->dirName.'_jsCache');
|
||
|
|
sugar_cache_clear('theme_'.$this->dirName.'_cssCache');
|
||
|
|
sugar_cache_clear('theme_'.$this->dirName.'_imageCache');
|
||
|
|
sugar_cache_clear('theme_'.$this->dirName.'_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',
|
||
|
|
'dirName',
|
||
|
|
'parentTheme',
|
||
|
|
'version',
|
||
|
|
'colors',
|
||
|
|
'fonts',
|
||
|
|
'barChartColors',
|
||
|
|
'pieChartColors',
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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 = '<link rel="stylesheet" type="text/css" href="'.$this->getCSSURL('yui.css').'" />';
|
||
|
|
$html .= '<link rel="stylesheet" type="text/css" href="'.$this->getCSSURL('deprecated.css').'" />';
|
||
|
|
$html .= '<link rel="stylesheet" type="text/css" href="'.$this->getCSSURL('style.css').'" />';
|
||
|
|
|
||
|
|
// 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 .= '<link rel="stylesheet" type="text/css" href="'.$this->getCSSURL('colors.'.$color.'.css').'" id="current_color_style" />';
|
||
|
|
}
|
||
|
|
|
||
|
|
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 .= '<link rel="stylesheet" type="text/css" href="'.$this->getCSSURL('fonts.'.$font.'.css').'" id="current_font_style" />';
|
||
|
|
}
|
||
|
|
|
||
|
|
return $html;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Returns javascript for the current theme
|
||
|
|
*
|
||
|
|
* @return string HTML code
|
||
|
|
*/
|
||
|
|
public function getJS()
|
||
|
|
{
|
||
|
|
$styleJS = $this->getJSURL('style.js');
|
||
|
|
return <<<EOHTML
|
||
|
|
<script type="text/javascript" src="$styleJS"></script>
|
||
|
|
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] = "<img src=\"". getJSPath($imageURL) ."\" width=\"$width\" height=\"$height\" ";
|
||
|
|
|
||
|
|
return $cached_results[$imageName] . "$other_attributes />";
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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) ) {
|
||
|
|
$cssFileContents = file_get_contents('jscalendar/calendar-win2k-cold-1.css') . $cssFileContents;
|
||
|
|
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)) != '')
|
||
|
|
$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) && $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
|
||
|
|
*
|
||
|
|
*/
|
||
|
|
public static function current()
|
||
|
|
{
|
||
|
|
if ( !isset(self::$_currentTheme) )
|
||
|
|
self::buildRegistry();
|
||
|
|
|
||
|
|
return self::$_themes[self::$_currentTheme];
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 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) && $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 ( !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();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|