odvečne .gitignore fajle zbrisal

master
Uros Gu 2021-06-01 02:08:00 +02:00
parent e7ece48179
commit 57f2a259c7
26 changed files with 2232 additions and 65 deletions

4
.gitignore vendored
View File

@ -16,7 +16,3 @@ desktop.ini
# Mac OS X # Mac OS X
.DS_Store .DS_Store
._* ._*
# Composer
/composer.phar
/vendor

1
assets/.gitignore vendored
View File

@ -1 +0,0 @@
# This file is meant to be empty

1
config/.gitignore vendored
View File

@ -1 +0,0 @@
# This file is meant to be empty

1
content/.gitignore vendored
View File

@ -1 +0,0 @@
# This file is meant to be empty

2
plugins/.gitignore vendored
View File

@ -1,2 +0,0 @@
# You should add plugins installed by Composer here
/PicoDeprecated

View File

@ -0,0 +1,155 @@
Pico Deprecated Changelog
=========================
**Note:** This changelog only provides technical information about the changes
introduced with a particular Pico version, and is meant to supplement
the actual code changes. The information in this changelog are often
insufficient to understand the implications of larger changes. Please
refer to both the UPGRADE and NEWS sections of the docs for more
details.
**Note:** Changes breaking backwards compatibility (BC) are marked with an `!`
(exclamation mark). This doesn't include changes for which BC is
preserved by this plugin. If a previously deprecated feature is later
removed, this change is going to be marked as BC-breaking change.
Please note that BC-breaking changes are only possible with a new
major version.
**Note:** Many versions of `PicoDeprecated` include changes which are not
explicitly mentioned in this changelog. This primarily concerns
changes in Pico's plugin API. These changes aren't listed separately
because they are already listed in Pico's changelog. Only functional
changes and/or BC-breaking changes are listed below.
### Version 2.1.4
Released: 2020-08-29
No changes
### Version 2.1.3
Released: 2020-07-10
No changes
### Version 2.1.2
Released: 2020-04-10
No changes
### Version 2.1.1
Released: 2019-12-31
No changes
### Version 2.1.0
Released: 2019-11-24
No changes
### Version 2.1.0-beta.1
Released: 2019-11-03
```
* [New] Add support for the latest API v3 changes
* [New] Support disabled Twig autoescape prior to API v3
* [New] Re-introduce `theme_url` config variable
* [New] Re-introduce `prev_page`, `base_dir` and `theme_dir` Twig variables
* [New] Support loading additional plugins using API v1 `onPluginsLoaded` event
* [New] Re-introduce Pico v0.9 config constant `CACHE_DIR`
* [New] Add release & build system to test the plugin using PHP_CodeSniffer and
to automatically create pre-built release packages
* [Changed] Split the plugin's functionality into multiple compatibility
plugins (two for each API version, for plugins and themes resp.)
and load the necessary compatibility plugins on demand only; also
allow 3rd-party plugins to load their own compatibility plugins
```
### Version 2.0.5-beta.1
Released: 2019-01-03
```
* [New] Add `2.0.x-dev` alias for master branch to `composer.json`
```
### Version 2.0.4
Released: 2018-12-17
No changes
### Version 2.0.3
Released: 2018-12-03
No changes
### Version 2.0.2
Released: 2018-08-12
No changes
### Version 2.0.1
Released: 2018-07-29
No changes
### Version 2.0.0
Released: 2018-07-01
No changes
### Version 2.0.0-beta.3
Released: 2018-04-07
No changes
### Version 2.0.0-beta.2
Released: 2018-01-21
```
* [New] Add support for the latest API v2 changes
* [New] ! Add support for themes using the old `.html` file extension for Twig
templates; however, starting with API v2 plugins might rely on `.twig`
as file extension, making this a BC-breaking change regardless
```
### Version 2.0.0-beta.1
Released: 2017-11-05
**Note:** Pico's official `PicoDeprecated` plugin was moved to this separate
repository in preparation for Pico 2.0. Refer to Pico's changelog for
a list of changes to this plugin before Pico 2.0.
```
* [New] Update plugin to API v2 and add support for all API v1 events
* [New] Keep track of all loaded Pico plugins and distinguish them by the API
version they use; deprecated events are only triggered on plugins using
this particular API version (`PicoDeprecated::API_VERSION_*` constants)
* [New] Take care of triggering events on plugins using older API versions;
this includes not only core events, but also all custom events; as a
result, old plugin's always depend on `PicoDeprecated` now
* [New] Use a simple event alias table to keep track of unchanged or just
renamed core events
* [New] Add `rewrite_url` and `is_front_page` Twig variables
* [New] Add support for the `config/config.php` configuration file
* [New] Additionally compare registered meta headers case-insensitive
* [New] Make meta headers on the first level of a page's meta data also
available using a lowered key (as of Pico 1.0; i.e. `SomeKey: value` is
now accessible using both `$meta['SomeKey']` and `$meta['somekey']`)
* [New] Add public `PicoDeprecated::triggersApiEvents()` method
* [New] Add public `PicoDeprecated::triggerEvent()` method (and the additional
`$apiVersion` parameter) as replacement for the previously protected
method of the same name
* [Fixed] ! Don't overwrite the global `$config` variable if it is defined
* [Fixed] ! Improve re-indexing of pages added by the API v0 event `get_pages`
* [Changed] No longer try to guess whether the plugin needs to be enabled or
not, rather enable it by default (guessing was pretty error-prone)
* [Changed] ! Use a scope-isolated `require()` to include configuration files
* [Changed] ! Don't pass `$plugins` parameter to API v1 `onPluginsLoaded` event
by reference anymore; use `Pico::loadPlugin()` instead
* [Changed] ! The API v1 events `onTwigRegistration` and `onMetaHeaders`, as
well as the API v0 event `before_twig_register` are no longer part
of Pico's event flow and are triggered just once on demand
* [Changed] Improve PHP class docs
* [Changed] A vast number of small improvements and changes...
* [Removed] ! Remove support for `PicoParsePagesContent` plugin
* [Removed] ! Remove support for `PicoExcerpt` plugin
```

