first commit
This commit is contained in:
155
plugins/stThemePlugin/lib/config/stThemeConfig.class.php
Normal file
155
plugins/stThemePlugin/lib/config/stThemeConfig.class.php
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
class stThemeConfig
|
||||
{
|
||||
protected $themeConfig = null;
|
||||
|
||||
protected $config = array();
|
||||
|
||||
protected $categories = array();
|
||||
|
||||
public function load(ThemeConfig $theme_config)
|
||||
{
|
||||
$this->themeConfig = $theme_config;
|
||||
|
||||
$files = $this->findYamls($theme_config->getTheme());
|
||||
|
||||
$this->config = $this->parseYamls($files);
|
||||
|
||||
return $this->config;
|
||||
}
|
||||
|
||||
public function getThemeConfig()
|
||||
{
|
||||
return $this->themeConfig;
|
||||
}
|
||||
|
||||
public function get($name, $default = null)
|
||||
{
|
||||
return isset($this->config[$name]) ? $this->config[$name] : $default;
|
||||
}
|
||||
|
||||
public function getCategories($name)
|
||||
{
|
||||
if (!isset($this->categories[$name]))
|
||||
{
|
||||
$scope = $this->get($name);
|
||||
|
||||
if ($scope)
|
||||
{
|
||||
$results = array();
|
||||
|
||||
foreach (array_keys($scope) as $category)
|
||||
{
|
||||
if ($category[0] != '_')
|
||||
{
|
||||
$results[] = $category;
|
||||
}
|
||||
}
|
||||
|
||||
$this->categories[$name] = $results;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->categories[$name];
|
||||
}
|
||||
|
||||
public function validate()
|
||||
{
|
||||
$theme = $this->themeConfig->getTheme();
|
||||
|
||||
return is_file($this->themeConfig->getTheme()->getConfigurationPath(true)) || !$theme->isSystemDefault() && $theme->hasBaseTheme() && $this->findYamls($theme);
|
||||
}
|
||||
|
||||
protected function findYamls(Theme $theme)
|
||||
{
|
||||
$files = array();
|
||||
|
||||
if ($theme->hasBaseTheme())
|
||||
{
|
||||
$current = $theme;
|
||||
|
||||
while ($current = $current->getBaseTheme()) {
|
||||
$path = $current->getConfigurationPath(true);
|
||||
|
||||
if (is_file($path))
|
||||
{
|
||||
$files[] = $path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$files = array_reverse($files);
|
||||
|
||||
$current = $theme->getConfigurationPath(true);
|
||||
|
||||
if (is_file($current))
|
||||
{
|
||||
$files[] = $current;
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
protected function parseYamls($files)
|
||||
{
|
||||
$config = array();
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
$config = self::merge($config, Yaml::parse($file));
|
||||
}
|
||||
|
||||
return $config;
|
||||
}
|
||||
|
||||
protected static function merge($array1, $array2)
|
||||
{
|
||||
$arrays = func_get_args();
|
||||
$narrays = count($arrays);
|
||||
|
||||
// check arguments
|
||||
// comment out if more performance is necessary (in this case the foreach loop will trigger a warning if the argument is not an array)
|
||||
for ($i = 0; $i < $narrays; $i++)
|
||||
{
|
||||
if (!is_array($arrays[$i]))
|
||||
{
|
||||
// also array_merge_recursive returns nothing in this case
|
||||
throw new sfException('Argument #' . ($i + 1) . ' is not an array - trying to merge array with scalar!');
|
||||
}
|
||||
}
|
||||
|
||||
// the first array is in the output set in every case
|
||||
$ret = $arrays[0];
|
||||
|
||||
// merege $ret with the remaining arrays
|
||||
for ($i = 1; $i < $narrays; $i++)
|
||||
{
|
||||
foreach ($arrays[$i] as $key => $value)
|
||||
{
|
||||
if ($key == 'display')
|
||||
{
|
||||
$ret[$key] = $value;
|
||||
}
|
||||
elseif (((string) $key) === ((string) intval($key)))
|
||||
{ // integer or string as integer key - append
|
||||
$ret[] = $value;
|
||||
}
|
||||
else
|
||||
{ // string key - megre
|
||||
if ($value && is_array($value) && !isset($value[0]) && isset($ret[$key]))
|
||||
{
|
||||
// if $ret[$key] is not an array you try to merge an scalar value with an array - the result is not defined (incompatible arrays)
|
||||
// in this case the call will trigger an E_USER_WARNING and the $ret[$key] will be null.
|
||||
$ret[$key] = self::merge($ret[$key], $value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ret[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
<?php
|
||||
|
||||
class stThemeConfigGenerator
|
||||
{
|
||||
|
||||
/**
|
||||
*
|
||||
* @var stThemeEditorConfig
|
||||
*/
|
||||
protected $editorConfig;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var ThemeConfig
|
||||
*/
|
||||
protected $themeConfig;
|
||||
|
||||
public function __construct(stThemeEditorConfig $editor_config)
|
||||
{
|
||||
$this->themeConfig = $editor_config->getThemeConfig();
|
||||
|
||||
$this->editorConfig = $editor_config;
|
||||
}
|
||||
|
||||
public static function loadImageConfig(Theme $theme, $preview = false)
|
||||
{
|
||||
$filename = sfConfig::get('sf_data_dir').'/config/_editor/'.($preview ? 'preview_'.$theme->getName() : $theme->getName()).'.conf';
|
||||
|
||||
if (is_file($filename))
|
||||
{
|
||||
return unserialize(file_get_contents($filename));
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function generateGraphic($preview = false)
|
||||
{
|
||||
if (!$preview)
|
||||
{
|
||||
stWebFileManager::getInstance()->remove($this->themeConfig->getTheme()->getImageDir(true).'/_editor/prod');
|
||||
}
|
||||
|
||||
$this->generateImage($preview);
|
||||
|
||||
$this->generateCss($preview);
|
||||
}
|
||||
|
||||
public function generateImage($preview = false)
|
||||
{
|
||||
$theme = $this->themeConfig->getTheme();
|
||||
|
||||
$images = array();
|
||||
|
||||
if ($this->themeConfig->hasType('image'))
|
||||
{
|
||||
foreach ($this->themeConfig->getType('image') as $category => $fields)
|
||||
{
|
||||
foreach ($fields as $name => $value)
|
||||
{
|
||||
$target = $this->editorConfig->getGraphicFieldParameter($category, $name, 'default');
|
||||
|
||||
$images[$target] = $preview ? $value : $this->applyImage($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($preview)
|
||||
{
|
||||
$theme_name = 'preview_'.$theme->getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
$theme_name = $theme->getName();
|
||||
}
|
||||
|
||||
$filename = sfConfig::get('sf_data_dir').'/config/_editor/'.$theme_name.'.conf';
|
||||
|
||||
$dir = dirname($filename);
|
||||
|
||||
if (!is_dir($dir))
|
||||
{
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
|
||||
file_put_contents($filename, serialize($images));
|
||||
}
|
||||
|
||||
public function compileCss($category = null)
|
||||
{
|
||||
$css = array();
|
||||
|
||||
$theme = $this->themeConfig->getTheme();
|
||||
|
||||
$categories = $category ? array($category) : $this->editorConfig->getGraphicCategories();
|
||||
|
||||
foreach ($categories as $category)
|
||||
{
|
||||
if ($category == '_less')
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($this->editorConfig->getGraphicFields($category) as $field)
|
||||
{
|
||||
$default = $this->editorConfig->getGraphicFieldParameter($category, $field, 'default');
|
||||
|
||||
if ($this->editorConfig->hasGraphicFieldType($category, $field, 'css'))
|
||||
{
|
||||
$selector = $this->editorConfig->getGraphicFieldParameter($category, $field, 'selector');
|
||||
|
||||
$media = $this->editorConfig->getGraphicFieldParameter($category, $field, 'media', 'xs');
|
||||
|
||||
$properties = $this->editorConfig->getGraphicFieldParameter($category, $field, 'property');
|
||||
|
||||
$value = $this->themeConfig->getCss($category, $field);
|
||||
|
||||
if ($value)
|
||||
{
|
||||
foreach ((array) $properties as $property)
|
||||
{
|
||||
$css_value = $this->getValue($value, $property);
|
||||
|
||||
if ($css_value)
|
||||
{
|
||||
$css[$media][$selector][$property] = $css_value;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($this->editorConfig->getGraphicGenerated($category, $field) as $generated)
|
||||
{
|
||||
$css[isset($generated['media']) ? $generated['media'] : 'xs'][$generated['selector']][$generated['property']] = $this->getValue($value, $generated['property']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$content = array();
|
||||
|
||||
foreach ($this->editorConfig->getMedia() as $media => $setting)
|
||||
{
|
||||
if (isset($css[$media]))
|
||||
{
|
||||
if ($media != 'xs')
|
||||
{
|
||||
$content[] = "@media (".$setting.") {\n";
|
||||
}
|
||||
|
||||
$intend = $media != 'xs' ? "\t" : "";
|
||||
|
||||
foreach ($css[$media] as $selector => $properties)
|
||||
{
|
||||
$content[] = $intend.$selector." {\n";
|
||||
|
||||
foreach ($properties as $property => $value)
|
||||
{
|
||||
if ($theme->getVersion() < 7)
|
||||
{
|
||||
$content[] = $intend."\t".$property.': '.$value." !important;\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$content[] = $intend."\t".$property.': '.$value.";\n";
|
||||
}
|
||||
}
|
||||
|
||||
$content[] = $intend."}\n";
|
||||
}
|
||||
|
||||
if ($media != 'xs')
|
||||
{
|
||||
$content[] = "}\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return implode("\n", $content);
|
||||
}
|
||||
|
||||
public function generateCss($preview = false)
|
||||
{
|
||||
$theme = $this->themeConfig->getTheme();
|
||||
|
||||
$filename = $preview ? $theme->getEditorCssPath('preview_style.css', true) : $theme->getEditorCssPath('style.css', true);
|
||||
|
||||
$dir = dirname($filename);
|
||||
|
||||
if (!is_dir($dir))
|
||||
{
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
|
||||
file_put_contents($filename, $this->compileCss());
|
||||
}
|
||||
|
||||
public function generateLess($preview = false)
|
||||
{
|
||||
$less = array();
|
||||
|
||||
$fields = array_merge($this->editorConfig->getGraphicFields(array('_less', 'palette')), $this->editorConfig->getGraphicFields(array('_less', 'colors')));
|
||||
|
||||
foreach ($fields as $field)
|
||||
{
|
||||
$default = $this->editorConfig->getGraphicFieldParameter('_less', $field, 'default');
|
||||
|
||||
$value = $this->themeConfig->getLess($field, $default);
|
||||
|
||||
if (!$value || $value == 'transparent')
|
||||
{
|
||||
$less[$field] = 'transparent';
|
||||
}
|
||||
else
|
||||
{
|
||||
$less[$field] = strpos($value, 'rgb') === false ? '#'.$value : $value;
|
||||
}
|
||||
}
|
||||
|
||||
$theme = $this->themeConfig->getTheme();
|
||||
|
||||
$filename = $preview ? $theme->getEditorCssPath('preview_config.less', true) : $theme->getEditorCssPath('config.less', true);
|
||||
|
||||
$dir = dirname($filename);
|
||||
|
||||
if (!is_dir($dir))
|
||||
{
|
||||
mkdir($dir, 0755, true);
|
||||
}
|
||||
|
||||
$content = array();
|
||||
|
||||
foreach ($less as $var => $value)
|
||||
{
|
||||
$content[] = "@".$var.': '.$value.";\n";
|
||||
}
|
||||
|
||||
file_put_contents($filename, $content);
|
||||
|
||||
if ($preview && is_file($theme->getEditorCssPath('preview_style.css', true)))
|
||||
{
|
||||
$this->generateCss(true);
|
||||
}
|
||||
}
|
||||
|
||||
protected function applyImage($image)
|
||||
{
|
||||
$theme = $this->themeConfig->getTheme();
|
||||
|
||||
$target = str_replace('_editor/preview', '_editor/prod', $image);
|
||||
|
||||
$target_filename = $theme->getEditorImagePath($target, true);
|
||||
|
||||
$target_dir = dirname($target_filename);
|
||||
|
||||
if (!is_dir($target_dir))
|
||||
{
|
||||
mkdir($target_dir, 0755, true);
|
||||
}
|
||||
|
||||
$source_filename = $theme->getEditorImagePath($image, true);
|
||||
|
||||
copy($source_filename, $target_filename);
|
||||
|
||||
return $target;
|
||||
}
|
||||
|
||||
protected function getValue($value, $property)
|
||||
{
|
||||
$theme = $this->themeConfig->getTheme();
|
||||
|
||||
$css_value = null;
|
||||
|
||||
switch ($property)
|
||||
{
|
||||
case 'background-image':
|
||||
if ($value)
|
||||
{
|
||||
$css_value = sprintf('url(\'%s\')', $theme->getEditorImagePath($this->applyImage($value)));
|
||||
}
|
||||
break;
|
||||
case 'background-repeat':
|
||||
$css_value = $value;
|
||||
break;
|
||||
default:
|
||||
if (!$value || $value == 'transparent')
|
||||
{
|
||||
$css_value = 'transparent';
|
||||
}
|
||||
else
|
||||
{
|
||||
$css_value = strpos($value, 'rgb') === false ? '#'.$value : $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $css_value;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
<?php
|
||||
|
||||
class stThemeEditorConfig extends stThemeConfig
|
||||
{
|
||||
public function getMedia()
|
||||
{
|
||||
return isset($this->config['editor_config']['media']) ? $this->config['editor_config']['media'] : array('xs' => null);
|
||||
}
|
||||
|
||||
public function getGraphicCategories()
|
||||
{
|
||||
return array_keys($this->config['editor_config']['graphic']);
|
||||
}
|
||||
|
||||
public function getGraphicFields($category)
|
||||
{
|
||||
return is_array($category) ? $this->config['editor_config']['graphic'][$category[0]]['display'][$category[1]] : $this->config['editor_config']['graphic'][$category]['display'];
|
||||
}
|
||||
|
||||
public function hasGraphicFieldType($category, $field, $type)
|
||||
{
|
||||
return $this->getGraphicFieldParameter($category, $field, 'type') == $type;
|
||||
}
|
||||
|
||||
public function getGraphicCategoryLabel($category)
|
||||
{
|
||||
return isset($this->config['editor_config']['graphic'][$category]) ? $this->config['editor_config']['graphic'][$category]['label'] : null;
|
||||
}
|
||||
|
||||
public function hasGraphicFieldProperty($category, $field, $property)
|
||||
{
|
||||
$value = $this->getGraphicFieldParameter($category, $field, 'property');
|
||||
|
||||
return is_array($value) ? array_search($property, $value) : $value == $property;
|
||||
}
|
||||
|
||||
public function isGraphicFieldRelated($category, $field)
|
||||
{
|
||||
if (isset($this->config['editor_config']['graphic'][$category]['fields'][$field]['default']))
|
||||
{
|
||||
$value = $this->config['editor_config']['graphic'][$category]['fields'][$field]['default'];
|
||||
|
||||
return $value && $value{0} == '@';
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function getGraphicGenerated($category, $field)
|
||||
{
|
||||
if (isset($this->config['editor_config']['graphic'][$category]['generated'][$field]))
|
||||
{
|
||||
return $this->config['editor_config']['graphic'][$category]['generated'][$field];
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getGraphicFieldParameter($category, $field, $parameter, $default = null)
|
||||
{
|
||||
if (isset($this->config['editor_config']['graphic'][$category]['fields'][$field][$parameter]))
|
||||
{
|
||||
$value = $this->config['editor_config']['graphic'][$category]['fields'][$field][$parameter];
|
||||
|
||||
if ($parameter == 'default' && $value && $value{0} == '@')
|
||||
{
|
||||
$name = substr($value, 1);
|
||||
|
||||
$value = $this->themeConfig->getLess($name);
|
||||
|
||||
if (null === $value)
|
||||
{
|
||||
$value = $this->getGraphicFieldParameter('_less', $name, 'default');
|
||||
}
|
||||
|
||||
if ($filter = $this->getGraphicFieldParameter($category, $field, 'filter'))
|
||||
{
|
||||
$value = call_user_func(array('stThemeLess', $filter[0]), $value, $filter[1]);
|
||||
}
|
||||
}
|
||||
|
||||
return is_array($value) ? $value : ltrim($value, '#');
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user