Horde_Themes_Build -> Horde_Themes_Cache
authorMichael M Slusarz <slusarz@curecanti.org>
Tue, 23 Nov 2010 18:58:35 +0000 (11:58 -0700)
committerMichael M Slusarz <slusarz@curecanti.org>
Tue, 23 Nov 2010 22:47:18 +0000 (15:47 -0700)
framework/Core/lib/Horde/Core/Factory/ThemesBuild.php [deleted file]
framework/Core/lib/Horde/Core/Factory/ThemesCache.php [new file with mode: 0644]
framework/Core/lib/Horde/Themes/Build.php [deleted file]
framework/Core/lib/Horde/Themes/Cache.php [new file with mode: 0644]
framework/Core/lib/Horde/Themes/Css.php
framework/Core/lib/Horde/Themes/Element.php
framework/Core/package.xml

diff --git a/framework/Core/lib/Horde/Core/Factory/ThemesBuild.php b/framework/Core/lib/Horde/Core/Factory/ThemesBuild.php
deleted file mode 100644 (file)
index f184d28..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-<?php
-/**
- * A Horde_Injector:: based Horde_Themes_Build:: factory.
- *
- * PHP version 5
- *
- * @category Horde
- * @package  Core
- * @author   Michael Slusarz <slusarz@horde.org>
- * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
- * @link     http://pear.horde.org/index.php?package=Core
- */
-
-/**
- * A Horde_Injector:: based Horde_Themes_Build:: factory.
- *
- * Copyright 2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @category Horde
- * @package  Core
- * @author   Michael Slusarz <slusarz@horde.org>
- * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
- * @link     http://pear.horde.org/index.php?package=Core
- */
-class Horde_Core_Factory_ThemesBuild
-{
-    /**
-     * The list of cache IDs mapped to instance IDs.
-     *
-     * @var array
-     */
-    private $_cacheids = array();
-
-    /**
-     * The injector.
-     *
-     * @var Horde_Injector
-     */
-    private $_injector;
-
-    /**
-     * Instances.
-     *
-     * @var array
-     */
-    private $_instances = array();
-
-    /**
-     * Constructor.
-     *
-     * @param Horde_Injector $injector  The injector to use.
-     */
-    public function __construct(Horde_Injector $injector)
-    {
-        $this->_injector = $injector;
-    }
-
-    /**
-     * Return the Horde_Themes_Build:: instance.
-     *
-     * @param string $app    The application name.
-     * @param string $theme  The theme name.
-     *
-     * @return Horde_Themes_Build  The singleton instance.
-     */
-    public function create($app, $theme)
-    {
-        $sig = implode('|', array($app, $theme));
-
-        if (isset($this->_instances[$sig])) {
-            return $this->_instances[$sig];
-        }
-
-        if (!empty($GLOBALS['conf']['cachethemes'])) {
-            $cache = $this->_injector->getInstance('Horde_Cache');
-        }
-
-        if (!$cache || ($cache instanceof Horde_Cache_Null)) {
-            $instance = new Horde_Themes_Build($app, $theme);
-        } else {
-            $id = $sig . '|' . $GLOBALS['registry']->getVersion($app);
-            if ($app != 'horde') {
-                $id .= '|' . $GLOBALS['registry']->getVersion('horde');
-            }
-
-            $cache_sig = hash('md5', $id);
-
-            try {
-                $instance = @unserialize($cache->get($cache_sig, 86400));
-            } catch (Exception $e) {
-                $instance = null;
-            }
-
-            if (!($instance instanceof Horde_Themes_Build)) {
-                $instance = new Horde_Themes_Build($app, $theme);
-                $instance->build();
-
-                if (empty($this->_cacheids)) {
-                    register_shutdown_function(array($this, 'shutdown'));
-                }
-            }
-
-            $this->_cacheids[$sig] = $cache_sig;
-        }
-
-        $this->_instances[$sig] = $instance;
-
-        return $this->_instances[$sig];
-    }
-
-    /**
-     * Store object in cache.
-     */
-    public function shutdown()
-    {
-        $cache = $this->_injector->getInstance('Horde_Cache');
-
-        foreach ($this->_instances as $key => $val) {
-            if ($val->changed) {
-                $cache->set($this->_cacheids[$key], serialize($val), 86400);
-            }
-        }
-    }
-
-}
diff --git a/framework/Core/lib/Horde/Core/Factory/ThemesCache.php b/framework/Core/lib/Horde/Core/Factory/ThemesCache.php
new file mode 100644 (file)
index 0000000..d00efac
--- /dev/null
@@ -0,0 +1,128 @@
+<?php
+/**
+ * A Horde_Injector:: based Horde_Themes_Cache:: factory.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package  Core
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Core
+ */
+
+/**
+ * A Horde_Injector:: based Horde_Themes_Cache:: factory.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Horde
+ * @package  Core
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Core
+ */
+class Horde_Core_Factory_ThemesCache
+{
+    /**
+     * The list of cache IDs mapped to instance IDs.
+     *
+     * @var array
+     */
+    private $_cacheids = array();
+
+    /**
+     * The injector.
+     *
+     * @var Horde_Injector
+     */
+    private $_injector;
+
+    /**
+     * Instances.
+     *
+     * @var array
+     */
+    private $_instances = array();
+
+    /**
+     * Constructor.
+     *
+     * @param Horde_Injector $injector  The injector to use.
+     */
+    public function __construct(Horde_Injector $injector)
+    {
+        $this->_injector = $injector;
+    }
+
+    /**
+     * Return the Horde_Themes_Cache:: instance.
+     *
+     * @param string $app    The application name.
+     * @param string $theme  The theme name.
+     *
+     * @return Horde_Themes_Cache  The singleton instance.
+     */
+    public function create($app, $theme)
+    {
+        $sig = implode('|', array($app, $theme));
+
+        if (isset($this->_instances[$sig])) {
+            return $this->_instances[$sig];
+        }
+
+        if (!empty($GLOBALS['conf']['cachethemes'])) {
+            $cache = $this->_injector->getInstance('Horde_Cache');
+        }
+
+        if (!$cache || ($cache instanceof Horde_Cache_Null)) {
+            $instance = new Horde_Themes_Cache($app, $theme);
+        } else {
+            $id = $sig . '|' . $GLOBALS['registry']->getVersion($app);
+            if ($app != 'horde') {
+                $id .= '|' . $GLOBALS['registry']->getVersion('horde');
+            }
+
+            $cache_sig = hash('md5', $id);
+
+            try {
+                $instance = @unserialize($cache->get($cache_sig, 86400));
+            } catch (Exception $e) {
+                $instance = null;
+            }
+
+            if (!($instance instanceof Horde_Themes_Cache)) {
+                $instance = new Horde_Themes_Cache($app, $theme);
+                $instance->build();
+
+                if (empty($this->_cacheids)) {
+                    register_shutdown_function(array($this, 'shutdown'));
+                }
+            }
+
+            $this->_cacheids[$sig] = $cache_sig;
+        }
+
+        $this->_instances[$sig] = $instance;
+
+        return $this->_instances[$sig];
+    }
+
+    /**
+     * Store object in cache.
+     */
+    public function shutdown()
+    {
+        $cache = $this->_injector->getInstance('Horde_Cache');
+
+        foreach ($this->_instances as $key => $val) {
+            if ($val->changed) {
+                $cache->set($this->_cacheids[$key], serialize($val), 86400);
+            }
+        }
+    }
+
+}
diff --git a/framework/Core/lib/Horde/Themes/Build.php b/framework/Core/lib/Horde/Themes/Build.php
deleted file mode 100644 (file)
index fbe1d6c..0000000
+++ /dev/null
@@ -1,233 +0,0 @@
-<?php
-/**
- * This class is responsible for parsing/building a theme.
- *
- * Copyright 2010 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author   Michael Slusarz <slusarz@horde.org>
- * @category Horde
- * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
- * @package  Core
- */
-class Horde_Themes_Build implements Serializable
-{
-    /* Constants */
-    const HORDE_DEFAULT = 1;
-    const APP_DEFAULT = 2;
-    const HORDE_THEME = 4;
-    const APP_THEME = 8;
-
-    /**
-     * Has the data changed?
-     *
-     * @var boolean
-     */
-    public $changed = false;
-
-    /**
-     * Application name.
-     *
-     * @var string
-     */
-    protected $_app;
-
-    /**
-     * 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.
-     *
-     * @throws UnexpectedValueException
-     */
-    public function build()
-    {
-        $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 = true;
-    }
-
-    /**
-     * 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.
-     *
-     * @throws UnexpectedValueException
-     */
-    protected function _build($app, $theme, $mask)
-    {
-        $path = $GLOBALS['registry']->get('themesfs', $app) . '/'. $theme;
-        $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
-
-        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 (!($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';
-        } else {
-            $app = 'horde';
-            $theme = 'default';
-        }
-
-        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(
-            '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 ($entry & self::APP_DEFAULT) {
-            $out[] = $this->_getOutput($this->_app, 'default', $item);
-        }
-        if ($entry & self::HORDE_DEFAULT) {
-            $out[] = $this->_getOutput('horde', 'default', $item);
-        }
-
-        return $out;
-    }
-
-    /* Serializable methods. */
-
-    /**
-     */
-    public function serialize()
-    {
-        return serialize(array(
-            $this->_app,
-            $this->_data,
-            $this->_theme
-        ));
-    }
-
-    /**
-     */
-    public function unserialize($data)
-    {
-        list(
-            $this->_app,
-            $this->_data,
-            $this->_theme
-        ) = unserialize($data);
-    }
-
-}
diff --git a/framework/Core/lib/Horde/Themes/Cache.php b/framework/Core/lib/Horde/Themes/Cache.php
new file mode 100644 (file)
index 0000000..3294b14
--- /dev/null
@@ -0,0 +1,234 @@
+<?php
+/**
+ * This class is responsible for parsing/building theme elements and then
+ * caching these results.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author   Michael Slusarz <slusarz@horde.org>
+ * @category Horde
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @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;
+
+    /**
+     * Has the data changed?
+     *
+     * @var boolean
+     */
+    public $changed = false;
+
+    /**
+     * Application name.
+     *
+     * @var string
+     */
+    protected $_app;
+
+    /**
+     * 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.
+     *
+     * @throws UnexpectedValueException
+     */
+    public function build()
+    {
+        $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 = true;
+    }
+
+    /**
+     * 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.
+     *
+     * @throws UnexpectedValueException
+     */
+    protected function _build($app, $theme, $mask)
+    {
+        $path = $GLOBALS['registry']->get('themesfs', $app) . '/'. $theme;
+        $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path));
+
+        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 (!($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';
+        } else {
+            $app = 'horde';
+            $theme = 'default';
+        }
+
+        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(
+            '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 ($entry & self::APP_DEFAULT) {
+            $out[] = $this->_getOutput($this->_app, 'default', $item);
+        }
+        if ($entry & self::HORDE_DEFAULT) {
+            $out[] = $this->_getOutput('horde', 'default', $item);
+        }
+
+        return $out;
+    }
+
+    /* Serializable methods. */
+
+    /**
+     */
+    public function serialize()
+    {
+        return serialize(array(
+            $this->_app,
+            $this->_data,
+            $this->_theme
+        ));
+    }
+
+    /**
+     */
+    public function unserialize($data)
+    {
+        list(
+            $this->_app,
+            $this->_data,
+            $this->_theme
+        ) = unserialize($data);
+    }
+
+}
index 5a32cdd..d82138c 100644 (file)
@@ -182,12 +182,12 @@ class Horde_Themes_Css
             : $opts['app'];
         $mask = empty($opts['nohorde'])
             ? 0
