123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- <?php
- /**
- * Serve features of Pico deprecated since v1.0
- *
- * This plugin exists for backward compatibility and is disabled by default.
- * It gets automatically enabled when a plugin which doesn't implement
- * {@link PicoPluginInterface} is loaded. This plugin triggers deprecated
- * events and automatically enables {@link PicoParsePagesContent} and
- * {@link PicoExcerpt}. These plugins heavily impact Pico's performance! You
- * can disable this plugin by calling {@link PicoDeprecated::setEnabled()}.
- *
- * The following deprecated events are triggered by this plugin:
- *
- * | Event | ... triggers the deprecated event |
- * | ------------------- | --------------------------------------------------------- |
- * | onPluginsLoaded | plugins_loaded() |
- * | onConfigLoaded | config_loaded($config) |
- * | onRequestUrl | request_url($url) |
- * | onContentLoading | before_load_content($file) |
- * | onContentLoaded | after_load_content($file, $rawContent) |
- * | on404ContentLoading | before_404_load_content($file) |
- * | on404ContentLoaded | after_404_load_content($file, $rawContent) |
- * | onMetaHeaders | before_read_file_meta($headers) |
- * | onMetaParsed | file_meta($meta) |
- * | onContentParsing | before_parse_content($rawContent) |
- * | onContentParsed | after_parse_content($content) |
- * | onContentParsed | content_parsed($content) |
- * | onSinglePageLoaded | get_page_data($pages, $meta) |
- * | onPagesLoaded | get_pages($pages, $currentPage, $previousPage, $nextPage) |
- * | onTwigRegistration | before_twig_register() |
- * | onPageRendering | before_render($twigVariables, $twig, $templateName) |
- * | onPageRendered | after_render($output) |
- *
- * Since Pico 1.0 the config is stored in {@path "config/config.php"}. This
- * plugin tries to read {@path "config.php"} in Pico's root dir and overwrites
- * all settings previously specified in {@path "config/config.php"}.
- *
- * @author Daniel Rudolf
- * @link http://picocms.org
- * @license http://opensource.org/licenses/MIT The MIT License
- * @version 1.0
- */
- class PicoDeprecated extends AbstractPicoPlugin
- {
- /**
- * This plugin is disabled by default
- *
- * @see AbstractPicoPlugin::$enabled
- */
- protected $enabled = false;
- /**
- * The requested file
- *
- * @see PicoDeprecated::getRequestFile()
- * @var string|null
- */
- protected $requestFile;
- /**
- * Enables this plugin on demand and triggers the deprecated event
- * plugins_loaded()
- *
- * @see DummyPlugin::onPluginsLoaded()
- */
- public function onPluginsLoaded(array &$plugins)
- {
- if (!empty($plugins)) {
- foreach ($plugins as $plugin) {
- if (!($plugin instanceof PicoPluginInterface)) {
- // the plugin doesn't implement PicoPluginInterface; it uses deprecated events
- // enable PicoDeprecated if it hasn't be explicitly enabled/disabled yet
- if (!$this->isStatusChanged()) {
- $this->setEnabled(true, true, true);
- }
- break;
- }
- }
- } else {
- // no plugins were found, so it actually isn't necessary to call deprecated events
- // anyway, this plugin also ensures compatibility apart from events used by old plugins,
- // so enable PicoDeprecated if it hasn't be explicitly enabled/disabled yet
- if (!$this->isStatusChanged()) {
- $this->setEnabled(true, true, true);
- }
- }
- if ($this->isEnabled()) {
- $this->triggerEvent('plugins_loaded');
- }
- }
- /**
- * Triggers the deprecated event config_loaded($config)
- *
- * This method also defines deprecated constants, reads the `config.php`
- * in Pico's root dir, enables the plugins {@link PicoParsePagesContent}
- * and {@link PicoExcerpt} and makes `$config` globally accessible (the
- * latter was removed with Pico 0.9 and was added again as deprecated
- * feature with Pico 1.0)
- *
- * @see PicoDeprecated::defineConstants()
- * @see PicoDeprecated::loadRootDirConfig()
- * @see PicoDeprecated::enablePlugins()
- * @see DummyPlugin::onConfigLoaded()
- * @param array &$config array of config variables
- * @return void
- */
- public function onConfigLoaded(array &$config)
- {
- $this->defineConstants();
- $this->loadRootDirConfig($config);
- $this->enablePlugins();
- $GLOBALS['config'] = &$config;
- $this->triggerEvent('config_loaded', array(&$config));
- }
- /**
- * Defines deprecated constants
- *
- * `ROOT_DIR`, `LIB_DIR`, `PLUGINS_DIR`, `THEMES_DIR` and `CONTENT_EXT`
- * are deprecated since v1.0, `CONTENT_DIR` existed just in v0.9,
- * `CONFIG_DIR` just for a short time between v0.9 and v1.0 and
- * `CACHE_DIR` was dropped with v1.0 without a replacement.
- *
- * @see PicoDeprecated::onConfigLoaded()
- * @return void
- */
- protected function defineConstants()
- {
- if (!defined('ROOT_DIR')) {
- define('ROOT_DIR', $this->getRootDir());
- }
- if (!defined('CONFIG_DIR')) {
- define('CONFIG_DIR', $this->getConfigDir());
- }
- if (!defined('LIB_DIR')) {
- $picoReflector = new ReflectionClass('Pico');
- define('LIB_DIR', dirname($picoReflector->getFileName()) . '/');
- }
- if (!defined('PLUGINS_DIR')) {
- define('PLUGINS_DIR', $this->getPluginsDir());
- }
- if (!defined('THEMES_DIR')) {
- define('THEMES_DIR', $this->getThemesDir());
- }
- if (!defined('CONTENT_DIR')) {
- define('CONTENT_DIR', $this->getConfig('content_dir'));
- }
- if (!defined('CONTENT_EXT')) {
- define('CONTENT_EXT', $this->getConfig('content_ext'));
- }
- }
- /**
- * Read config.php in Pico's root dir
- *
- * @see PicoDeprecated::onConfigLoaded()
- * @see Pico::loadConfig()
- * @param array &$realConfig array of config variables
- * @return void
- */
- protected function loadRootDirConfig(array &$realConfig)
- {
- if (file_exists($this->getRootDir() . 'config.php')) {
- $config = null;
- // scope isolated require()
- $includeClosure = function ($configFile) use (&$config) {
- require($configFile);
- };
- if (PHP_VERSION_ID >= 50400) {
- $includeClosure = $includeClosure->bindTo(null);
- }
- // config.php in Pico::$rootDir is deprecated
- // use config.php in Pico::$configDir instead
- $includeClosure($this->getRootDir() . 'config.php');
- if (is_array($config)) {
- if (isset($config['base_url'])) {
- $config['base_url'] = rtrim($config['base_url'], '/') . '/';
- }
- if (isset($config['content_dir'])) {
- $config['content_dir'] = rtrim($config['content_dir'], '/\\') . '/';
- }
- $realConfig = $config + $realConfig;
- }
- }
- }
- /**
- * Enables the plugins PicoParsePagesContent and PicoExcerpt
- *
- * @see PicoParsePagesContent
- * @see PicoExcerpt
- * @return void
- */
- protected function enablePlugins()
- {
- // enable PicoParsePagesContent and PicoExcerpt
- // we can't enable them during onPluginsLoaded because we can't know
- // if the user disabled us (PicoDeprecated) manually in the config
- $plugins = $this->getPlugins();
- if (isset($plugins['PicoParsePagesContent'])) {
- // parse all pages content if this plugin hasn't
- // be explicitly enabled/disabled yet
- if (!$plugins['PicoParsePagesContent']->isStatusChanged()) {
- $plugins['PicoParsePagesContent']->setEnabled(true, true, true);
- }
- }
- if (isset($plugins['PicoExcerpt'])) {
- // enable excerpt plugin if it hasn't be explicitly enabled/disabled yet
- if (!$plugins['PicoExcerpt']->isStatusChanged()) {
- $plugins['PicoExcerpt']->setEnabled(true, true, true);
- }
- }
- }
- /**
- * Triggers the deprecated event request_url($url)
- *
- * @see DummyPlugin::onRequestUrl()
- */
- public function onRequestUrl(&$url)
- {
- $this->triggerEvent('request_url', array(&$url));
- }
- /**
- * Sets PicoDeprecated::$requestFile to trigger the deprecated
- * events after_load_content() and after_404_load_content()
- *
- * @see PicoDeprecated::onContentLoaded()
- * @see PicoDeprecated::on404ContentLoaded()
- * @see DummyPlugin::onRequestFile()
- */
- public function onRequestFile(&$file)
- {
- $this->requestFile = &$file;
- }
- /**
- * Triggers the deprecated before_load_content($file)
- *
- * @see DummyPlugin::onContentLoading()
- */
- public function onContentLoading(&$file)
- {
- $this->triggerEvent('before_load_content', array(&$file));
- }
- /**
- * Triggers the deprecated event after_load_content($file, $rawContent)
- *
- * @see DummyPlugin::onContentLoaded()
- */
- public function onContentLoaded(&$rawContent)
- {
- $this->triggerEvent('after_load_content', array(&$this->requestFile, &$rawContent));
- }
- /**
- * Triggers the deprecated before_404_load_content($file)
- *
- * @see DummyPlugin::on404ContentLoading()
- */
- public function on404ContentLoading(&$file)
- {
- $this->triggerEvent('before_404_load_content', array(&$file));
- }
- /**
- * Triggers the deprecated event after_404_load_content($file, $rawContent)
- *
- * @see DummyPlugin::on404ContentLoaded()
- */
- public function on404ContentLoaded(&$rawContent)
- {
- $this->triggerEvent('after_404_load_content', array(&$this->requestFile, &$rawContent));
- }
- /**
- * Triggers the deprecated event before_read_file_meta($headers)
- *
- * @see DummyPlugin::onMetaHeaders()
- */
- public function onMetaHeaders(array &$headers)
- {
- $this->triggerEvent('before_read_file_meta', array(&$headers));
- }
- /**
- * Triggers the deprecated event file_meta($meta)
- *
- * @see DummyPlugin::onMetaParsed()
- */
- public function onMetaParsed(array &$meta)
- {
- $this->triggerEvent('file_meta', array(&$meta));
- }
- /**
- * Triggers the deprecated event before_parse_content($rawContent)
- *
- * @see DummyPlugin::onContentParsing()
- */
- public function onContentParsing(&$rawContent)
- {
- $this->triggerEvent('before_parse_content', array(&$rawContent));
- }
- /**
- * Triggers the deprecated events after_parse_content($content) and
- * content_parsed($content)
- *
- * @see DummyPlugin::onContentParsed()
- */
- public function onContentParsed(&$content)
- {
- $this->triggerEvent('after_parse_content', array(&$content));
- // deprecated since v0.8
- $this->triggerEvent('content_parsed', array(&$content));
- }
- /**
- * Triggers the deprecated event get_page_data($pages, $meta)
- *
- * @see DummyPlugin::onSinglePageLoaded()
- */
- public function onSinglePageLoaded(array &$pageData)
- {
- $this->triggerEvent('get_page_data', array(&$pageData, $pageData['meta']));
- }
- /**
- * Triggers the deprecated event
- * get_pages($pages, $currentPage, $previousPage, $nextPage)
- *
- * Please note that the `get_pages()` event gets `$pages` passed without a
- * array index. The index is rebuild later using either the `id` array key
- * or is derived from the `url` array key. Duplicates are prevented by
- * adding `~dup` when necessary.
- *
- * @see DummyPlugin::onPagesLoaded()
- */
- public function onPagesLoaded(
- array &$pages,
- array &$currentPage = null,
- array &$previousPage = null,
- array &$nextPage = null
- ) {
- // remove keys of pages array
- $plainPages = array();
- foreach ($pages as &$pageData) {
- $plainPages[] = &$pageData;
- }
- unset($pageData);
- $this->triggerEvent('get_pages', array(&$plainPages, &$currentPage, &$previousPage, &$nextPage));
- // re-index pages array
- $pages = array();
- foreach ($plainPages as &$pageData) {
- if (!isset($pageData['id'])) {
- $urlPrefixLength = strlen($this->getBaseUrl()) + intval(!$this->isUrlRewritingEnabled());
- $pageData['id'] = substr($pageData['url'], $urlPrefixLength);
- }
- // prevent duplicates
- $id = $pageData['id'];
- for ($i = 1; isset($pages[$id]); $i++) {
- $id = $pageData['id'] . '~dup' . $i;
- }
- $pages[$id] = &$pageData;
- }
- }
- /**
- * Triggers the deprecated event before_twig_register()
- *
- * @see DummyPlugin::onTwigRegistration()
- */
- public function onTwigRegistration()
- {
- $this->triggerEvent('before_twig_register');
- }
- /**
- * Triggers the deprecated event before_render($twigVariables, $twig, $templateName)
- *
- * Please note that the `before_render()` event gets `$templateName` passed
- * without its file extension. The file extension is later added again.
- *
- * @see DummyPlugin::onPageRendering()
- */
- public function onPageRendering(Twig_Environment &$twig, array &$twigVariables, &$templateName)
- {
- // template name contains file extension since Pico 1.0
- $fileExtension = '';
- if (($fileExtensionPos = strrpos($templateName, '.')) !== false) {
- $fileExtension = substr($templateName, $fileExtensionPos);
- $templateName = substr($templateName, 0, $fileExtensionPos);
- }
- $this->triggerEvent('before_render', array(&$twigVariables, &$twig, &$templateName));
- // add original file extension
- $templateName = $templateName . $fileExtension;
- }
- /**
- * Triggers the deprecated event after_render($output)
- *
- * @see DummyPlugin::onPageRendered()
- */
- public function onPageRendered(&$output)
- {
- $this->triggerEvent('after_render', array(&$output));
- }
- /**
- * Triggers a deprecated event on all plugins
- *
- * Deprecated events are also triggered on plugins which implement
- * {@link PicoPluginInterface}. Please note that the methods are called
- * directly and not through {@link PicoPluginInterface::handleEvent()}.
- *
- * @param string $eventName event to trigger
- * @param array $params parameters to pass
- * @return void
- */
- protected function triggerEvent($eventName, array $params = array())
- {
- foreach ($this->getPlugins() as $plugin) {
- if (method_exists($plugin, $eventName)) {
- call_user_func_array(array($plugin, $eventName), $params);
- }
- }
- }
- }
|