329 lines
8.7 KiB
PHP
Raw Normal View History

2014-05-14 23:24:20 +10:00
<?php namespace Cms\Classes;
2014-07-19 16:07:32 +10:00
use URL;
2014-05-14 23:24:20 +10:00
use File;
2015-01-28 18:03:35 +11:00
use Yaml;
2014-05-14 23:24:20 +10:00
use Lang;
2014-07-19 16:07:32 +10:00
use Cache;
2014-05-14 23:24:20 +10:00
use Event;
use Config;
2014-07-29 17:44:24 +10:00
use DbDongle;
2014-07-19 16:07:32 +10:00
use System\Models\Parameters;
2015-01-28 18:03:35 +11:00
use SystemException;
use Cms\Models\ThemeData;
2014-07-19 16:07:32 +10:00
use DirectoryIterator;
2014-05-14 23:24:20 +10:00
/**
2014-06-25 13:47:16 +10:00
* This class represents the CMS theme.
2014-05-14 23:24:20 +10:00
* CMS theme is a directory that contains all CMS objects - pages, layouts, partials and asset files..
* The theme parameters are specified in the theme.ini file in the theme root directory.
*
* @package october\cms
* @author Alexey Bobkov, Samuel Georges
*/
class Theme
{
/**
* @var string Specifies the theme directory name.
*/
protected $dirName;
2014-07-19 13:05:50 +11:00
/**
* @var mixed Keeps the cached configuration file values.
*/
protected $configCache = null;
2014-10-09 18:08:28 +11:00
/**
* @var mixed Active theme cache in memory
*/
protected static $activeThemeCache = false;
2014-10-09 18:08:28 +11:00
/**
* @var mixed Edit theme cache in memory
*/
protected static $editThemeCache = false;
2014-10-09 18:08:28 +11:00
const ACTIVE_KEY = 'cms::theme.active';
const EDIT_KEY = 'cms::theme.edit';
2014-05-14 23:24:20 +10:00
/**
* Loads the theme.
* @return self
2014-05-14 23:24:20 +10:00
*/
public static function load($dirName)
2014-05-14 23:24:20 +10:00
{
$theme = new static;
$theme->setDirName($dirName);
return $theme;
2014-05-14 23:24:20 +10:00
}
/**
* Returns the absolute theme path.
2014-06-25 19:04:34 +10:00
* @param string $dirName Optional theme directory. Defaults to $this->getDirName()
2014-06-25 19:03:46 +10:00
* @return string
2014-05-14 23:24:20 +10:00
*/
2014-06-25 19:03:46 +10:00
public function getPath($dirName = null)
2014-05-14 23:24:20 +10:00
{
2014-10-11 01:22:03 +02:00
if (!$dirName) {
2014-06-25 19:03:46 +10:00
$dirName = $this->getDirName();
2014-10-11 01:22:03 +02:00
}
2014-06-25 13:47:16 +10:00
return themes_path().'/'.$dirName;
2014-05-14 23:24:20 +10:00
}
/**
* Sets the theme directory name.
* @return void
*/
public function setDirName($dirName)
{
$this->dirName = $dirName;
}
2014-05-14 23:24:20 +10:00
/**
* Returns the theme directory name.
* @return string
*/
public function getDirName()
{
return $this->dirName;
}
2014-06-25 13:47:16 +10:00
/**
2014-06-25 19:04:34 +10:00
* Determines if a theme with given directory name exists
* @param string $dirName The theme directory
2014-06-25 13:47:16 +10:00
* @return bool
*/
2014-06-25 19:03:46 +10:00
public static function exists($dirName)
2014-06-25 13:47:16 +10:00
{
$theme = static::load($dirName);
$path = $theme->getPath();
2014-06-25 13:47:16 +10:00
return File::isDirectory($path);
}
2014-05-14 23:24:20 +10:00
/**
* Returns a list of pages in the theme.
* This method is used internally in the routing process and in the back-end UI.
* @param boolean $skipCache Indicates if the pages should be reloaded from the disk bypassing the cache.
* @return array Returns an array of \Cms\Classes\Page objects.
*/
public function listPages($skipCache = false)
{
return Page::listInTheme($this, $skipCache);
}
/**
* Returns the active theme.
* By default the active theme is loaded from the cms.activeTheme parameter,
2014-05-17 18:08:01 +02:00
* but this behavior can be overridden by the cms.activeTheme event listeners.
* @return \Cms\Classes\Theme Returns the loaded theme object.
2014-05-14 23:24:20 +10:00
* If the theme doesn't exist, returns null.
*/
public static function getActiveTheme()
{
2014-10-11 01:22:03 +02:00
if (self::$activeThemeCache !== false) {
return self::$activeThemeCache;
2014-10-11 01:22:03 +02:00
}
2014-07-19 16:07:32 +10:00
$activeTheme = Config::get('cms.activeTheme');
2014-07-19 13:05:50 +11:00
2014-07-29 17:44:24 +10:00
if (DbDongle::hasDatabase()) {
$dbResult = Cache::remember(self::ACTIVE_KEY, 1440, function() {
return Parameters::findRecord(self::ACTIVE_KEY)->pluck('value');
});
2014-07-19 13:05:50 +11:00
if ($dbResult !== null && static::exists($dbResult)) {
2014-07-29 17:44:24 +10:00
$activeTheme = $dbResult;
2014-10-11 01:22:03 +02:00
}
2014-07-29 17:44:24 +10:00
}
2014-05-14 23:24:20 +10:00
$apiResult = Event::fire('cms.activeTheme', [], true);
2014-10-11 01:22:03 +02:00
if ($apiResult !== null) {
2014-05-14 23:24:20 +10:00
$activeTheme = $apiResult;
2014-10-11 01:22:03 +02:00
}
2014-05-14 23:24:20 +10:00
2014-10-11 01:22:03 +02:00
if (!strlen($activeTheme)) {
2014-05-14 23:24:20 +10:00
throw new SystemException(Lang::get('cms::lang.theme.active.not_set'));
2014-10-11 01:22:03 +02:00
}
2014-05-14 23:24:20 +10:00
$theme = static::load($activeTheme);
2014-10-11 01:22:03 +02:00
if (!File::isDirectory($theme->getPath())) {
return self::$activeThemeCache = null;
2014-10-11 01:22:03 +02:00
}
2014-05-14 23:24:20 +10:00
return self::$activeThemeCache = $theme;
2014-05-14 23:24:20 +10:00
}
2014-07-19 13:05:50 +11:00
/**
* Sets the active theme.
* The active theme code is stored in the database and overrides the configuration cms.activeTheme parameter.
* @param string $code Specifies the active theme code.
*/
public static function setActiveTheme($code)
{
2014-10-09 18:08:28 +11:00
self::resetCache();
Parameters::set(self::ACTIVE_KEY, $code);
2014-07-19 13:05:50 +11:00
}
2014-05-14 23:24:20 +10:00
/**
* Returns the edit theme.
* By default the edit theme is loaded from the cms.editTheme parameter,
2014-05-17 18:08:01 +02:00
* but this behavior can be overridden by the cms.editTheme event listeners.
2014-05-14 23:24:20 +10:00
* If the edit theme is not defined in the configuration file, the active theme
* is returned.
2014-05-17 18:08:01 +02:00
* @return \Cms\Classes\Theme Returns the loaded theme object.
2014-05-14 23:24:20 +10:00
* If the theme doesn't exist, returns null.
*/
public static function getEditTheme()
{
2014-10-11 01:22:03 +02:00
if (self::$editThemeCache !== false) {
return self::$editThemeCache;
2014-10-11 01:22:03 +02:00
}
2014-05-14 23:24:20 +10:00
$editTheme = Config::get('cms.editTheme');
2014-10-11 01:22:03 +02:00
if (!$editTheme) {
2014-07-25 17:21:06 +10:00
$editTheme = static::getActiveTheme()->getDirName();
2014-10-11 01:22:03 +02:00
}
2014-05-14 23:24:20 +10:00
$apiResult = Event::fire('cms.editTheme', [], true);
2014-10-11 01:22:03 +02:00
if ($apiResult !== null) {
2014-05-14 23:24:20 +10:00
$editTheme = $apiResult;
2014-10-11 01:22:03 +02:00
}
2014-05-14 23:24:20 +10:00
2014-10-11 01:22:03 +02:00
if (!strlen($editTheme)) {
2014-05-14 23:24:20 +10:00
throw new SystemException(Lang::get('cms::lang.theme.edit.not_set'));
2014-10-11 01:22:03 +02:00
}
2014-05-14 23:24:20 +10:00
$theme = static::load($editTheme);
2014-10-11 01:22:03 +02:00
if (!File::isDirectory($theme->getPath())) {
return self::$editThemeCache = null;
2014-10-11 01:22:03 +02:00
}
2014-05-14 23:24:20 +10:00
return self::$editThemeCache = $theme;
2014-05-14 23:24:20 +10:00
}
2014-07-19 13:05:50 +11:00
/**
* Returns a list of all themes.
* @return array Returns an array of the Theme objects.
*/
public static function all()
{
$it = new DirectoryIterator(themes_path());
2014-07-19 16:09:44 +10:00
$it->rewind();
2014-07-19 13:05:50 +11:00
$result = [];
foreach ($it as $fileinfo) {
2014-10-11 01:22:03 +02:00
if (!$fileinfo->isDir() || $fileinfo->isDot()) {
2014-07-19 13:05:50 +11:00
continue;
2014-10-11 01:22:03 +02:00
}
2014-07-19 13:05:50 +11:00
$theme = static::load($fileinfo->getFilename());
2014-07-19 13:05:50 +11:00
$result[] = $theme;
}
return $result;
}
/**
* Reads the theme.yaml file and returns the theme configuration values.
* @return array Returns the parsed configuration file values.
*/
public function getConfig()
{
2014-10-11 01:22:03 +02:00
if ($this->configCache !== null) {
2014-07-19 13:05:50 +11:00
return $this->configCache;
2014-10-11 01:22:03 +02:00
}
2014-07-19 13:05:50 +11:00
$path = $this->getPath().'/theme.yaml';
2014-10-11 01:22:03 +02:00
if (!File::exists($path)) {
2014-07-19 13:05:50 +11:00
return $this->configCache = [];
2014-10-11 01:22:03 +02:00
}
2014-07-19 13:05:50 +11:00
return $this->configCache = Yaml::parseFile($path);
}
/**
* Returns a value from the theme configuration file by its name.
* @param string $name Specifies the configuration parameter name.
2014-10-11 01:22:03 +02:00
* @param mixed $default Specifies the default value to return in case if the parameter
* doesn't exist in the configuration file.
2014-07-19 13:05:50 +11:00
* @return mixed Returns the parameter value or a default value
2014-10-11 01:22:03 +02:00
*/
public function getConfigValue($name, $default = null)
2014-07-19 13:05:50 +11:00
{
return array_get($this->getConfig(), $name, $default);
2014-07-19 13:05:50 +11:00
}
/**
* Returns the theme preview image URL.
* If the image file doesn't exist returns the placeholder image URL.
* @return string Returns the image URL.
*/
public function getPreviewImageUrl()
{
$previewPath = '/assets/images/theme-preview.png';
$path = $this->getPath().$previewPath;
2014-10-11 01:22:03 +02:00
if (!File::exists($path)) {
2014-07-19 13:05:50 +11:00
return URL::asset('modules/cms/assets/images/default-theme-preview.png');
2014-10-11 01:22:03 +02:00
}
2014-07-19 13:05:50 +11:00
return URL::asset('themes/'.$this->getDirName().$previewPath);
}
2014-10-09 18:08:28 +11:00
/**
* Resets any memory or cache involved with the active or edit theme.
* @return void
*/
public static function resetCache()
{
self::$activeThemeCache = false;
self::$editThemeCache = false;
Cache::forget(self::ACTIVE_KEY);
Cache::forget(self::EDIT_KEY);
}
/**
* Returns true if this theme has form fields that supply customization data.
* @return bool
*/
public function hasCustomData()
{
return $this->getConfigValue('form', false);
}
/**
* Implements the getter functionality.
* @param string $name
* @return void
*/
public function __get($name)
{
if ($this->hasCustomData()) {
$theme = ThemeData::forTheme($this);
return $theme->{$name};
}
return null;
}
/**
* Determine if an attribute exists on the object.
* @param string $key
* @return void
*/
public function __isset($key)
{
if ($this->hasCustomData()) {
$theme = ThemeData::forTheme($this);
return isset($theme->{$key});
}
return false;
}
2014-06-25 13:47:16 +10:00
}