-            : Horde_Themes_Build::APP_DEFAULT | Horde_Themes_Build::APP_THEME;
+            : Horde_Themes_Cache::APP_DEFAULT | Horde_Themes_Cache::APP_THEME;
         $sub = empty($opts['sub'])
             ? null
             : $opts['sub'];
 
-        $build = $GLOBALS['injector']->getInstance('Horde_Core_Factory_ThemesBuild')->create($curr_app, $theme);
+        $build = $GLOBALS['injector']->getInstance('Horde_Core_Factory_ThemesCache')->create($curr_app, $theme);
 
         foreach ($css_list as $css_name) {
             if (empty($opts['subonly'])) {
index a02dcd8..e60bee0 100644 (file)
@@ -121,10 +121,10 @@ class Horde_Themes_Element
                 'uri' => $registry->get('themesuri', $this->app) . '/' . $theme . '/' . $this->_dirname
             );
         } else {
-            $build = $GLOBALS['injector']->getInstance('Horde_Core_Factory_ThemesBuild')->create($this->app, $theme);
+            $build = $GLOBALS['injector']->getInstance('Horde_Core_Factory_ThemesCache')->create($this->app, $theme);
             $mask = empty($this->_opts['nohorde'])
                 ? 0
-                : Horde_Themes_Build::APP_DEFAULT | Horde_Themes_Build::APP_THEME;
+                : Horde_Themes_Cache::APP_DEFAULT | Horde_Themes_Cache::APP_THEME;
 
             $this->_data = $build->get($this->_dirname . '/' . $this->_name, $mask);
         }
