[TASK] Simplify sprite manager
authorChristian Kuhn <lolli@schwarzbu.ch>
Wed, 1 Aug 2012 19:55:09 +0000 (21:55 +0200)
committerHelmut Hummel <helmut.hummel@typo3.org>
Wed, 1 Aug 2012 21:40:54 +0000 (23:40 +0200)
- Default sprite handler is registered in DefaultConfiguration.php
- Manager class is made static, $GLOBALS['spriteManager'] is gone
- The compliled global sprite array is stuffed to the php_code cache
  instead of an own .inc file in typo3temp/sprite
- $allowRegeneration parameter is dropped and not needed anymore: The
  cache entries are tagged and will be dropped by the extension manager
  upon loading, unloading and upgrading an extension

Change-Id: Ibb15b488dccd170a75819ad5ac44f01058510b69
Resolves: #39458
Releases: 6.0
Reviewed-on: http://review.typo3.org/13420
Reviewed-by: Steffen Ritter
Reviewed-by: Helmut Hummel
Tested-by: Helmut Hummel
t3lib/class.t3lib_spritemanager.php
t3lib/spritemanager/class.t3lib_spritemanager_abstracthandler.php
t3lib/stddb/DefaultConfiguration.php
typo3/classes/Bootstrap.php
typo3/cli_dispatch.phpsh
typo3/init.php
typo3/sysext/cms/tslib/index_ts.php