View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2012 The Pico Community
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,383 @@
<?php
/**
* This file is part of Pico. It's copyrighted by the contributors recorded
* in the version control history of the file, available from the following
* original location:
*
* <https://github.com/picocms/pico-deprecated/blob/master/PicoDeprecated.php>
*
* The file was previously part of the project's main repository; the version
* control history of the original file applies accordingly, available from
* the following original location:
*
* <https://github.com/picocms/Pico/blob/82a342ba445122182b898a2c1800f03c8d16f18c/plugins/00-PicoDeprecated.php>
*
* SPDX-License-Identifier: MIT
* License-Filename: LICENSE
*/
/**
* Maintain backward compatibility to older Pico releases
*
* `PicoDeprecated`'s purpose is to maintain backward compatibility to older
* versions of Pico, by re-introducing characteristics that were removed from
* Pico's core.
*
* `PicoDeprecated` is basically a mandatory plugin for all Pico installs.
* Without this plugin you can't use plugins which were written for other
* API versions than the one of Pico's core, even when there was just the
* slightest change.
*
* {@see http://picocms.org/plugins/deprecated/} for a full list of features.
*
* @author Daniel Rudolf
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.1
*/
class PicoDeprecated extends AbstractPicoPlugin
{
/**
* API version used by this plugin
*
* @var int
*/
const API_VERSION = 3;
/**
* API version 0, used by Pico 0.9 and earlier
*
* @var int
*/
const API_VERSION_0 = 0;
/**
* API version 1, used by Pico 1.0
*
* @var int
*/
const API_VERSION_1 = 1;
/**
* API version 2, used by Pico 2.0
*
* @var int
*/
const API_VERSION_2 = 2;
/**
* API version 3, used by Pico 2.1
*
* @var int
*/
const API_VERSION_3 = 3;
/**
* Loaded plugins, indexed by API version
*
* @see PicoDeprecated::getPlugins()
*
* @var object[]
*/
protected $plugins = array();
/**
* Loaded compatibility plugins
*
* @see PicoDeprecated::getCompatPlugins()
*
* @var PicoCompatPluginInterface[]
*/
protected $compatPlugins = array();
/**
* {@inheritDoc}
*/
public function __construct(Pico $pico)
{
parent::__construct($pico);
if (is_file(__DIR__ . '/vendor/autoload.php')) {
require(__DIR__ . '/vendor/autoload.php');
}
if (!class_exists('PicoMainCompatPlugin')) {
die(
"Cannot find PicoDeprecated's 'vendor/autoload.php'. If you're using a composer-based Pico install, "
. "run `composer update`. If you're rather trying to use one of PicoDeprecated's pre-built release "
. "packages, make sure to download PicoDeprecated's release package matching Pico's version named "
. "'pico-deprecated-release-v*.tar.gz' (don't download a source code package)."
);
}
if ($pico::API_VERSION !== static::API_VERSION) {
throw new RuntimeException(
'PicoDeprecated requires API version ' . static::API_VERSION . ', '
. 'but Pico is running API version ' . $pico::API_VERSION
);
}
}
/**
* {@inheritDoc}
*/
public function handleEvent($eventName, array $params)
{
parent::handleEvent($eventName, $params);
// trigger events on compatibility plugins
if ($this->isEnabled() || ($eventName === 'onPluginsLoaded')) {
$isCoreEvent = in_array($eventName, $this->getCoreEvents());
foreach ($this->compatPlugins as $plugin) {
if ($isCoreEvent) {
if ($plugin->getApiVersion() === static::API_VERSION) {
$plugin->handleEvent($eventName, $params);
}
} elseif ($plugin instanceof PicoPluginApiCompatPluginInterface) {
$plugin->handleCustomEvent($eventName, $params);
}
}
}
}
/**
* Reads all loaded plugins and indexes them by API level, loads the
* necessary compatibility plugins
*
* @see PicoDeprecated::loadPlugin()
*
* @param object[] $plugins loaded plugin instances
*/
public function onPluginsLoaded(array $plugins)
{
$this->loadCompatPlugin('PicoMainCompatPlugin');
foreach ($plugins as $plugin) {
$this->loadPlugin($plugin);
}
$this->getPico()->triggerEvent('onPicoDeprecated', array($this));
}
/**
* Adds a manually loaded plugin to PicoDeprecated's plugin index, loads
* the necessary compatibility plugins
*
* @see PicoDeprecated::loadPlugin()
*
* @param object $plugin loaded plugin instance
*/
public function onPluginManuallyLoaded($plugin)
{
$this->loadPlugin($plugin);
}
/**
* Loads a compatibility plugin if Pico's theme uses a old theme API
*
* @param string $theme name of current theme
* @param int $themeApiVersion API version of the theme
* @param array $themeConfig config array of the theme
*/
public function onThemeLoaded($theme, $themeApiVersion, array &$themeConfig)
{
$this->loadThemeApiCompatPlugin($themeApiVersion);
}
/**
* Adds a plugin to PicoDeprecated's plugin index
*
* @see PicoDeprecated::onPluginsLoaded()
* @see PicoDeprecated::onPluginManuallyLoaded()
* @see PicoDeprecated::getPlugins()
*
* @param object $plugin loaded plugin instance
*/
protected function loadPlugin($plugin)
{
$pluginName = get_class($plugin);
$apiVersion = $this->getPluginApiVersion($plugin);
if (!isset($this->plugins[$apiVersion])) {
$this->plugins[$apiVersion] = array();
$this->loadPluginApiCompatPlugin($apiVersion);
}
$this->plugins[$apiVersion][$pluginName] = $plugin;
}
/**
* Returns a list of all loaded Pico plugins using the given API level
*
* @param int $apiVersion API version to match plugins
*
* @return object[] loaded plugin instances
*/
public function getPlugins($apiVersion)
{
return isset($this->plugins[$apiVersion]) ? $this->plugins[$apiVersion] : array();
}
/**
* Loads a compatibility plugin
*
* @param PicoCompatPluginInterface|string $plugin either the class name of
* a plugin to instantiate or a plugin instance
*
* @return PicoCompatPluginInterface instance of the loaded plugin
*/
public function loadCompatPlugin($plugin)
{
if (!is_object($plugin)) {
$className = (string) $plugin;
if (class_exists($className)) {
$plugin = new $className($this->getPico(), $this);
} else {
throw new RuntimeException(
"Unable to load PicoDeprecated compatibility plugin '" . $className . "': Class not found"
);
}
}
$className = get_class($plugin);
if (isset($this->compatPlugins[$className])) {
return $this->compatPlugins[$className];
}
if (!($plugin instanceof PicoCompatPluginInterface)) {
throw new RuntimeException(
"Unable to load PicoDeprecated compatibility plugin '" . $className . "': "
. "Compatibility plugins must implement 'PicoCompatPluginInterface'"
);
}
$apiVersion = $plugin->getApiVersion();
$this->loadPluginApiCompatPlugin($apiVersion);
$dependsOn = $plugin->getDependencies();
foreach ($dependsOn as $pluginDependency) {
$this->loadCompatPlugin($pluginDependency);
}
$this->compatPlugins[$className] = $plugin;
return $plugin;
}
/**
* Loads a plugin API compatibility plugin
*
* @param int $apiVersion API version to load the compatibility plugin for
*/
protected function loadPluginApiCompatPlugin($apiVersion)
{
if ($apiVersion !== static::API_VERSION) {
$this->loadCompatPlugin('PicoPluginApi' . $apiVersion . 'CompatPlugin');
}
}
/**
* Loads a theme API compatibility plugin
*
* @param int $apiVersion API version to load the compatibility plugin for
*/
protected function loadThemeApiCompatPlugin($apiVersion)
{
if ($apiVersion !== static::API_VERSION) {
$this->loadCompatPlugin('PicoThemeApi' . $apiVersion . 'CompatPlugin');
}
}
/**
* Returns all loaded compatibility plugins
*
* @return PicoCompatPluginInterface[] list of loaded compatibility plugins
*/
public function getCompatPlugins()
{
return $this->compatPlugins;
}
/**
* Triggers deprecated events on plugins of different API versions
*
* You can use this public method in other plugins to trigger custom events
* on plugins using a particular API version. If you want to trigger a
* custom event on all plugins, no matter their API version (except for
* plugins using API v0, which can't handle custom events), use
* {@see Pico::triggerEvent()} instead.
*
* @see Pico::triggerEvent()
*
* @param int $apiVersion API version of the event
* @param string $eventName event to trigger
* @param array $params optional parameters to pass
*/
public function triggerEvent($apiVersion, $eventName, array $params = array())
{
foreach ($this->getPlugins($apiVersion) as $plugin) {
$plugin->handleEvent($eventName, $params);
}
}
/**
* Returns the API version of a given plugin
*
* @param object $plugin plugin instance
*
* @return int API version used by the plugin
*/
public function getPluginApiVersion($plugin)
{
$pluginApiVersion = self::API_VERSION_0;
if ($plugin instanceof PicoPluginInterface) {
$pluginApiVersion = self::API_VERSION_1;
if (defined(get_class($plugin) . '::API_VERSION')) {
$pluginApiVersion = $plugin::API_VERSION;
}
}
return $pluginApiVersion;
}
/**
* Returns a list of the names of Pico's core events
*
* @return string[] list of Pico's core events
*/
public function getCoreEvents()
{
return array(
'onPluginsLoaded',
'onPluginManuallyLoaded',
'onConfigLoaded',
'onThemeLoading',
'onThemeLoaded',
'onRequestUrl',
'onRequestFile',
'onContentLoading',
'on404ContentLoading',
'on404ContentLoaded',
'onContentLoaded',
'onMetaParsing',
'onMetaParsed',
'onContentParsing',
'onContentPrepared',
'onContentParsed',
'onPagesLoading',
'onSinglePageLoading',
'onSinglePageContent',
'onSinglePageLoaded',
'onPagesDiscovered',
'onPagesLoaded',
'onCurrentPageDiscovered',
'onPageTreeBuilt',
'onPageRendering',
'onPageRendered',
'onMetaHeaders',
'onYamlParserRegistered',
'onParsedownRegistered',
'onTwigRegistered'
);
}
}

View File

