Files
server/usr/share/psa-pear/pear/php/Horde/Themes/Cache.php
2026-01-07 20:52:11 +01:00

318 lines
7.9 KiB
PHP

<?php
/**
* Copyright 2010-2017 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2010-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Core
*/
/**
* This class is responsible for parsing/building theme elements and then
* caching these results.
*
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2010-2017 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package Core
*/
class Horde_Themes_Cache implements Serializable
{
/* Constants */
const HORDE_DEFAULT = 1;
const APP_DEFAULT = 2;
const HORDE_THEME = 4;
const APP_THEME = 8;
const VIEW = 16;
/**
* Has the data changed?
*
* @var boolean
*/
public $changed = false;
/**
* Application name.
*
* @var string
*/
protected $_app;
/**
* The cache ID.
*
* @var string
*/
protected $_cacheid;
/**
* Is this a complete representation of the theme?
*
* @var boolean
*/
protected $_complete = false;
/**
* Theme data.
*
* @var array
*/
protected $_data = array();
/**
* Theme name.
*
* @var string
*/
protected $_theme;
/**
* Constructor.
*
* @param string $app The application name.
* @param string $theme The theme name.
*/
public function __construct($app, $theme)
{
$this->_app = $app;
$this->_theme = $theme;
}
/**
* Build the entire theme data structure.
*
* @return array The list of theme files.
*/
public function build()
{
if (!$this->_complete) {
$this->_data = array();
$this->_build('horde', 'default', self::HORDE_DEFAULT);
$this->_build('horde', $this->_theme, self::HORDE_THEME);
if ($this->_app != 'horde') {
$this->_build($this->_app, 'default', self::APP_DEFAULT);
$this->_build($this->_app, $this->_theme, self::APP_THEME);
}
$this->changed = $this->_complete = true;
}
return array_keys($this->_data);
}
/**
* Add theme data from an app/theme combo.
*
* @param string $app The application name.
* @param string $theme The theme name.
* @param integer $mask Mask for the app/theme combo.
*/
protected function _build($app, $theme, $mask)
{
$path = $GLOBALS['registry']->get('themesfs', $app) . '/'. $theme;
try {
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
} catch (UnexpectedValueException $e) {
return;
}
foreach ($it as $val) {
if (!$val->isDir()) {
$sub = $it->getSubPathname();
if (isset($this->_data[$sub])) {
$this->_data[$sub] |= $mask;
} else {
$this->_data[$sub] = $mask;
}
}
}
}
/**
*/
public function get($item, $mask = 0)
{
if ($mask & self::VIEW) {
$item_dir = Horde_Themes::viewDir($GLOBALS['registry']->getView()) . '/' . $item;
$mask &= ~self::VIEW;
if (!is_null($out = $this->get($item_dir, $mask))) {
return $out;
}
}
if (!($entry = $this->_get($item))) {
return null;
}
if ($mask) {
$entry &= $mask;
}
if ($entry & self::APP_THEME) {
$app = $this->_app;
$theme = $this->_theme;
} elseif ($entry & self::HORDE_THEME) {
$app = 'horde';
$theme = $this->_theme;
} elseif ($entry & self::APP_DEFAULT) {
$app = $this->_app;
$theme = 'default';
} elseif ($entry & self::HORDE_DEFAULT) {
$app = 'horde';
$theme = 'default';
} else {
return null;
}
return $this->_getOutput($app, $theme, $item);
}
/**
*/
protected function _get($item)
{
if (!isset($this->_data[$item])) {
$entry = 0;
$path = $GLOBALS['registry']->get('themesfs', 'horde');
if (file_exists($path . '/default/' . $item)) {
$entry |= self::HORDE_DEFAULT;
}
if (file_exists($path . '/' . $this->_theme . '/' . $item)) {
$entry |= self::HORDE_THEME;
}
if ($this->_app != 'horde') {
$path = $GLOBALS['registry']->get('themesfs', $this->_app);
if (file_exists($path . '/default/' . $item)) {
$entry |= self::APP_DEFAULT;
}
if (file_exists($path . '/' . $this->_theme . '/' . $item)) {
$entry |= self::APP_THEME;
}
}
$this->_data[$item] = $entry;
$this->changed = true;
}
return $this->_data[$item];
}
/**
*/
protected function _getOutput($app, $theme, $item)
{
return array(
'app' => $app,
'fs' => $GLOBALS['registry']->get('themesfs', $app) . '/' . $theme . '/' . $item,
'uri' => $GLOBALS['registry']->get('themesuri', $app) . '/' . $theme . '/' . $item
);
}
/**
*/
public function getAll($item, $mask = 0)
{
if (!($entry = $this->_get($item))) {
return array();
}
if ($mask) {
$entry &= $mask;
}
$out = array();
if ($entry & self::APP_THEME) {
$out[] = $this->_getOutput($this->_app, $this->_theme, $item);
}
if ($entry & self::HORDE_THEME) {
$out[] = $this->_getOutput('horde', $this->_theme, $item);
}
if (($this->_theme != 'default') && $entry & self::APP_DEFAULT) {
$out[] = $this->_getOutput($this->_app, 'default', $item);
}
if (($this->_theme != 'default') && $entry & self::HORDE_DEFAULT) {
$out[] = $this->_getOutput('horde', 'default', $item);
}
return $out;
}
/**
*/
public function getCacheId()
{
global $conf, $registry;
if (!isset($this->_cacheid)) {
$check = isset($conf['cachethemesparams']['check'])
? $conf['cachethemesparams']['check']
: null;
switch ($check) {
case 'appversion':
default:
$id = array($registry->getVersion($this->_app));
if ($this->_app != 'horde') {
$id[] = $registry->getVersion('horde');
}
$this->_cacheid = 'v:' . implode('|', $id);
break;
case 'none':
$this->_cacheid = '';
break;
}
}
return $this->_cacheid;
}
/* Serializable methods. */
/**
*/
public function serialize()
{
return serialize(array(
'a' => $this->_app,
'c' => $this->_complete,
'd' => $this->_data,
'id' => $this->getCacheId(),
't' => $this->_theme
));
}
/**
*/
public function unserialize($data)
{
$out = @unserialize($data);
// Needed to generate cache ID.
if (isset($out['a'])) {
$this->_app = $out['a'];
}
if (isset($out['id']) && ($out['id'] != $this->getCacheId())) {
throw new Exception('Cache invalidated for ' . $out['a'] . ': ' . $out['id'] . " != ".$this->getCacheId());
}
$this->_complete = $out['c'];
$this->_data = $out['d'];
$this->_theme = $out['t'];
}
}