index a4e7801..ec44a06 100644 (file)
@@ -45,111 +45,87 @@ class t3lib_SpriteManager {
        public static $tempPath = 'typo3temp/sprites/';
 
        /**
-        * @var t3lib_spritemanager_SpriteIconGenerator Handler class instance
-        */
-       protected $handler = NULL;
-
-       /**
-        * @var array Register of valid icons
-        */
-       protected $iconNames = array();
-
-       /**
-        * @var string Name of current cache file
+        * Initialize sprite manager.
+        * Loads registered sprite configuration from cache, or
+        * rebuilds new cache before registration.
+        *
+        * @return void
         */
-       protected $tempFileName = '';
+       public static function initialize() {
+               $cacheIdentifier = static::getCacheIdentifier();
+               /** @var $phpCodeCache t3lib_cache_frontend_PhpFrontend */
+               $phpCodeCache = $GLOBALS['typo3CacheManager']->getCache('cache_phpcode');
+               if ($phpCodeCache->has($cacheIdentifier)) {
+                       $phpCodeCache->requireOnce($cacheIdentifier);
+               } else {
+                       static::createSpriteCache();
+                       $phpCodeCache->requireOnce($cacheIdentifier);
+               }
+       }
 
        /**
-        * Check if the icon cache has to be rebuild, instantiate and call the handler class if so.
+        * Compile sprite icon cache by calling the registered generator.
         *
-        * @param boolean $allowRegeneration Suppress regeneration if FALSE (useful for feediting)
+        * Stuff the compiled $GLOBALS['TBE_STYLES']['spriteIconApi']['iconsAvailable']
+        * global into php code cache
+        *
+        * @throws RuntimeException
+        * @return void
         */
-       function __construct($allowRegeneration = TRUE) {
+       protected static function createSpriteCache() {
+               $handlerClass = $GLOBALS['TYPO3_CONF_VARS']['BE']['spriteIconGenerator_handler'];
+               /** @var $handler t3lib_spritemanager_SpriteIconGenerator */
+               $handler = t3lib_div::makeInstance($handlerClass);
+
+                       // Throw exception if handler class does not implement required interface
+               if (!$handler instanceof t3lib_spritemanager_SpriteIconGenerator) {
+                       throw new RuntimeException(
+                               'Class ' . $handlerClass . ' in $TYPO3_CONF_VARS[BE][spriteIconGenerator_handler] ' .
+                               ' does not implement t3lib_spritemanager_SpriteIconGenerator',
+                               1294586333
+                       );
+               }
+
                        // Create temp directory if missing
                if (!is_dir(PATH_site . self::$tempPath)) {
                        t3lib_div::mkdir(PATH_site . self::$tempPath);
                }
 
-                       // Create cache filename, the hash includes all icons, registered CSS styles registered and the extension list
-               $this->tempFileName = PATH_site . self::$tempPath .
-                                                       md5(serialize($GLOBALS['TBE_STYLES']['spritemanager']) .
-                                                               md5(serialize($GLOBALS['TBE_STYLES']['spriteIconApi']['coreSpriteImageNames'])) .
-                                                               $GLOBALS['TYPO3_CONF_VARS']['EXT']['extList']) . '.inc';
-
-                       // Regenerate cache file if not already existing
-               if (!@file_exists($this->tempFileName)) {
-                       if ($allowRegeneration) {
-                               $handlerClass = (
-                               $GLOBALS['TYPO3_CONF_VARS']['BE']['spriteIconGenerator_handler'] ?
-                                               $GLOBALS['TYPO3_CONF_VARS']['BE']['spriteIconGenerator_handler'] :
-                                               't3lib_spritemanager_SimpleHandler'
-                               );
-                               $this->handler = t3lib_div::makeInstance($handlerClass);
-
-                                       // Throw exception if handler class does not implement required interface
-                               if (!$this->handler || !($this->handler instanceof t3lib_spritemanager_SpriteIconGenerator)) {
-                                       throw new RuntimeException(
-                                               'Class in $TYPO3_CONF_VARS[BE][spriteIconGenerator_handler] (' .
-                                               $GLOBALS['TYPO3_CONF_VARS']['BE']['spriteIconGenerator_handler'] .
-                                               ') does not exist or does not implement t3lib_spritemanager_SpriteIconGenerator.',
-                                               1294586333
-                                       );
-                               }
-
-                               $this->rebuildCache();
-                       } else {
-                                       // Set tempFileName to existing file if regeneration is not allowed
-                               list($this->tempFileName) = t3lib_div::getFilesInDir(PATH_site . self::$tempPath, 'inc', TRUE);
-                       }
-               }
-       }
-
-       /**
-        * Call handler class, merge results with skin data and cache it.
-        *
-        * @return void
-        */
-       protected function rebuildCache() {
                        // Generate CSS and TCA files, build icon set register
-               $this->handler->generate();
+               $handler->generate();
 
                        // Get all icons registered from skins, merge with core icon list
                $availableSkinIcons = (array) $GLOBALS['TBE_STYLES']['spriteIconApi']['coreSpriteImageNames'];
-               foreach ($GLOBALS['TBE_STYLES']['skins'] as $skinName => $skinData) {
+               foreach ($GLOBALS['TBE_STYLES']['skins'] as $skinData) {
                        $availableSkinIcons = array_merge($availableSkinIcons, (array) $skinData['availableSpriteIcons']);
                }
 
                        // Merge icon names provided by the skin, with
                        // registered "complete sprites" and the handler class
-               $this->iconNames = array_merge(
+               $iconNames = array_merge(
                        $availableSkinIcons,
                        (array) $GLOBALS['TBE_STYLES']['spritemanager']['spriteIconsAvailable'],
-                       $this->handler->getAvailableIconNames()
+                       $handler->getAvailableIconNames()
                );
 
-                       // Create serialized cache data
-               $cacheString = addslashes(serialize($this->iconNames));
-               $fileContent = '<?php $GLOBALS[\'TBE_STYLES\'][\'spriteIconApi\'][\'iconsAvailable\'] = unserialize(stripslashes(\'' . $cacheString . '\')); ?>';
-
-                       // Clean up cache directory
-               $oldFiles = t3lib_div::getFilesInDir(PATH_site . self::$tempPath, 'inc', TRUE);
-               foreach ($oldFiles as $file) {
-                       @unlink($file);
-               }
+               $cacheString = addslashes(serialize($iconNames));
+               $cacheFileContent = '$GLOBALS[\'TBE_STYLES\'][\'spriteIconApi\'][\'iconsAvailable\'] = unserialize(stripslashes(\'' . $cacheString . '\'));';
 
-                       // Write new cache file
-               t3lib_div::writeFile($this->tempFileName, $fileContent);
+               /** @var $phpCodeCache t3lib_cache_frontend_PhpFrontend */
+               $GLOBALS['typo3CacheManager']->getCache('cache_phpcode')->set(
+                       static::getCacheIdentifier(),
+                       $cacheFileContent,
+                       array('t3lib_cachemanager', 'core')
+               );
        }
 
        /**
-        * Include cache file if exists
+        * Get cache identifier for $GLOBALS['TBE_STYLES']['spriteIconApi']['iconsAvailable']
         *
-        * @return void
+        * @return string
         */
-       public function loadCacheFile() {
-               if (@file_exists($this->tempFileName)) {
-                       include_once($this->tempFileName);
-               }
+       protected static function getCacheIdentifier() {
+               return 'sprites_' . sha1(TYPO3_version . PATH_site . 'spriteManagement');
        }
 
        /**
@@ -163,8 +139,8 @@ class t3lib_SpriteManager {
         * - CSS class for loading the sprite: t3-icon-extensions-$extKey
         * - CSS class for single icons: t3-icon-$extKey-$iconName
         *
-        * @param array Icon names
-        * @param string Stylesheet filename relative to PATH_typo3. Skins do not need to supply the $styleSheetFile, if the CSS file is within the registered stylesheet folders
+        * @param array $icons Icon names
+        * @param string $styleSheetFile Stylesheet filename relative to PATH_typo3. Skins do not need to supply the $styleSheetFile, if the CSS file is within the registered stylesheet folders
         * @return void
         */
        public static function addIconSprite(array $icons, $styleSheetFile = '') {
@@ -181,8 +157,8 @@ class t3lib_SpriteManager {
         * API for extensions to register new sprite images which can be used with
         * t3lib_iconWorks::getSpriteIcon('extensions-$extKey-iconName');
         *
-        * @param array Icons to be registered, $iconname => $iconFile, $iconFile must be relative to PATH_site
-        * @param string Extension key
+        * @param array $icons Icons to be registered, $iconname => $iconFile, $iconFile must be relative to PATH_site
+        * @param string $extKey Extension key
         * @return void
         */
        public static function addSingleIcons(array $icons, $extKey = '') {
@@ -195,9 +171,9 @@ class t3lib_SpriteManager {
         * API to register new type icons for tables which use "typeicon_classes"
         * Can be used to provide icons for "modules" in pages table
         *
-        * @param string Table name to which the type icon should be added
-        * @param string Type column name of the table
-        * @param string Icon filename, relative to PATH_typo3
+        * @param string $table Table name to which the type icon should be added
+        * @param string $type Type column name of the table
+        * @param string $iconFile Icon filename, relative to PATH_typo3
         * @return void
         */
        public static function addTcaTypeIcon($table, $type, $iconFile) {
@@ -207,5 +183,4 @@ class t3lib_SpriteManager {
                }
        }
 }
-
 ?>
\ No newline at end of file
index 033a60a..baa841f 100644 (file)
@@ -64,7 +64,7 @@ abstract class t3lib_spritemanager_AbstractHandler implements t3lib_spritemanage
 
        /**
         * Loads all stylesheet files registered through
-        * t3lib_SpriteManager::::addIconSprite
+        * t3lib_SpriteManager::addIconSprite
         *
         * In fact the stylesheet-files are copied to t3lib_SpriteManager::tempPath
         * where they automatically will be included from via template.php and
index 11faf60..fbb5088 100644 (file)
@@ -546,7 +546,7 @@ return array(
                'flexformForceCDATA' => 0,                              // Boolean:  If set, will add CDATA to Flexform XML. Some versions of libxml have a bug that causes HTML entities to be stripped from any XML content and this setting will avoid the bug by adding CDATA.
                'explicitConfirmationOfTranslation' => FALSE,   // If set, then the diff-data of localized records is not saved automatically when updated but requires that a translator clicks the special finish_translation/save/close button that becomes available.
                'versionNumberInFilename' => FALSE,     // <p>Boolean: If TRUE, included CSS and JS files will have the timestamp embedded in the filename, ie. filename.1269312081.js. This will make browsers and proxies reload the files if they change (thus avoiding caching issues). IMPORTANT: this feature requires extra .htaccess rules to work (please refer to _.htaccess or the _.htaccess file from the dummy package)</p><p>If FALSE the filemtime will be appended as a query-string.</p>
-               'spriteIconGenerator_handler' => '',    // String: Used to register own/other spriteGenerating Handler, they have to implement the interface t3lib_spritemanager_SpriteIconGenerator. If set to "t3lib_spritemanager_SpriteBuildingHandler" icons from extensions will automatically merged into sprites.
+               'spriteIconGenerator_handler' => 't3lib_spritemanager_SimpleHandler',   // String: Used to register own/other spriteGenerating Handler, they have to implement the interface t3lib_spritemanager_SpriteIconGenerator. If set to "t3lib_spritemanager_SpriteBuildingHandler" icons from extensions will automatically merged into sprites.
                'debug' => FALSE,                       // Boolean: If set, the loginrefresh is disabled and pageRenderer is set to debug mode. Use this to debug the backend only!
                'AJAX' => array(                                // array of key-value pairs for a unified use of AJAX calls in the TYPO3 backend. Keys are the unique ajaxIDs where the value will be resolved to call a method in an object. See ajax.php and the classes/class.typo3ajax.php for more information.
                        'SC_alt_db_navframe::expandCollapse'                => 'typo3/alt_db_navframe.php:SC_alt_db_navframe->ajaxExpandCollapse',
index b798a5e..5b0f6cc 100644 (file)
@@ -941,15 +941,12 @@ class Typo3_Bootstrap {
        }
 
        /**
-        * Initialize sprite manager global
+        * Initialize sprite manager
         *
-        * @param boolean $allowRegeneration
         * @return Typo3_Bootstrap
         */
-       public function initializeSpriteManager($allowRegeneration = TRUE) {
-                       /** @var $spriteManager t3lib_SpriteManager */
-               $GLOBALS['spriteManager'] = t3lib_div::makeInstance('t3lib_SpriteManager', $allowRegeneration);
-               $GLOBALS['spriteManager']->loadCacheFile();
+       public function initializeSpriteManager() {
+               t3lib_SpriteManager::initialize();
 
                return $this;
        }
index 53d6d87..9c75c45 100755 (executable)
@@ -78,7 +78,7 @@ Typo3_Bootstrap_Cli::initializeCliKeyOrDie();
 Typo3_Bootstrap::getInstance()
        ->loadExtensionTables(TRUE)
                // TODO: Check if we really need the sprite manager on the command line
-       ->initializeSpriteManager(TRUE)
+       ->initializeSpriteManager()
        ->initializeBackendUser()
        ->initializeBackendUserMounts()
        ->initializeLanguageObject();
index b154322..fd41cc7 100644 (file)
@@ -96,7 +96,7 @@ Typo3_Bootstrap::getInstance()
        ->checkValidBrowserOrDie()
        ->establishDatabaseConnection()
        ->loadExtensionTables(TRUE)
-       ->initializeSpriteManager(TRUE)
+       ->initializeSpriteManager()
        ->initializeBackendUser()
        ->initializeBackendUserMounts()
        ->initializeLanguageObject()
index 94d9180..412a291 100644 (file)
@@ -182,7 +182,7 @@ $TT->pull();
 
        // Admin Panel & Frontend editing
 if ($TSFE->isBackendUserLoggedIn()) {
-       Typo3_Bootstrap::getInstance()->initializeSpriteManager(FALSE);
+       Typo3_Bootstrap::getInstance()->initializeSpriteManager();
 
        $BE_USER->initializeFrontendEdit();
        if ($BE_USER->adminPanel instanceof tslib_AdminPanel) {