@ -0,0 +1,44 @@
Pico Deprecated Plugin
======================
This is the repository of Pico's official `PicoDeprecated` plugin.
Pico is a stupidly simple, blazing fast, flat file CMS. See http://picocms.org/ for more info.
`PicoDeprecated`'s purpose is to maintain backward compatibility to older versions of Pico, by re-introducing characteristics that were removed from Pico's core. It for example triggers old events (like the `before_render` event used before Pico 1.0) and reads config files that were written in PHP (`config/config.php`, used before Pico 2.0).
Please refer to [`picocms/Pico`](https://github.com/picocms/Pico) to get info about how to contribute or getting help.
Install
-------
You usually don't have to install this plugin manually, it's shipped together with [Pico's pre-built release packages](https://github.com/picocms/Pico/releases/latest) and a default dependency of [`picocms/pico-composer`](https://github.com/picocms/pico-composer).
If you're using plugins and themes that are compatible with Pico's latest API version only, you can safely remove `PicoDeprecated` from your Pico installation or disable the plugin (please refer to the "Usage" section below). However, if you're not sure about this, simply leave it as it is - it won't hurt... :wink:
If you use a `composer`-based installation of Pico and want to either remove or install `PicoDeprecated`, simply open a shell on your server and navigate to Pico's install directory (e.g. `/var/www/html`). Run `composer remove picocms/pico-deprecated` to remove `PicoDeprecated`, or run `composer require picocms/pico-deprecated` (via [Packagist.org](https://packagist.org/packages/picocms/pico-deprecated)) to install `PicoDeprecated`.
If you rather use one of Pico's pre-built release packages, it is best to disable `PicoDeprecated` and not to actually remove it. The reason for this is, that `PicoDeprecated` is part of Pico's pre-built release packages, thus it will be automatically re-installed when updating Pico. However, if you really want to remove `PicoDeprecated`, simply delete the `plugins/PicoDeprecated` directory in Pico's install directory (e.g. `/var/www/html`). If you want to install `PicoDeprecated`, you must first create a empty `plugins/PicoDeprecated` directory on your server, [download the version of `PicoDeprecated`](https://github.com/picocms/pico-deprecated/releases) matching the version of your Pico installation and upload all containing files (esp. `PicoDeprecated.php` and the `lib/`, `plugins/` and `vendor/` directories) into said `plugins/PicoDeprecated` directory (resulting in `plugins/PicoDeprecated/PicoDeprecated.php`).
The versioning of `PicoDeprecated` strictly follows the version of Pico's core. You *must not* use a version of `PicoDeprecated` that doesn't match the version of Pico's core (e.g. PicoDeprecated 2.0.1 is *not compatible* with Pico 2.0.0). If you're using a `composer`-based installation of Pico, simply use a version constaint like `^2.0` - `PicoDeprecated` ensures that its version matches Pico's version. Even if you're using one of Pico's pre-built release packages, you don't have to take care of anything - a matching version of `PicoDeprecated` is part of Pico's pre-built release packages anyway.
Usage
-----
You can explicitly disable `PicoDeprecated` by adding `PicoDeprecated.enabled: false` to your `config/config.yml`. If you want to re-enable `PicoDeprecated`, simply remove this line from your `config/config.yml`. `PicoDeprecated` itself has no configuration options, it enables and disables all of its features depending on whether there are plugins and/or themes requiring said characteristics.
`PicoDeprecated`'s functionality is split into various so-called "compatibility plugins". There are compatibility plugins for every old API version (Pico 0.9 and earlier were using API version 0, Pico 1.0 was using API version 1 and Pico 2.0 was using API version 2; the current API version is version 3, used by Pico 2.1), one for plugins and another one for themes. Their purpose is to re-introduce characteristics plugins and themes using said API version might rely on. For example, plugin API compatibility plugins are responsible for simulating old Pico core events (like the `before_render` event used by Pico 0.9 and earlier). Theme API compatibility plugins will e.g. register old Twig variables (like the `is_front_page` Twig variable used by Pico 1.0). If you install a plugin using API version 2, the corresponding `PicoPluginApi2CompatPlugin` will be loaded. All plugin API compatibility plugins also depend on their theme counterpart, thus `PicoThemeApi2CompatPlugin` will be loaded, too. Furthermore all compatibility plugins depend on their respective API successors.
The plugin exposes a simple API to allow other plugins to load their own compatibility plugins. As a plugin developer you may use the `PicoDeprecated::loadCompatPlugin(PicoCompatPluginInterface $compatPlugin)` method to load a custom compatibility plugin. Use `PicoDeprecated::getCompatPlugins()` to return a list of all loaded compatibility plugins. You can furthermore use the `PicoDeprecated::getPlugins(int $apiVersion)` method to return a list of all loaded Pico plugins using a particular API version. If you want to trigger a custom event on plugins using a particular API version only, use `PicoDeprecated::triggerEvent(int $apiVersion, string $eventName, array $parameters = [])`. `PicoDeprecated` furthermore triggers the custom `onPicoDeprecated(PicoDeprecated $picoDeprecated)` event.
Getting Help
------------
Please refer to the ["Getting Help" section](https://github.com/picocms/Pico#getting-help) of our main repository.
Contributing
------------
Please refer to the ["Contributing" section](https://github.com/picocms/Pico#contributing) of our main repository.
By contributing to Pico, you accept and agree to the *Developer Certificate of Origin* for your present and future contributions submitted to Pico. Please refer to the ["Developer Certificate of Origin" section](https://github.com/picocms/Pico/blob/master/CONTRIBUTING.md#developer-certificate-of-origin) in the `CONTRIBUTING.md` of our main repository.

View File

@ -0,0 +1,41 @@
{
"name": "picocms/pico-deprecated",
"type": "pico-plugin",
"description": "This is Pico's official PicoDeprecated plugin. Pico is a stupidly simple, blazing fast, flat file CMS.",
"keywords": [ "pico", "picocms", "picocms-plugin", "pico-deprecated", "compatibility", "deprecation" ],
"homepage": "http://picocms.org/",
"license": "MIT",
"authors": [
{
"name": "Daniel Rudolf",
"email": "picocms.org@daniel-rudolf.de",
"role": "Lead Developer"
},
{
"name": "The Pico Community",
"homepage": "http://picocms.org/"
},
{
"name": "Contributors",
"homepage": "https://github.com/picocms/pico-deprecated/graphs/contributors"
}
],
"support": {
"docs": "http://picocms.org/plugins/deprecated/",
"issues": "https://github.com/picocms/pico-deprecated/issues",
"source": "https://github.com/picocms/pico-deprecated"
},
"require": {
"php": ">=5.3.0",
"picocms/pico": "self.version"
},
"autoload": {
"classmap": [ "PicoDeprecated.php", "lib/", "plugins/" ]
},
"extra": {
"branch-alias": {
"dev-master": "2.1.x-dev",
"dev-pico-3.0": "3.0.x-dev"
}
}
}

View File

@ -0,0 +1,101 @@
<?php
/**
* This file is part of Pico. It's copyrighted by the contributors recorded
* in the version control history of the file, available from the following
* original location:
*
* <https://github.com/picocms/pico-deprecated/blob/master/lib/AbstractPicoCompatPlugin.php>
*
* SPDX-License-Identifier: MIT
* License-Filename: LICENSE
*/
/**
* Abstract class to extend from when implementing a PicoDeprecated
* compatibility plugin
*
* Please refer to {@see PicoCompatPluginInterface} for more information about
* how to develop a PicoDeprecated compatibility plugin.
*
* @see PicoCompatPluginInterface
*
* @author Daniel Rudolf
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.1
*/
abstract class AbstractPicoCompatPlugin implements PicoCompatPluginInterface
{
/**
* Current instance of Pico
*
* @see PicoCompatPluginInterface::getPico()
*
* @var Pico
*/
protected $pico;
/**
* Instance of the main PicoDeprecated plugin
*
* @see PicoCompatPluginInterface::getPicoDeprecated()
*
* @var PicoDeprecated
*/
protected $picoDeprecated;
/**
* List of plugins which this plugin depends on
*
* @see PicoCompatPluginInterface::getDependencies()
*
* @var string[]
*/
protected $dependsOn = array();
/**
* Constructs a new instance of a PicoDeprecated compatibility plugin
*
* @param Pico $pico current instance of Pico
* @param PicoDeprecated $picoDeprecated current instance of PicoDeprecated
*/
public function __construct(Pico $pico, PicoDeprecated $picoDeprecated)
{
$this->pico = $pico;
$this->picoDeprecated = $picoDeprecated;
}
/**
* {@inheritDoc}
*/
public function handleEvent($eventName, array $params)
{
if (method_exists($this, $eventName)) {
call_user_func_array(array($this, $eventName), $params);
}
}
/**
* {@inheritDoc}
*/
public function getPico()
{
return $this->pico;
}
/**
* {@inheritDoc}
*/
public function getPicoDeprecated()
{
return $this->picoDeprecated;
}
/**
* {@inheritDoc}
*/
public function getDependencies()
{
return (array) $this->dependsOn;
}
}

View File

@ -0,0 +1,83 @@
<?php
/**
* This file is part of Pico. It's copyrighted by the contributors recorded
* in the version control history of the file, available from the following
* original location:
*
* <https://github.com/picocms/pico-deprecated/blob/master/lib/AbstractPicoPluginApiCompatPlugin.php>
*
* SPDX-License-Identifier: MIT
* License-Filename: LICENSE
*/
/**
* Abstract class to extend from when implementing a PicoDeprecated plugin API
* compatibility plugin
*
* Please refer to {@see PicoPluginApiCompatPluginInterface} for more information about
* how to develop a PicoDeprecated plugin API compatibility plugin.
*
* @see PicoPluginApiCompatPluginInterface
*
* @author Daniel Rudolf
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.1
*/
abstract class AbstractPicoPluginApiCompatPlugin extends AbstractPicoCompatPlugin implements
PicoPluginApiCompatPluginInterface
{
/**
* Map of core events matching event signatures of older API versions
*
* @see AbstractPicoPluginApiCompatPlugin::handleEvent()
*
* @var array<string,string>
*/
protected $eventAliases = array();
/**
* {@inheritDoc}
*/
public function handleEvent($eventName, array $params)
{
parent::handleEvent($eventName, $params);
// trigger core events matching the event signatures of older API versions
if (isset($this->eventAliases[$eventName])) {
foreach ($this->eventAliases[$eventName] as $eventAlias) {
$this->triggerEvent($eventAlias, $params);
}
}
}
/**
* {@inheritDoc}
*/
public function handleCustomEvent($eventName, array $params = array())
{
$this->getPicoDeprecated()->triggerEvent($this->getApiVersionSupport(), $eventName, $params);
}
/**
* Triggers deprecated events on plugins of the supported API version
*
* @param string $eventName name of the event to trigger
* @param array $params optional parameters to pass
*/
protected function triggerEvent($eventName, array $params = array())
{
$apiVersion = $this->getApiVersionSupport();
$picoDeprecated = $this->getPicoDeprecated();
if ($apiVersion !== $picoDeprecated::API_VERSION) {
foreach ($picoDeprecated->getCompatPlugins() as $compatPlugin) {
if ($compatPlugin->getApiVersion() === $apiVersion) {
$compatPlugin->handleEvent($eventName, $params);
}
}
}
$picoDeprecated->triggerEvent($apiVersion, $eventName, $params);
}
}

View File

@ -0,0 +1,62 @@
<?php
/**
* This file is part of Pico. It's copyrighted by the contributors recorded
* in the version control history of the file, available from the following
* original location:
*
* <https://github.com/picocms/pico-deprecated/blob/master/lib/PicoCompatPluginInterface.php>
*
* SPDX-License-Identifier: MIT
* License-Filename: LICENSE
*/
/**
* Common interface for PicoDeprecated compatibility plugins
*
* @author Daniel Rudolf
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.1
*/
interface PicoCompatPluginInterface
{
/**
* Handles a Pico event
*
* @param string $eventName name of the triggered event
* @param array $params passed parameters
*/
public function handleEvent($eventName, array $params);
/**
* Returns a list of names of compat plugins required by this plugin
*
* @return string[] required plugins
*/
public function getDependencies();
/**
* Returns the plugin's instance of Pico
*
* @see Pico
*
* @return Pico the plugin's instance of Pico
*/
public function getPico();
/**
* Returns the plugin's main PicoDeprecated plugin instance
*
* @see PicoDeprecated
*
* @return PicoDeprecated the plugin's instance of Pico
*/
public function getPicoDeprecated();
/**
* Returns the version of the API this plugin uses
*
* @return int the API version used by this plugin
*/
public function getApiVersion();
}

View File

@ -0,0 +1,37 @@
<?php
/**
* This file is part of Pico. It's copyrighted by the contributors recorded
* in the version control history of the file, available from the following
* original location:
*
* <https://github.com/picocms/pico-deprecated/blob/master/lib/PicoPluginApiCompatPluginInterface.php>
*
* SPDX-License-Identifier: MIT
* License-Filename: LICENSE
*/
/**
* Common interface for PicoDeprecated plugin API compatibility plugins
*
* @author Daniel Rudolf
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.1
*/
interface PicoPluginApiCompatPluginInterface extends PicoCompatPluginInterface
{
/**
* Handles custom events for plugins of the supported API version
*
* @param string $eventName name of the triggered event
* @param array $params passed parameters
*/
public function handleCustomEvent($eventName, array $params = array());
/**
* Returns the API version this plugin maintains backward compatibility for
*
* @return int
*/
public function getApiVersionSupport();
}

View File

@ -0,0 +1,102 @@
<?php
/**
* This file is part of Pico. It's copyrighted by the contributors recorded
* in the version control history of the file, available from the following
* original location:
*
* <https://github.com/picocms/pico-deprecated/blob/master/plugins/PicoMainCompatPlugin.php>
*
* This file was created by splitting up an original file into multiple files,
* which in turn was previously part of the project's main repository. The
* version control history of these files apply accordingly, available from
* the following original locations:
*
* <https://github.com/picocms/pico-deprecated/blob/90ea3d5a9767f1511f165e051dd7ffb8f1b3f92e/PicoDeprecated.php>
* <https://github.com/picocms/Pico/blob/82a342ba445122182b898a2c1800f03c8d16f18c/plugins/00-PicoDeprecated.php>
*
* SPDX-License-Identifier: MIT
* License-Filename: LICENSE
*/
/**
* Maintains backward compatibility with older Pico versions
*
* @author Daniel Rudolf
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.1
*/
class PicoMainCompatPlugin extends AbstractPicoCompatPlugin
{
/**
* Load's config.php from Pico's root and config dir
*
* Since we want to utilize Pico's own code dealing with particular config
* settings (like making paths and URLs absolute), we must call this before
* {@see Pico::loadConfig()}. `onConfigLoaded` is triggered later, thus we
* use the `onPluginsLoaded` event.
*
* @see PicoMainCompatPlugin::loadScriptedConfig()
*
* @param object[] $plugins loaded plugin instances
*/
public function onPluginsLoaded(array $plugins)
{
// deprecated since Pico 1.0
if (is_file($this->getPico()->getRootDir() . 'config.php')) {
$this->loadScriptedConfig($this->getPico()->getRootDir() . 'config.php');
}
// deprecated since Pico 2.0
if (is_file($this->getPico()->getConfigDir() . 'config.php')) {
$this->loadScriptedConfig($this->getPico()->getConfigDir() . 'config.php');
}
}
/**
* Reads a Pico PHP config file and injects the config into Pico
*
* This method injects the config into Pico using PHP's Reflection API
* (i.e. {@see ReflectionClass}). Even though the Reflection API was
* created to aid development and not to do things like this, it's the best
* solution. Otherwise we'd have to copy all of Pico's code dealing with
* special config settings (like making paths and URLs absolute).
*
* @see PicoMainCompatPlugin::onConfigLoaded()
* @see Pico::loadConfig()
*
* @param string $configFile path to the config file to load
*/
protected function loadScriptedConfig($configFile)
{
// scope isolated require()
$includeConfigClosure = function ($configFile) {
require($configFile);
return (isset($config) && is_array($config)) ? $config : array();
};
if (PHP_VERSION_ID >= 50400) {
$includeConfigClosure = $includeConfigClosure->bindTo(null);
}
$scriptedConfig = $includeConfigClosure($configFile);
if (!empty($scriptedConfig)) {
$picoReflector = new ReflectionObject($this->getPico());
$picoConfigReflector = $picoReflector->getProperty('config');
$picoConfigReflector->setAccessible(true);
$config = $picoConfigReflector->getValue($this->getPico()) ?: array();
$config += $scriptedConfig;
$picoConfigReflector->setValue($this->getPico(), $config);
}
}
/**
* {@inheritDoc}
*/
public function getApiVersion()
{
return PicoDeprecated::API_VERSION_3;
}
}

View File

@ -0,0 +1,314 @@
<?php
/**
* This file is part of Pico. It's copyrighted by the contributors recorded
* in the version control history of the file, available from the following
* original location:
*
* <https://github.com/picocms/pico-deprecated/blob/master/plugins/PicoPluginApi0CompatPlugin.php>
*
* This file was created by splitting up an original file into multiple files,
* which in turn was previously part of the project's main repository. The
* version control history of these files apply accordingly, available from
* the following original locations:
*
* <https://github.com/picocms/pico-deprecated/blob/90ea3d5a9767f1511f165e051dd7ffb8f1b3f92e/PicoDeprecated.php>
* <https://github.com/picocms/Pico/blob/82a342ba445122182b898a2c1800f03c8d16f18c/plugins/00-PicoDeprecated.php>
*
* SPDX-License-Identifier: MIT
* License-Filename: LICENSE
*/
/**
* Maintains backward compatibility with plugins using API version 0, written
* for Pico 0.9 and earlier
*
* @author Daniel Rudolf
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.1
*/
class PicoPluginApi0CompatPlugin extends AbstractPicoPluginApiCompatPlugin
{
/**
* This plugin extends {@see PicoPluginApi1CompatPlugin} and
* {@see PicoThemeApi0CompatPlugin}
*
* @var string[]
*/
protected $dependsOn = array('PicoPluginApi1CompatPlugin', 'PicoThemeApi0CompatPlugin');
/**
* Map of core events matching event signatures of older API versions
*
* @see AbstractPicoPluginApiCompatPlugin::handleEvent()
*
* @var array<string,string>
*/
protected $eventAliases = array(
'onConfigLoaded' => array('config_loaded'),
'onRequestUrl' => array('request_url'),
'onContentLoading' => array('before_load_content'),
'on404ContentLoading' => array('before_404_load_content'),
'onMetaParsed' => array('file_meta'),
'onContentParsing' => array('before_parse_content'),
'onContentParsed' => array('after_parse_content', 'content_parsed'),
'onTwigRegistration' => array('before_twig_register'),
'onPageRendered' => array('after_render')
);
/**
* Pico's request file
*
* @see Pico::$requestFile
* @see PicoPluginApi0CompatPlugin::onRequestFile()
*
* @var string|null
*/
protected $requestFile;
/**
* Triggers the plugins_loaded event
*
* @param object[] $plugins loaded plugin instances
*/
public function onPluginsLoaded(array &$plugins)
{
$this->triggerEvent('plugins_loaded');
}
/**
* Defines various config-related constants and sets the $config global
*
* `ROOT_DIR`, `LIB_DIR`, `PLUGINS_DIR`, `THEMES_DIR`, `CONTENT_EXT` and
* `CACHE_DIR` were removed wih Pico 1.0, `CONTENT_DIR` existed just in
* Pico 0.9 and `CONFIG_DIR` existed just for a short time between Pico 0.9
* and Pico 1.0.
*
* @param array &$config array of config variables
*/
public function onConfigLoaded(array &$config)
{
$this->defineConfigConstants($config);
if (!isset($GLOBALS['config'])) {
$GLOBALS['config'] = &$config;
}
}
/**
* Defines various config-related constants
*
* `ROOT_DIR`, `LIB_DIR`, `PLUGINS_DIR`, `THEMES_DIR`, `CONTENT_EXT` and
* `CACHE_DIR` were removed wih Pico 1.0, `CONTENT_DIR` existed just in
* Pico 0.9 and `CONFIG_DIR` existed just for a short time between Pico 0.9
* and Pico 1.0.
*
* @param array &$config array of config variables
*/
protected function defineConfigConstants(array &$config)
{
if (!defined('ROOT_DIR')) {
define('ROOT_DIR', $this->getPico()->getRootDir());
}
if (!defined('CONFIG_DIR')) {
define('CONFIG_DIR', $this->getPico()->getConfigDir());
}
if (!defined('LIB_DIR')) {
$picoReflector = new ReflectionClass('Pico');
define('LIB_DIR', dirname($picoReflector->getFileName()) . '/');
}
if (!defined('PLUGINS_DIR')) {
define('PLUGINS_DIR', $this->getPico()->getPluginsDir());
}
if (!defined('THEMES_DIR')) {
define('THEMES_DIR', $this->getPico()->getThemesDir());
}
if (!defined('CONTENT_DIR')) {
define('CONTENT_DIR', $this->getPico()->getConfig('content_dir'));
}
if (!defined('CONTENT_EXT')) {
define('CONTENT_EXT', $this->getPico()->getConfig('content_ext'));
}
if (!defined('CACHE_DIR')) {
$twigConfig = $this->getPico()->getConfig('twig_config');
define('CACHE_DIR', $twigConfig['cache'] ?: '');
}
}
/**
* Sets PicoPluginApi1CompatPlugin::$requestFile
*
* @see PicoPluginApi0CompatPlugin::$requestFile
*
* @param string &$file absolute path to the content file to serve
*/
public function onRequestFile(&$file)
{
$this->requestFile = &$file;
}
/**
* Triggers the after_404_load_content event
*
* @param string &$rawContent raw file contents
*/
public function on404ContentLoaded(&$rawContent)
{
$this->triggerEvent('after_404_load_content', array(&$this->requestFile, &$rawContent));
}
/**
* Triggers the after_load_content event
*
* @param string &$rawContent raw file contents
*/
public function onContentLoaded(&$rawContent)
{
$this->triggerEvent('after_load_content', array(&$this->requestFile, &$rawContent));
}
/**
* Triggers the before_read_file_meta event
*
* @param string &$rawContent raw file contents
* @param string[] &$headers list of known meta header fields
*/
public function onMetaParsing(&$rawContent, array &$headers)
{
$this->triggerEvent('before_read_file_meta', array(&$headers));
}
/**
* Triggers the get_page_data event
*
* @param array &$pageData data of the loaded page
*/
public function onSinglePageLoaded(array &$pageData)
{
$this->triggerEvent('get_page_data', array(&$pageData, $pageData['meta']));
}
/**
* Triggers the get_pages event
*
* 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. If it isn't possible to derive
* the array key, `~unknown` is being used. Duplicates are prevented by
* adding `~dup` when necessary.
*
* @param array[] &$pages sorted list of all known pages
* @param array|null &$currentPage data of the page being served
* @param array|null &$previousPage data of the previous page
* @param array|null &$nextPage data of the next page
*/
public function onPagesLoaded(
array &$pages,
array &$currentPage = null,
array &$previousPage = null,
array &$nextPage = null
) {
// remove keys of pages array
$plainPages = array();
foreach ($pages as &$plainPageData) {
$plainPages[] = &$plainPageData;
}
// trigger event
$this->triggerEvent('get_pages', array(&$plainPages, &$currentPage, &$previousPage, &$nextPage));
// re-index pages array
$baseUrl = $this->getPico()->getBaseUrl();
$baseUrlLength = strlen($baseUrl);
$urlRewritingEnabled = $this->getPico()->isUrlRewritingEnabled();
$pages = array();
foreach ($plainPages as &$pageData) {
if (!isset($pageData['id'])) {
if (substr($pageData['url'], 0, $baseUrlLength) === $baseUrl) {
if ($urlRewritingEnabled && (substr($pageData['url'], $baseUrlLength, 1) === '?')) {
$pageData['id'] = substr($pageData['url'], $baseUrlLength + 1);
} else {
$pageData['id'] = substr($pageData['url'], $baseUrlLength);
}
} else {
// foreign URLs are indexed by ~unknown, ~unknown~dup1, ~unknown~dup2, …
$pageData['id'] = '~unknown';
}
}
// prevent duplicates
$id = $pageData['id'];
for ($i = 1; isset($pages[$id]); $i++) {
$id = $pageData['id'] . '~dup' . $i;
}
$pages[$id] = &$pageData;
}
}
/**
* Triggers the before_render event
*
* Please note that the `before_render` event gets `$templateName` passed
* without its file extension. The file extension is re-added later.
*
* @param Twig_Environment &$twig Twig instance
* @param string &$templateName file name of the template
* @param array &$twigVariables template variables
*/
public function onPageRendering(Twig_Environment &$twig, array &$twigVariables, &$templateName)
{
$templateNameInfo = pathinfo($templateName) + array('extension' => '');
// the template name hasn't had a file extension in API v0
$templateName = $templateNameInfo['filename'];
$this->triggerEvent('before_render', array(&$twigVariables, &$twig, &$templateName));
// recover original file extension
// we assume that all templates of a theme use the same file extension
$templateName = $templateName . '.' . $templateNameInfo['extension'];
}
/**
* {@inheritDoc}
*/
public function handleCustomEvent($eventName, array $params = array())
{
// never trigger custom events
}
/**
* {@inheritDoc}
*/
public function triggerEvent($eventName, array $params = array())
{
// we don't support compat plugins using API v0, so no need to take care of compat plugins here
// API v0 events are also triggered on plugins using API v1 (but not later)
$plugins = $this->getPicoDeprecated()->getPlugins(PicoDeprecated::API_VERSION_0);
$plugins += $this->getPicoDeprecated()->getPlugins(PicoDeprecated::API_VERSION_1);
foreach ($plugins as $plugin) {
if (method_exists($plugin, $eventName)) {
call_user_func_array(array($plugin, $eventName), $params);
}
}
}
/**
* {@inheritDoc}
*/
public function getApiVersion()
{
return PicoDeprecated::API_VERSION_1;
}
/**
* {@inheritDoc}
*/
public function getApiVersionSupport()
{
return PicoDeprecated::API_VERSION_0;
}
}

View File

@ -0,0 +1,347 @@
<?php
/**
* This file is part of Pico. It's copyrighted by the contributors recorded
* in the version control history of the file, available from the following
* original location:
*
* <https://github.com/picocms/pico-deprecated/blob/master/plugins/PicoPluginApi1CompatPlugin.php>
*
* This file was created by splitting up an original file into multiple files,
* which in turn was previously part of the project's main repository. The
* version control history of these files apply accordingly, available from
* the following original locations:
*
* <https://github.com/picocms/pico-deprecated/blob/90ea3d5a9767f1511f165e051dd7ffb8f1b3f92e/PicoDeprecated.php>
* <https://github.com/picocms/Pico/blob/82a342ba445122182b898a2c1800f03c8d16f18c/plugins/00-PicoDeprecated.php>
*
* SPDX-License-Identifier: MIT
* License-Filename: LICENSE
*/
/**
* Maintains backward compatibility with plugins using API version 1, written
* for Pico 1.0
*
* @author Daniel Rudolf
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.1
*/
class PicoPluginApi1CompatPlugin extends AbstractPicoPluginApiCompatPlugin
{
/**
* This plugin extends {@see PicoPluginApi2CompatPlugin} and
* {@see PicoThemeApi1CompatPlugin}
*
* @var string[]
*/
protected $dependsOn = array('PicoPluginApi2CompatPlugin', 'PicoThemeApi1CompatPlugin');
/**
* Map of core events matching event signatures of older API versions
*
* @see AbstractPicoPluginApiCompatPlugin::handleEvent()
*
* @var array<string,string>
*/
protected $eventAliases = array(
'onConfigLoaded' => array('onConfigLoaded'),
'onRequestUrl' => array('onRequestUrl'),
'onRequestFile' => array('onRequestFile'),
'on404ContentLoaded' => array('on404ContentLoaded'),
'onContentLoaded' => array('onContentLoaded'),
'onContentPrepared' => array('onContentPrepared'),
'onContentParsed' => array('onContentParsed'),
'onPagesLoading' => array('onPagesLoading'),
'onSinglePageLoaded' => array('onSinglePageLoaded'),
'onPageRendered' => array('onPageRendered')
);
/**
* Pico's request file
*
* @see Pico::$requestFile
* @see PicoPluginApi1CompatPlugin::onRequestFile()
*
* @var string|null
*/
protected $requestFile;
/**
* Pico's raw contents
*
* @see Pico::$rawContent
* @see PicoPluginApi1CompatPlugin::onContentLoaded()
*
* @var string|null
*/
protected $rawContent;
/**
* Pico's meta headers array
*
* @see Pico::$metaHeaders
* @see PicoPluginApi1CompatPlugin::onMetaHeaders()
*
* @var array<string,string>|null
*/
protected $metaHeaders;
/**
* Pico's pages array
*
* @see Pico::$pages
* @see PicoPluginApi1CompatPlugin::onPagesLoaded()
*
* @var array[]|null
*/
protected $pages;
/**
* Pico's Twig instance
*
* @see Pico::$twig
* @see PicoPluginApi1CompatPlugin::onTwigRegistered()
*
* @var Twig_Environment|null
*/
protected $twig;
/**
* Triggers the onPluginsLoaded event
*
* Prior to API v2 the event `onPluginsLoaded` passed the `$plugins` array
* by reference. This is no longer the case. We still pass the parameter by
* reference and use {@see Pico::loadPlugin()} to load additional plugins,
* however, unloading or replacing plugins was removed without a
* replacement. This might be a BC-breaking change for you!
*
* @param object[] $plugins loaded plugin instances
*/
public function onPluginsLoaded(array $plugins)
{
$originalPlugins = $plugins;
$this->triggerEvent('onPluginsLoaded', array(&$plugins));
foreach ($plugins as $pluginName => $plugin) {
if (!isset($originalPlugins[$pluginName])) {
$this->getPico()->loadPlugin($plugin);
} elseif ($plugin !== $originalPlugins[$pluginName]) {
throw new RuntimeException(
"A Pico plugin using API version 1 tried to replace Pico plugin '" . $pluginName . "' using the "
. "onPluginsLoaded() event, however, replacing plugins was removed with API version 2"
);
}
unset($originalPlugins[$pluginName]);
}
if ($originalPlugins) {
$removedPluginsList = implode("', '", array_keys($originalPlugins));
throw new RuntimeException(
"A Pico plugin using API version 1 tried to unload the Pico plugin(s) '" . $removedPluginsList . "' "
. "using the onPluginsLoaded() event, however, unloading plugins was removed with API version 2"
);
}
}
/**
* Sets PicoPluginApi1CompatPlugin::$requestFile
*
* @see PicoPluginApi1CompatPlugin::$requestFile
*
* @param string &$file absolute path to the content file to serve
*/
public function onRequestFile(&$file)
{
$this->requestFile = &$file;
}
/**
* Triggers the onContentLoading event
*/
public function onContentLoading()
{
$this->triggerEvent('onContentLoading', array(&$this->requestFile));
}
/**
* Sets PicoPluginApi1CompatPlugin::$rawContent
*
* @see PicoPluginApi1CompatPlugin::$rawContent
*
* @param string &$rawContent raw file contents
*/
public function onContentLoaded(&$rawContent)
{
$this->rawContent = &$rawContent;
}
/**
* Triggers the on404ContentLoading event
*/
public function on404ContentLoading()
{
$this->triggerEvent('on404ContentLoading', array(&$this->requestFile));
}
/**
* Triggers the onMetaParsing event
*
* @see PicoPluginApi1CompatPlugin::onMetaHeaders()
*/
public function onMetaParsing()
{
$headersFlipped = $this->getFlippedMetaHeaders();
$this->triggerEvent('onMetaParsing', array(&$this->rawContent, &$headersFlipped));
$this->updateFlippedMetaHeaders($headersFlipped);
}
/**
* Triggers the onMetaParsed and onParsedownRegistration events
*
* @param string[] &$meta parsed meta data
*/
public function onMetaParsed(array &$meta)
{
$this->triggerEvent('onMetaParsed', array(&$meta));
$this->triggerEvent('onParsedownRegistration');
}
/**
* Triggers the onContentParsing event
*/
public function onContentParsing()
{
$this->triggerEvent('onContentParsing', array(&$this->rawContent));
}
/**
* Sets PicoPluginApi1CompatPlugin::$pages
*
* @see PicoPluginApi1CompatPlugin::$pages
*
* @param array[] &$pages sorted list of all known pages
*/
public function onPagesLoaded(array &$pages)
{
$this->pages = &$pages;
}
/**
* Triggers the onPagesLoaded and onTwigRegistration events
*
* @param array|null &$currentPage data of the page being served
* @param array|null &$previousPage data of the previous page
* @param array|null &$nextPage data of the next page
*/
public function onCurrentPageDiscovered(
array &$currentPage = null,
array &$previousPage = null,
array &$nextPage = null
) {
$this->triggerEvent('onPagesLoaded', array(&$this->pages, &$currentPage, &$previousPage, &$nextPage));
$this->triggerEvent('onTwigRegistration');
$this->getPico()->getTwig();
}
/**
* Triggers the onPageRendering event
*
* @param string &$templateName file name of the template
* @param array &$twigVariables template variables
*/
public function onPageRendering(&$templateName, array &$twigVariables)
{
$this->triggerEvent('onPageRendering', array(&$this->twig, &$twigVariables, &$templateName));
}
/**
* Triggers the onMetaHeaders event with flipped meta headers and sets
* PicoPluginApi1CompatPlugin::$metaHeaders
*
* @see PicoPluginApi1CompatPlugin::$metaHeaders
*
* @param string[] &$headers list of known meta header fields; the array
* key specifies the YAML key to search for, the array value is later
* used to access the found value
*/
public function onMetaHeaders(array &$headers)
{
$this->metaHeaders = &$headers;
$headersFlipped = $this->getFlippedMetaHeaders();
$this->triggerEvent('onMetaHeaders', array(&$headersFlipped));
$this->updateFlippedMetaHeaders($headersFlipped);
}
/**
* Sets PicoPluginApi1CompatPlugin::$twig
*
* @see PicoPluginApi1CompatPlugin::$twig
*
* @param Twig_Environment &$twig Twig instance
*/
public function onTwigRegistered(Twig_Environment &$twig)
{
$this->twig = $twig;
}
/**
* Returns the flipped meta headers array
*
* Pico 1.0 and earlier were using the values of the meta headers array to
* match registered meta headers in a page's meta data, and used the keys
* of the meta headers array to store the meta value in the page's meta
* data. However, starting with Pico 2.0 it is the other way round. This
* allows us to specify multiple "search strings" for a single registered
* meta value (e.g. "Nyan Cat" and "Tac Nayn" can be synonmous).
*
* @return array flipped meta headers
*/
protected function getFlippedMetaHeaders()
{
if ($this->metaHeaders === null) {
// make sure to trigger the onMetaHeaders event
$this->getPico()->getMetaHeaders();
}
return array_flip($this->metaHeaders ?: array());
}
/**
* Syncs PicoPluginApi1CompatPlugin::$metaHeaders with a flipped headers array
*
* @param array $headersFlipped flipped headers array
*/
protected function updateFlippedMetaHeaders(array $headersFlipped)
{
foreach ($this->metaHeaders as $name => $key) {
if (!isset($headersFlipped[$key])) {
unset($this->metaHeaders[$name]);
}
}
foreach ($headersFlipped as $key => $name) {
$this->metaHeaders[$name] = $key;
}
}
/**
* {@inheritDoc}
*/
public function getApiVersion()
{
return PicoDeprecated::API_VERSION_2;
}
/**
* {@inheritDoc}
*/
public function getApiVersionSupport()
{
return PicoDeprecated::API_VERSION_1;
}
}

View File

@ -0,0 +1,131 @@
<?php
/**
* This file is part of Pico. It's copyrighted by the contributors recorded
* in the version control history of the file, available from the following
* original location:
*
* <https://github.com/picocms/pico-deprecated/blob/master/plugins/PicoPluginApi2CompatPlugin.php>
*
* This file was created by splitting up an original file into multiple files,
* which in turn was previously part of the project's main repository. The
* version control history of these files apply accordingly, available from
* the following original locations:
*
* <https://github.com/picocms/pico-deprecated/blob/90ea3d5a9767f1511f165e051dd7ffb8f1b3f92e/PicoDeprecated.php>
* <https://github.com/picocms/Pico/blob/82a342ba445122182b898a2c1800f03c8d16f18c/plugins/00-PicoDeprecated.php>
*
* SPDX-License-Identifier: MIT
* License-Filename: LICENSE
*/
/**
* Maintains backward compatibility with plugins using API version 2, written
* for Pico 2.0
*
* @author Daniel Rudolf
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.1
*/
class PicoPluginApi2CompatPlugin extends AbstractPicoPluginApiCompatPlugin
{
/**
* This plugin extends {@see PicoThemeApi2CompatPlugin}
*
* @var string[]
*/
protected $dependsOn = array('PicoThemeApi2CompatPlugin');
/**
* Map of core events matching event signatures of older API versions
*
* @see AbstractPicoPluginApiCompatPlugin::handleEvent()
*
* @var array<string,string>
*/
protected $eventAliases = array(
'onPluginsLoaded' => array('onPluginsLoaded'),
'onPluginManuallyLoaded' => array('onPluginManuallyLoaded'),
'onRequestUrl' => array('onRequestUrl'),
'onRequestFile' => array('onRequestFile'),
'onContentLoading' => array('onContentLoading'),
'on404ContentLoading' => array('on404ContentLoading'),
'on404ContentLoaded' => array('on404ContentLoaded'),
'onContentLoaded' => array('onContentLoaded'),
'onMetaParsing' => array('onMetaParsing'),
'onMetaParsed' => array('onMetaParsed'),
'onContentParsing' => array('onContentParsing'),
'onContentPrepared' => array('onContentPrepared'),
'onContentParsed' => array('onContentParsed'),
'onPagesLoading' => array('onPagesLoading'),
'onSinglePageLoading' => array('onSinglePageLoading'),
'onSinglePageContent' => array('onSinglePageContent'),
'onSinglePageLoaded' => array('onSinglePageLoaded'),
'onPagesDiscovered' => array('onPagesDiscovered'),
'onPagesLoaded' => array('onPagesLoaded'),
'onCurrentPageDiscovered' => array('onCurrentPageDiscovered'),
'onPageTreeBuilt' => array('onPageTreeBuilt'),
'onPageRendering' => array('onPageRendering'),
'onPageRendered' => array('onPageRendered'),
'onMetaHeaders' => array('onMetaHeaders'),
'onYamlParserRegistered' => array('onYamlParserRegistered'),
'onParsedownRegistered' => array('onParsedownRegistered'),
'onTwigRegistered' => array('onTwigRegistered')
);
/**
* Pico's config array
*
* @see Pico::$config
* @see PicoPluginApi2CompatPlugin::onConfigLoaded()
*
* @var array|null
*/
protected $config;
/**
* Sets PicoPluginApi1CompatPlugin::$config and handles the theme_url
* config param
*
* @see PicoPluginApi2CompatPlugin::$config
*
* @param array $config
*/
public function onConfigLoaded(array &$config)
{
$this->config = &$config;
if (!empty($config['theme_url'])) {
$config['themes_url'] = $this->getPico()->getAbsoluteUrl($config['theme_url']);
$config['theme_url'] = &$config['themes_url'];
}
}
/**
* Triggers the onConfigLoaded event
*
* @param string $theme name of current theme
* @param int $themeApiVersion API version of the theme
* @param array &$themeConfig config array of the theme
*/
public function onThemeLoaded($theme, $themeApiVersion, array &$themeConfig)
{
$this->triggerEvent('onConfigLoaded', array(&$this->config));
}
/**
* {@inheritDoc}
*/
public function getApiVersion()
{
return PicoDeprecated::API_VERSION_3;
}
/**
* {@inheritDoc}
*/
public function getApiVersionSupport()
{
return PicoDeprecated::API_VERSION_2;
}
}

View File

@ -0,0 +1,52 @@
<?php
/**
* This file is part of Pico. It's copyrighted by the contributors recorded
* in the version control history of the file, available from the following
* original location:
*
* <https://github.com/picocms/pico-deprecated/blob/master/plugins/PicoThemeApi0CompatPlugin.php>
*
* This file was created by splitting up an original file into multiple files,
* which in turn was previously part of the project's main repository. The
* version control history of these files apply accordingly, available from
* the following original locations:
*
* <https://github.com/picocms/pico-deprecated/blob/90ea3d5a9767f1511f165e051dd7ffb8f1b3f92e/PicoDeprecated.php>
* <https://github.com/picocms/Pico/blob/82a342ba445122182b898a2c1800f03c8d16f18c/plugins/00-PicoDeprecated.php>
*
* SPDX-License-Identifier: MIT
* License-Filename: LICENSE
*/
/**
* Maintains backward compatibility with themes using API version 0, written
* for Pico 0.9 and earlier
*
* Since there were no theme-related changes between Pico 0.9 and Pico 1.0,
* this compat plugin doesn't hold any code itself, it just depends on
* {@see PicoThemeApi1CompatPlugin}. Since themes didn't support API versioning
* until Pico 2.1 (i.e. API version 3), all older themes will appear to use API
* version 0.
*
* @author Daniel Rudolf
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.1
*/
class PicoThemeApi0CompatPlugin extends AbstractPicoCompatPlugin
{
/**
* This plugin extends {@see PicoThemeApi1CompatPlugin}
*
* @var string[]
*/
protected $dependsOn = array('PicoThemeApi1CompatPlugin');
/**
* {@inheritDoc}
*/
public function getApiVersion()
{
return PicoDeprecated::API_VERSION_3;
}
}

View File

@ -0,0 +1,154 @@
<?php
/**
* This file is part of Pico. It's copyrighted by the contributors recorded
* in the version control history of the file, available from the following
* original location:
*
* <https://github.com/picocms/pico-deprecated/blob/master/plugins/PicoThemeApi1CompatPlugin.php>
*
* This file was created by splitting up an original file into multiple files,
* which in turn was previously part of the project's main repository. The
* version control history of these files apply accordingly, available from
* the following original locations:
*
* <https://github.com/picocms/pico-deprecated/blob/90ea3d5a9767f1511f165e051dd7ffb8f1b3f92e/PicoDeprecated.php>
* <https://github.com/picocms/Pico/blob/82a342ba445122182b898a2c1800f03c8d16f18c/plugins/00-PicoDeprecated.php>
*
* SPDX-License-Identifier: MIT
* License-Filename: LICENSE
*/
/**
* Maintains backward compatibility with themes using API version 1, written
* for Pico 1.0
*
* @author Daniel Rudolf
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.1
*/
class PicoThemeApi1CompatPlugin extends AbstractPicoCompatPlugin
{
/**
* This plugin extends {@see PicoThemeApi2CompatPlugin}
*
* @var string[]
*/
protected $dependsOn = array('PicoThemeApi2CompatPlugin');
/**
* Lowers the page's meta headers
*
* @see PicoThemeApi1CompatPlugin::lowerFileMeta()
*
* @param string[] &$meta parsed meta data
*/
public function onMetaParsed(array &$meta)
{
$this->lowerFileMeta($meta);
}
/**
* Lowers the page's meta headers
*
* @see PicoThemeApi1CompatPlugin::lowerFileMeta()
*
* @param array &$pageData data of the loaded page
*/
public function onSinglePageLoaded(array &$pageData)
{
// don't lower the file meta of the requested page,
// it was already lowered during the onMetaParsed event
$contentDir = $this->getPico()->getConfig('content_dir');
$contentExt = $this->getPico()->getConfig('content_ext');
if ($contentDir . $pageData['id'] . $contentExt !== $this->getPico()->getRequestFile()) {
$this->lowerFileMeta($pageData['meta']);
}
}
/**
* Handles .html Twig templates and re-introcudes the Twig variables
* rewrite_url and is_front_page
*
* @param string &$templateName file name of the template
* @param array &$twigVariables template variables
*/
public function onPageRendering(&$templateName, array &$twigVariables)
{
if (!isset($twigVariables['rewrite_url'])) {
$twigVariables['rewrite_url'] = $this->getPico()->isUrlRewritingEnabled();
}
if (!isset($twigVariables['is_front_page'])) {
$contentDir = $this->getPico()->getConfig('content_dir');
$contentExt = $this->getPico()->getConfig('content_ext');
$requestFile = $this->getPico()->getRequestFile();
$twigVariables['is_front_page'] = ($requestFile === $contentDir . 'index' . $contentExt);
}
// API v2 requires themes to use .twig as file extension
// try to load the template and if this fails, try .html instead (as of API v1)
$templateNameInfo = pathinfo($templateName) + array('extension' => '');
$twig = $this->getPico()->getTwig();
try {
$twig->loadTemplate($templateName);
} catch (Twig_Error_Loader $e) {
if ($templateNameInfo['extension'] === 'twig') {
try {
$twig->loadTemplate($templateNameInfo['filename'] . '.html');
$templateName = $templateNameInfo['filename'] . '.html';
$templateNameInfo['extension'] = 'html';
} catch (Twig_Error_Loader $e) {
// template doesn't exist, Twig will very likely fail later
}
}
}
}
/**
* Lowers a page's meta headers as with Pico 1.0 and older
*
* This makes unregistered meta headers available using lowered array keys
* and matches registered meta headers in a case-insensitive manner.
*
* @param array &$meta meta data
*/
protected function lowerFileMeta(array &$meta)
{
$metaHeaders = $this->getPico()->getMetaHeaders();
// get unregistered meta
$unregisteredMeta = array();
foreach ($meta as $key => $value) {
if (!in_array($key, $metaHeaders)) {
$unregisteredMeta[$key] = &$meta[$key];
}
}
// Pico 1.0 lowered unregistered meta unsolicited...
if ($unregisteredMeta) {
$metaHeadersLowered = array_change_key_case($metaHeaders, CASE_LOWER);
foreach ($unregisteredMeta as $key => $value) {
$keyLowered = strtolower($key);
if (isset($metaHeadersLowered[$keyLowered])) {
$registeredKey = $metaHeadersLowered[$keyLowered];
if ($meta[$registeredKey] === '') {
$meta[$registeredKey] = &$unregisteredMeta[$key];
}
} elseif (!isset($meta[$keyLowered]) || ($meta[$keyLowered] === '')) {
$meta[$keyLowered] = &$unregisteredMeta[$key];
}
}
}
}
/**
* {@inheritDoc}
*/
public function getApiVersion()
{
return PicoDeprecated::API_VERSION_3;
}
}

View File

@ -0,0 +1,205 @@
<?php
/**
* This file is part of Pico. It's copyrighted by the contributors recorded
* in the version control history of the file, available from the following
* original location:
*
* <https://github.com/picocms/pico-deprecated/blob/master/plugins/PicoThemeApi2CompatPlugin.php>
*
* This file was created by splitting up an original file into multiple files,
* which in turn was previously part of the project's main repository. The
* version control history of these files apply accordingly, available from
* the following original locations:
*
* <https://github.com/picocms/pico-deprecated/blob/90ea3d5a9767f1511f165e051dd7ffb8f1b3f92e/PicoDeprecated.php>
* <https://github.com/picocms/Pico/blob/82a342ba445122182b898a2c1800f03c8d16f18c/plugins/00-PicoDeprecated.php>
*
* SPDX-License-Identifier: MIT
* License-Filename: LICENSE
*/
/**
* Maintains backward compatibility with themes using API version 2, written
* for Pico 2.0
*
* @author Daniel Rudolf
* @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License
* @version 2.1
*/
class PicoThemeApi2CompatPlugin extends AbstractPicoCompatPlugin
{
/**
* Manually configured Twig escape strategy
*
* @var mixed|null
*/
protected $twigEscapeStrategy;
/**
* Directory paths of plugins
*
* @var string[]
*/
protected $pluginPaths = array();
/**
* Sets PicoThemeApi2CompatPlugin::$twigEscapeStrategy
*
* @see PicoThemeApi2CompatPlugin::$twigEscapeStrategy
*
* @param array &$config array of config variables
*/
public function onConfigLoaded(array &$config)
{
if (isset($config['twig_config']['autoescape'])) {
$this->twigEscapeStrategy = $config['twig_config']['autoescape'];
}
}
/**
* Re-introduces the Twig variables prev_page, base_dir and theme_dir
*
* @param string &$templateName file name of the template
* @param array &$twigVariables template variables
*/
public function onPageRendering(&$templateName, array &$twigVariables)
{
$twigVariables['prev_page'] = &$twigVariables['previous_page'];
$twigVariables['base_dir'] = rtrim($this->getPico()->getRootDir(), '/');
$twigVariables['theme_dir'] = $this->getPico()->getThemesDir() . $this->getPico()->getTheme();
}
/**
* Registers PicoPluginApi2CompatPlugin::twigEscapeStrategy() as Twig's
* default escape strategy
*
* @see PicoPluginApi2CompatPlugin::twigEscapeStrategy()
*
* @param Twig_Environment &$twig Twig instance
*/
public function onTwigRegistered(Twig_Environment &$twig)
{
if ($twig->hasExtension('Twig_Extension_Escaper')) {
/** @var Twig_Extension_Escaper $escaperExtension */
$escaperExtension = $twig->getExtension('Twig_Extension_Escaper');
$escaperExtension->setDefaultStrategy(array($this, 'twigEscapeStrategy'));
}
}
/**
* Returns Twig's default escaping strategy for the given template
*
* This escape strategy takes a template name and decides whether Twig's
* global default escape strategy should be used, or escaping should be
* disabled. Escaping is disabled for themes using API v2 and below as well
* as for templates of plugins using API v2 and below. If a escape strategy
* has been configured manually, this method always returns this explicitly
* configured escape strategy.
*
* @param string $templateName template name
*
* @return string|false escape strategy for this template
*/
public function twigEscapeStrategy($templateName)
{
$twigConfig = $this->getPico()->getConfig('twig_config');
$escapeStrategy = $twigConfig['autoescape'];
if (($this->twigEscapeStrategy !== null) && ($escapeStrategy === $this->twigEscapeStrategy)) {
return $escapeStrategy;
}
if (!is_string($escapeStrategy) && ($escapeStrategy !== false)) {
$escapeStrategy = call_user_func($escapeStrategy, $templateName);
}
if ($escapeStrategy === false) {
return false;
}
/** @var Twig_SourceContextLoaderInterface $twigLoader */
$twigLoader = $this->getPico()->getTwig()->getLoader();
if (!$twigLoader instanceof Twig_SourceContextLoaderInterface) {
throw new RuntimeException(
"PicoDeprecated compat plugin '" . __CLASS__ . "' requires a 'Twig_SourceContextLoaderInterface' "
. "Twig loader, '" . get_class($twigLoader) . "' given"
);
}
try {
$templatePath = $twigLoader->getSourceContext($templateName)->getPath();
} catch (\Twig\Error\LoaderError $e) {
$templatePath = '';
}
if ($templatePath) {
$themePath = realpath($this->getPico()->getThemesDir() . $this->getPico()->getTheme()) . '/';
if (substr($templatePath, 0, strlen($themePath)) === $themePath) {
$themeApiVersion = $this->getPico()->getThemeApiVersion();
return ($themeApiVersion >= PicoDeprecated::API_VERSION_3) ? $escapeStrategy : false;
}
$plugin = $this->getPluginFromPath($templatePath);
if ($plugin) {
$pluginApiVersion = $this->getPicoDeprecated()->getPluginApiVersion($plugin);
return ($pluginApiVersion >= PicoDeprecated::API_VERSION_3) ? $escapeStrategy : false;
}
}
// unknown template path
// to preserve BC we must assume that the template uses an old API version
return false;
}
/**
* Returns the matching plugin instance when the given path is within a
* plugin's base directory
*
* @param string $path file path to search for
*
* @return object|null either the matching plugin instance or NULL
*/
protected function getPluginFromPath($path)
{
$plugins = $this->getPico()->getPlugins();
foreach ($this->pluginPaths as $pluginName => $pluginPath) {
if ($pluginPath && (substr($path, 0, strlen($pluginPath)) === $pluginPath)) {
return $plugins[$pluginName];
}
}
$rootDir = realpath($this->getPico()->getRootDir()) . '/';
$vendorDir = realpath($this->getPico()->getVendorDir()) . '/';
$pluginsDir = realpath($this->getPico()->getPluginsDir()) . '/';
$themesDir = realpath($this->getPico()->getThemesDir()) . '/';
foreach ($plugins as $pluginName => $plugin) {
if (isset($this->pluginPaths[$pluginName])) {
continue;
}
$pluginReflector = new ReflectionObject($plugin);
$pluginPath = dirname($pluginReflector->getFileName() ?: '') . '/';
if (in_array($pluginPath, array('/', $rootDir, $vendorDir, $pluginsDir, $themesDir), true)) {
$pluginPath = '';
}
$this->pluginPaths[$pluginName] = $pluginPath;
if ($pluginPath && (substr($path, 0, strlen($pluginPath)) === $pluginPath)) {
return $plugins[$pluginName];
}
}
return null;
}
/**
* {@inheritDoc}
*/
public function getApiVersion()
{
return PicoDeprecated::API_VERSION_3;
}
}

View File

@ -1,2 +0,0 @@
vendor/
composer.lock

View File

@ -1,16 +0,0 @@
# Linux
*~
*.swp
# Windows
Thumbs.db
desktop.ini
# Mac OS X
.DS_Store
._*
# Composer
/composer.lock
/composer.phar
/vendor

View File

@ -1,3 +0,0 @@
vendor/
composer.lock
phpunit.xml

View File

@ -1,5 +0,0 @@
/build
/composer.lock
/ext/twig/autom4te.cache/
/phpunit.xml
/vendor

View File

@ -1,30 +0,0 @@
*.sw*
.deps
Makefile
Makefile.fragments
Makefile.global
Makefile.objects
acinclude.m4
aclocal.m4
build/
config.cache
config.guess
config.h
config.h.in
config.log
config.nice
config.status
config.sub
configure
configure.in
install-sh
libtool
ltmain.sh
missing
mkinstalldirs
run-tests.php
twig.loT
.libs/
modules/
twig.la
twig.lo