mirror of
https://github.com/silverstripe/silverstripe-framework
synced 2024-10-22 14:05:37 +02:00
1e0c4ae8d1
Conflicts: cache/Cache.php cli/CliController.php core/Convert.php core/Core.php core/ManifestBuilder.php core/Object.php core/SSViewer.php core/control/ContentController.php core/control/ContentNegotiator.php core/control/FormResponse.php core/control/RequestHandler.php core/control/SilverStripeNavigatorItem.php core/i18n.php core/i18nTextCollector.php core/model/DataObjectSet.php core/model/Hierarchy.php core/model/Image.php core/model/MySQLDatabase.php core/model/SiteConfig.php core/model/SiteTree.php core/model/Translatable.php core/model/VirtualPage.php dev/Debug.php dev/SapphireTest.php dev/TestRunner.php dev/YamlFixture.php dev/install/MySQLDatabaseConfigurationHelper.php docs/en/installation/from-source.md docs/en/topics/themes.md docs/en/tutorials/4-site-search.md email/Mailer.php filesystem/File.php filesystem/Folder.php forms/ComplexTableField.php forms/CurrencyField.php forms/DateField.php forms/FieldSet.php forms/FileField.php forms/FileIFrameField.php forms/HtmlEditorConfig.php forms/HtmlEditorField.php forms/SelectionGroup.php forms/SimpleImageField.php forms/TabSet.php forms/TableField.php forms/TableListField.php forms/TreeDropdownField.php forms/TreeMultiselectField.php integration/Geoip.php javascript/SelectionGroup.js javascript/TreeSelectorField.js javascript/UpdateURL.js javascript/core/jquery.ondemand.js javascript/tiny_mce_improvements.js javascript/tree/tree.js lang/en_US.php search/ContentControllerSearchExtension.php security/Group.php security/Member.php security/PermissionCheckboxSetField.php security/PermissionRole.php security/Security.php static-main.php templates/RelationComplexTableField.ss templates/TableListField.ss tests/ConvertTest.php tests/DataObjectSetTest.php tests/DataObjectTest.php tests/DataObjectTest.yml tests/RequestHandlingTest.php tests/SSViewerTest.php tests/SiteTreePermissionsTest.php tests/SiteTreeTest.php tests/TransactionTest.php tests/api/RestfulServiceTest.php tests/control/DirectorTest.php tests/control/ModelAsControllerTest.php tests/fieldtypes/WidgetAreaEditorTest.php tests/forms/CurrencyFieldTest.php tests/forms/FormTest.php tests/model/DatabaseTest.php tests/model/ImageTest.php tests/search/ContentControllerSearchExtensionTest.php tests/security/MemberAuthenticatorTest.php thirdparty/.gitignore thirdparty/behaviour/behaviour.js thirdparty/firebug-lite/firebug.js thirdparty/firebug-lite/firebugx.js thirdparty/jquery-form/jquery.form.js thirdparty/jquery-livequery/jquery.livequery.js thirdparty/jquery-livequery/test/jquery.js thirdparty/jquery-livequery/test/test.html thirdparty/jquery-livequery/test/test2.html thirdparty/jquery-metadata/META.json thirdparty/jquery-metadata/README thirdparty/jquery-metadata/jquery.metadata.js thirdparty/jquery-metadata/test/index.html thirdparty/jquery-metadata/test/jquery.js thirdparty/jquery-metadata/test/test.js thirdparty/jquery-metadata/test/testrunner.js thirdparty/jquery-metadata/test/testsuite.css thirdparty/jquery-ui-themes/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png thirdparty/jquery-ui-themes/smoothness/images/ui-bg_flat_75_ffffff_40x100.png thirdparty/jquery-ui-themes/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png thirdparty/jquery-ui-themes/smoothness/images/ui-bg_glass_65_ffffff_1x400.png thirdparty/jquery-ui-themes/smoothness/images/ui-bg_glass_75_dadada_1x400.png thirdparty/jquery-ui-themes/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png thirdparty/jquery-ui-themes/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png thirdparty/jquery-ui-themes/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png thirdparty/jquery-ui-themes/smoothness/images/ui-icons_222222_256x240.png thirdparty/jquery-ui-themes/smoothness/images/ui-icons_2e83ff_256x240.png thirdparty/jquery-ui-themes/smoothness/images/ui-icons_454545_256x240.png thirdparty/jquery-ui-themes/smoothness/images/ui-icons_888888_256x240.png thirdparty/jquery-ui-themes/smoothness/images/ui-icons_cd0a0a_256x240.png thirdparty/jquery-ui/i18n/jquery-ui-i18n.js thirdparty/jquery-ui/i18n/ui.datepicker-ar.js thirdparty/jquery-ui/i18n/ui.datepicker-bg.js thirdparty/jquery-ui/i18n/ui.datepicker-ca.js thirdparty/jquery-ui/i18n/ui.datepicker-cs.js thirdparty/jquery-ui/i18n/ui.datepicker-da.js thirdparty/jquery-ui/i18n/ui.datepicker-de.js thirdparty/jquery-ui/i18n/ui.datepicker-el.js thirdparty/jquery-ui/i18n/ui.datepicker-eo.js thirdparty/jquery-ui/i18n/ui.datepicker-es.js thirdparty/jquery-ui/i18n/ui.datepicker-fa.js thirdparty/jquery-ui/i18n/ui.datepicker-fi.js thirdparty/jquery-ui/i18n/ui.datepicker-fr.js thirdparty/jquery-ui/i18n/ui.datepicker-he.js thirdparty/jquery-ui/i18n/ui.datepicker-hr.js thirdparty/jquery-ui/i18n/ui.datepicker-hu.js thirdparty/jquery-ui/i18n/ui.datepicker-hy.js thirdparty/jquery-ui/i18n/ui.datepicker-id.js thirdparty/jquery-ui/i18n/ui.datepicker-is.js thirdparty/jquery-ui/i18n/ui.datepicker-it.js thirdparty/jquery-ui/i18n/ui.datepicker-ja.js thirdparty/jquery-ui/i18n/ui.datepicker-ko.js thirdparty/jquery-ui/i18n/ui.datepicker-lt.js thirdparty/jquery-ui/i18n/ui.datepicker-lv.js thirdparty/jquery-ui/i18n/ui.datepicker-ms.js thirdparty/jquery-ui/i18n/ui.datepicker-nl.js thirdparty/jquery-ui/i18n/ui.datepicker-no.js thirdparty/jquery-ui/i18n/ui.datepicker-pl.js thirdparty/jquery-ui/i18n/ui.datepicker-pt-BR.js thirdparty/jquery-ui/i18n/ui.datepicker-ro.js thirdparty/jquery-ui/i18n/ui.datepicker-ru.js thirdparty/jquery-ui/i18n/ui.datepicker-sk.js thirdparty/jquery-ui/i18n/ui.datepicker-sl.js thirdparty/jquery-ui/i18n/ui.datepicker-sq.js thirdparty/jquery-ui/i18n/ui.datepicker-sr-SR.js thirdparty/jquery-ui/i18n/ui.datepicker-sr.js thirdparty/jquery-ui/i18n/ui.datepicker-sv.js thirdparty/jquery-ui/i18n/ui.datepicker-th.js thirdparty/jquery-ui/i18n/ui.datepicker-tr.js thirdparty/jquery-ui/i18n/ui.datepicker-uk.js thirdparty/jquery-ui/i18n/ui.datepicker-zh-CN.js thirdparty/jquery-ui/i18n/ui.datepicker-zh-TW.js thirdparty/jquery/jquery.js thirdparty/jsmin/.piston.yml thirdparty/jsmin/jsmin.php thirdparty/prototype/prototype.js thirdparty/scriptaculous/dragdrop.js thirdparty/simplepie/.piston.yml thirdparty/spyc/.piston.yml thirdparty/spyc/README thirdparty/spyc/php4/spyc.php4 thirdparty/spyc/php4/test.php4 thirdparty/spyc/spyc.php thirdparty/spyc/spyc.yaml thirdparty/tinymce-advcode/dialog.html thirdparty/tinymce-advcode/editor_plugin_src.js thirdparty/tinymce-advcode/js/dialog.js thirdparty/tinymce/langs/en.js thirdparty/tinymce/plugins/advhr/langs/en_dlg.js thirdparty/tinymce/plugins/advhr/rule.htm thirdparty/tinymce/plugins/advimage/image.htm thirdparty/tinymce/plugins/advimage/langs/en_dlg.js thirdparty/tinymce/plugins/advlink/langs/en_dlg.js thirdparty/tinymce/plugins/advlink/link.htm thirdparty/tinymce/plugins/emotions/emotions.htm thirdparty/tinymce/plugins/emotions/langs/en_dlg.js thirdparty/tinymce/plugins/example/dialog.htm thirdparty/tinymce/plugins/fullpage/fullpage.htm thirdparty/tinymce/plugins/fullpage/langs/en_dlg.js thirdparty/tinymce/plugins/fullscreen/fullscreen.htm thirdparty/tinymce/plugins/inlinepopups/template.htm thirdparty/tinymce/plugins/media/langs/en_dlg.js thirdparty/tinymce/plugins/media/media.htm thirdparty/tinymce/plugins/paste/js/pasteword.js thirdparty/tinymce/plugins/paste/langs/en_dlg.js thirdparty/tinymce/plugins/paste/pastetext.htm thirdparty/tinymce/plugins/paste/pasteword.htm thirdparty/tinymce/plugins/searchreplace/langs/en_dlg.js thirdparty/tinymce/plugins/searchreplace/searchreplace.htm thirdparty/tinymce/plugins/spellchecker/editor_plugin.js thirdparty/tinymce/plugins/spellchecker/editor_plugin_src.js thirdparty/tinymce/plugins/style/langs/en_dlg.js thirdparty/tinymce/plugins/style/props.htm thirdparty/tinymce/plugins/table/cell.htm thirdparty/tinymce/plugins/table/langs/en_dlg.js thirdparty/tinymce/plugins/table/merge_cells.htm thirdparty/tinymce/plugins/table/row.htm thirdparty/tinymce/plugins/table/table.htm thirdparty/tinymce/plugins/template/langs/en_dlg.js thirdparty/tinymce/plugins/template/template.htm thirdparty/tinymce/plugins/xhtmlxtras/abbr.htm thirdparty/tinymce/plugins/xhtmlxtras/acronym.htm thirdparty/tinymce/plugins/xhtmlxtras/attributes.htm thirdparty/tinymce/plugins/xhtmlxtras/cite.htm thirdparty/tinymce/plugins/xhtmlxtras/del.htm thirdparty/tinymce/plugins/xhtmlxtras/ins.htm thirdparty/tinymce/plugins/xhtmlxtras/langs/en_dlg.js thirdparty/tinymce/themes/advanced/about.htm thirdparty/tinymce/themes/advanced/anchor.htm thirdparty/tinymce/themes/advanced/charmap.htm thirdparty/tinymce/themes/advanced/color_picker.htm thirdparty/tinymce/themes/advanced/image.htm thirdparty/tinymce/themes/advanced/langs/en.js thirdparty/tinymce/themes/advanced/langs/en_dlg.js thirdparty/tinymce/themes/advanced/link.htm thirdparty/tinymce/themes/advanced/source_editor.htm thirdparty/tinymce/themes/simple/langs/en.js thirdparty/tinymce/tiny_mce.js thirdparty/tinymce/tiny_mce_src.js widgets/Widget.php
199 lines
7.4 KiB
PHP
199 lines
7.4 KiB
PHP
<?php
|
|
/**
|
|
* SS_Cache provides a bunch of static functions wrapping the Zend_Cache system in something a little more
|
|
* easy to use with the SilverStripe config system.
|
|
*
|
|
* A Zend_Cache has both a frontend (determines how to get the value to cache, and how to serialize it for storage)
|
|
* and a backend (handles the actual storage).
|
|
*
|
|
* Rather than require library code to specify the backend directly, cache consumers provide a name for the cache
|
|
* backend they want. The end developer can then specify which backend to use for each name in their project's
|
|
* _config.php. They can also use 'all' to provide a backend for all named caches
|
|
*
|
|
* End developers provide a set of named backends, then pick the specific backend for each named cache. There is a
|
|
* default File cache set up as the 'default' named backend, which is assigned to 'all' named caches
|
|
*
|
|
* USING A CACHE
|
|
*
|
|
* $cache = SS_Cache::factory('foo') ; // foo is any name (try to be specific), and is used to get configuration & storage info
|
|
*
|
|
* if (!($result = $cache->load($cachekey))) {
|
|
* $result = caluate some how;
|
|
* $cache->save($result);
|
|
* }
|
|
*
|
|
* return $result;
|
|
*
|
|
* Normally there's no need to remove things from the cache - the cache backends clear out entries based on age & maximum
|
|
* allocated storage. If you include the version of the object in the cache key, even object changes don't need any invalidation
|
|
*
|
|
* DISABLING CACHING IN DEV MOVE
|
|
*
|
|
* (in _config.php)
|
|
*
|
|
* if (Director::isDev()) SS_Cache::set_cache_lifetime('any', -1, 100);
|
|
*
|
|
* USING MEMCACHED AS STORE
|
|
*
|
|
* (in _config.php)
|
|
*
|
|
* SS_Cache::add_backend('primary_memcached', 'Memcached',
|
|
* array('host' => 'localhost', 'port' => 11211, 'persistent' => true, 'weight' => 1, 'timeout' => 5, 'retry_interval' => 15, 'status' => true, 'failure_callback' => '' )
|
|
* );
|
|
*
|
|
* SS_Cache::pick_backend('primary_memcached', 'any', 10);
|
|
* SS_Cache::pick_backend('default', 'aggregate', 20); // Aggregate needs a backend with tag support, which memcached doesn't provide
|
|
* </code>
|
|
*
|
|
* USING APC AND FILE AS TWO LEVEL STORE
|
|
*
|
|
* (in _config.php)
|
|
*
|
|
* SS_Cache::add_backend('two-level', 'TwoLevels', array(
|
|
* 'slow_backend' => 'File',
|
|
* 'fast_backend' => 'Apc',
|
|
* 'slow_backend_options' => array('cache_dir' => TEMP_FOLDER . DIRECTORY_SEPARATOR . 'cache')
|
|
* ));
|
|
*
|
|
* SS_Cache::pick_backend('two-level', 'any', 10); // No need for special backend for aggregate - TwoLevels with a File slow backend supports tags
|
|
*
|
|
* @author hfried
|
|
* @package sapphire
|
|
* @subpackage core
|
|
*/
|
|
class SS_Cache {
|
|
|
|
protected static $backends = array();
|
|
protected static $backend_picks = array();
|
|
|
|
protected static $cache_lifetime = array();
|
|
|
|
/**
|
|
* Initialize the 'default' named cache backend
|
|
*/
|
|
protected static function init(){
|
|
if (!isset(self::$backends['default'])) {
|
|
$cachedir = TEMP_FOLDER . DIRECTORY_SEPARATOR . 'cache';
|
|
if (!is_dir($cachedir)) mkdir($cachedir);
|
|
self::$backends['default'] = array('File', array('cache_dir' => TEMP_FOLDER . DIRECTORY_SEPARATOR . 'cache'));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add a new named cache backend
|
|
*
|
|
* @param string $name The name of this backend as a freeform string
|
|
* @param string $type The Zend_Cache backend ('File' or 'Sqlite' or ...)
|
|
* @param array $options The Zend_Cache backend options (see http://framework.zend.com/manual/en/zend.cache.html)
|
|
* @return none
|
|
*/
|
|
static function add_backend($name, $type, $options=array()) {
|
|
self::init();
|
|
self::$backends[$name] = array($type, $options);
|
|
}
|
|
|
|
/**
|
|
* Pick a named cache backend for a particular named cache
|
|
*
|
|
* @param string $name The name of the backend, as passed as the first argument to add_backend
|
|
* @param string $for The name of the cache to pick this backend for (or 'any' for any backend)
|
|
* @param integer $priority The priority of this pick - the call with the highest number will be the actual backend picked.
|
|
* A backend picked for a specific cache name will always be used instead of 'any' if it exists, no matter the priority.
|
|
* @return none
|
|
*/
|
|
static function pick_backend($name, $for, $priority=1) {
|
|
self::init();
|
|
|
|
$current = -1;
|
|
if (isset(self::$backend_picks[$for])) $current = self::$backend_picks[$for]['priority'];
|
|
|
|
if ($priority >= $current) self::$backend_picks[$for] = array('name' => $name, 'priority' => $priority);
|
|
}
|
|
|
|
/**
|
|
* Set the cache lifetime for a particular named cache
|
|
*
|
|
* @param string $for The name of the cache to set this lifetime for (or 'any' for all backends)
|
|
* @param integer $lifetime The lifetime of an item of the cache, in seconds, or -1 to disable caching
|
|
* @param integer $priority The priority. The highest priority setting is used. Unlike backends, 'any' is not special in terms of priority.
|
|
*/
|
|
static function set_cache_lifetime($for, $lifetime=600, $priority=1) {
|
|
self::init();
|
|
|
|
$current = -1;
|
|
if (isset(self::$cache_lifetime[$for])) $current = self::$cache_lifetime[$for]['priority'];
|
|
|
|
if ($priority >= $current) self::$cache_lifetime[$for] = array('lifetime' => $lifetime, 'priority' => $priority);
|
|
}
|
|
|
|
/**
|
|
* Build a cache object
|
|
* @param string $for The name of the cache to build the cache object for
|
|
* @param string $frontend (optional) The type of Zend_Cache frontend to use. Output is almost always the best
|
|
* @param array $frontendOptions (optional) Any frontend options to use.
|
|
*
|
|
* @return The cache object. It has been partitioned so that actions on the object
|
|
* won't affect cache objects generated with a different $for value, even those using the same Zend_Backend
|
|
*
|
|
* -- Cache a calculation
|
|
*
|
|
* if (!($result = $cache->load($cachekey))) {
|
|
* $result = caluate some how;
|
|
* $cache->save($result);
|
|
* }
|
|
*
|
|
* return $result;
|
|
*
|
|
* -- Cache captured output
|
|
*
|
|
* if (!($cache->start($cachekey))) {
|
|
*
|
|
* // output everything as usual
|
|
* echo 'Hello world! ';
|
|
* echo 'This is cached ('.time().') ';
|
|
*
|
|
* $cache->end(); // output buffering ends
|
|
* }
|
|
*
|
|
* -- Invalidate an element
|
|
*
|
|
* $cache->remove($cachekey);
|
|
*
|
|
* -- Clear the cache (warning - this clears the entire backend, not just this named cache partition)
|
|
*
|
|
* $cache->clean(Zend_Cache::CLEANING_MODE_ALL);
|
|
*
|
|
* See the Zend_Cache documentation at http://framework.zend.com/manual/en/zend.cache.html for more
|
|
*
|
|
*/
|
|
static function factory($for, $frontend='Output', $frontendOptions=null) {
|
|
self::init();
|
|
|
|
$backend_name = 'default'; $backend_priority = -1;
|
|
$cache_lifetime = 600; $lifetime_priority = -1;
|
|
|
|
foreach (array('any', $for) as $name) {
|
|
if (isset(self::$backend_picks[$name]) && self::$backend_picks[$name]['priority'] > $backend_priority) {
|
|
$backend_name = self::$backend_picks[$name]['name'];
|
|
$backend_priority = self::$backend_picks[$name]['priority'];
|
|
}
|
|
|
|
if (isset(self::$cache_lifetime[$name]) && self::$cache_lifetime[$name]['priority'] > $lifetime_priority) {
|
|
$cache_lifetime = self::$cache_lifetime[$name]['lifetime'];
|
|
$lifetime_priority = self::$cache_lifetime[$name]['priority'];
|
|
}
|
|
}
|
|
|
|
$backend = self::$backends[$backend_name];
|
|
|
|
$basicOptions = array('cache_id_prefix' => $for);
|
|
|
|
if ($cache_lifetime >= 0) $basicOptions['lifetime'] = $cache_lifetime;
|
|
else $basicOptions['caching'] = false;
|
|
|
|
$frontendOptions = $frontendOptions ? array_merge($basicOptions, $frontendOptions) : $basicOptions;
|
|
|
|
require_once 'Zend/Cache.php';
|
|
return Zend_Cache::factory($frontend, $backend[0], $frontendOptions, $backend[1]);
|
|
}
|
|
} |