index e54aec8..8516b8d 100644 (file)
@@ -164,7 +164,7 @@ Application Framework.</description>
        <file name="ShareBase.php" role="php" />
        <file name="Template.php" role="php" />
        <file name="TextFilter.php" role="php" />
-       <file name="ThemesBuild.php" role="php" />
+       <file name="ThemesCache.php" role="php" />
        <file name="Token.php" role="php" />
        <file name="Tree.php" role="php" />
        <file name="Twitter.php" role="php" />
@@ -259,7 +259,7 @@ Application Framework.</description>
       <file name="Files.php" role="php" />
      </dir> <!-- /lib/Horde/Script -->
      <dir name="Themes">
-      <file name="Build.php" role="php" />
+      <file name="Cache.php" role="php" />
       <file name="Css.php" role="php" />
       <file name="Element.php" role="php" />
       <file name="Image.php" role="php" />
@@ -786,7 +786,7 @@ Application Framework.</description>
    <install as="Horde/Core/Factory/ShareBase.php" name="lib/Horde/Core/Factory/ShareBase.php" />
    <install as="Horde/Core/Factory/Template.php" name="lib/Horde/Core/Factory/Template.php" />
    <install as="Horde/Core/Factory/TextFilter.php" name="lib/Horde/Core/Factory/TextFilter.php" />
-   <install as="Horde/Core/Factory/ThemesBuild.php" name="lib/Horde/Core/Factory/ThemesBuild.php" />
+   <install as="Horde/Core/Factory/ThemesCache.php" name="lib/Horde/Core/Factory/ThemesCache.php" />
    <install as="Horde/Core/Factory/Token.php" name="lib/Horde/Core/Factory/Token.php" />
    <install as="Horde/Core/Factory/Tree.php" name="lib/Horde/Core/Factory/Tree.php" />
    <install as="Horde/Core/Factory/Twitter.php" name="lib/Horde/Core/Factory/Twitter.php" />
@@ -831,7 +831,7 @@ Application Framework.</description>
    <install as="Horde/Registry/Application.php" name="lib/Horde/Registry/Application.php" />
    <install as="Horde/Registry/Caller.php" name="lib/Horde/Registry/Caller.php" />
    <install as="Horde/Script/Files.php" name="lib/Horde/Script/Files.php" />
-   <install as="Horde/Themes/Build.php" name="lib/Horde/Themes/Build.php" />
+   <install as="Horde/Themes/Cache.php" name="lib/Horde/Themes/Cache.php" />
    <install as="Horde/Themes/Css.php" name="lib/Horde/Themes/Css.php" />
    <install as="Horde/Themes/Element.php" name="lib/Horde/Themes/Element.php" />
    <install as="Horde/Themes/Image.php" name="lib/Horde/Themes/Image.php" />