Move Pico to picocms\Pico\ namespace

This commit is contained in:
Daniel Rudolf 2020-04-10 21:09:00 +02:00
parent 039dd4edb2
commit 812ae5c215
No known key found for this signature in database
GPG Key ID: A061F02CD8DE4538
8 changed files with 140 additions and 131 deletions

View File

@ -43,10 +43,8 @@
"picocms/composer-installer": "This Composer plugin is responsible for installing Pico plugins and themes using the Composer package manager." "picocms/composer-installer": "This Composer plugin is responsible for installing Pico plugins and themes using the Composer package manager."
}, },
"autoload": { "autoload": {
"psr-0": { "psr-4": {
"Pico": "lib/", "picocms\\Pico\\": "lib/"
"PicoPluginInterface": "lib/",
"AbstractPicoPlugin": "lib/"
} }
}, },
"extra": { "extra": {

View File

@ -26,7 +26,7 @@ if (is_file(__DIR__ . '/vendor/autoload.php')) {
} }
// instance Pico // instance Pico
$pico = new Pico( $pico = new \picocms\Pico\Pico(
__DIR__, // root dir __DIR__, // root dir
'config/', // config dir 'config/', // config dir
'plugins/', // plugins dir 'plugins/', // plugins dir

View File

@ -25,7 +25,7 @@ if (!extension_loaded('mbstring')) {
require_once(__DIR__ . '/vendor/autoload.php'); require_once(__DIR__ . '/vendor/autoload.php');
// instance Pico // instance Pico
$pico = new Pico( $pico = new \picocms\Pico\Pico(
__DIR__, // root dir __DIR__, // root dir
'config/', // config dir 'config/', // config dir
'plugins/', // plugins dir 'plugins/', // plugins dir

View File

@ -10,25 +10,27 @@
* License-Filename: LICENSE * License-Filename: LICENSE
*/ */
namespace picocms\Pico;
/** /**
* Abstract class to extend from when implementing a Pico plugin * Abstract class to extend from when implementing a Pico plugin
* *
* Please refer to {@see PicoPluginInterface} for more information about how * Please refer to {@see PluginInterface} for more information about how to
* to develop a plugin for Pico. * develop a plugin for Pico.
* *
* @see PicoPluginInterface * @see PluginInterface
* *
* @author Daniel Rudolf * @author Daniel Rudolf
* @link http://picocms.org * @link http://picocms.org
* @license http://opensource.org/licenses/MIT The MIT License * @license http://opensource.org/licenses/MIT The MIT License
* @version 3.0 * @version 3.0
*/ */
abstract class AbstractPicoPlugin implements PicoPluginInterface abstract class AbstractPlugin implements PluginInterface
{ {
/** /**
* Current instance of Pico * Current instance of Pico
* *
* @see PicoPluginInterface::getPico() * @see PluginInterface::getPico()
* @var Pico * @var Pico
*/ */
protected $pico; protected $pico;
@ -36,8 +38,8 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
/** /**
* Boolean indicating if this plugin is enabled (TRUE) or disabled (FALSE) * Boolean indicating if this plugin is enabled (TRUE) or disabled (FALSE)
* *
* @see PicoPluginInterface::isEnabled() * @see PluginInterface::isEnabled()
* @see PicoPluginInterface::setEnabled() * @see PluginInterface::setEnabled()
* @var bool|null * @var bool|null
*/ */
protected $enabled; protected $enabled;
@ -45,7 +47,7 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
/** /**
* Boolean indicating if this plugin was ever enabled/disabled manually * Boolean indicating if this plugin was ever enabled/disabled manually
* *
* @see PicoPluginInterface::isStatusChanged() * @see PluginInterface::isStatusChanged()
* @var bool * @var bool
*/ */
protected $statusChanged = false; protected $statusChanged = false;
@ -53,7 +55,7 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
/** /**
* Boolean indicating whether this plugin matches Pico's API version * Boolean indicating whether this plugin matches Pico's API version
* *
* @see AbstractPicoPlugin::checkCompatibility() * @see AbstractPlugin::checkCompatibility()
* @var bool|null * @var bool|null
*/ */
protected $nativePlugin; protected $nativePlugin;
@ -61,8 +63,8 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
/** /**
* List of plugins which this plugin depends on * List of plugins which this plugin depends on
* *
* @see AbstractPicoPlugin::checkDependencies() * @see AbstractPlugin::checkDependencies()
* @see PicoPluginInterface::getDependencies() * @see PluginInterface::getDependencies()
* @var string[] * @var string[]
*/ */
protected $dependsOn = array(); protected $dependsOn = array();
@ -70,8 +72,8 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
/** /**
* List of plugin which depend on this plugin * List of plugin which depend on this plugin
* *
* @see AbstractPicoPlugin::checkDependants() * @see AbstractPlugin::checkDependants()
* @see PicoPluginInterface::getDependants() * @see PluginInterface::getDependants()
* @var object[]|null * @var object[]|null
*/ */
protected $dependants; protected $dependants;
@ -122,7 +124,7 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
// otherwise the plugin needs to be enabled manually // otherwise the plugin needs to be enabled manually
try { try {
$this->setEnabled(true, false, true); $this->setEnabled(true, false, true);
} catch (RuntimeException $e) { } catch (\RuntimeException $e) {
$this->enabled = false; $this->enabled = false;
} }
} }
@ -196,7 +198,7 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
/** /**
* Passes all not satisfiable method calls to Pico * Passes all not satisfiable method calls to Pico
* *
* @see PicoPluginInterface::getPico() * @see PluginInterface::getPico()
* *
* @deprecated 2.1.0 * @deprecated 2.1.0
* *
@ -211,7 +213,7 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
return call_user_func_array(array($this->getPico(), $methodName), $params); return call_user_func_array(array($this->getPico(), $methodName), $params);
} }
throw new BadMethodCallException( throw new \BadMethodCallException(
'Call to undefined method ' . get_class($this->getPico()) . '::' . $methodName . '() ' 'Call to undefined method ' . get_class($this->getPico()) . '::' . $methodName . '() '
. 'through ' . get_called_class() . '::__call()' . 'through ' . get_called_class() . '::__call()'
); );
@ -220,37 +222,37 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
/** /**
* Enables all plugins which this plugin depends on * Enables all plugins which this plugin depends on
* *
* @see PicoPluginInterface::getDependencies() * @see PluginInterface::getDependencies()
* *
* @param bool $recursive enable required plugins automatically * @param bool $recursive enable required plugins automatically
* *
* @throws RuntimeException thrown when a dependency fails * @throws \RuntimeException thrown when a dependency fails
*/ */
protected function checkDependencies($recursive) protected function checkDependencies($recursive)
{ {
foreach ($this->getDependencies() as $pluginName) { foreach ($this->getDependencies() as $pluginName) {
try { try {
$plugin = $this->getPico()->getPlugin($pluginName); $plugin = $this->getPico()->getPlugin($pluginName);
} catch (RuntimeException $e) { } catch (\RuntimeException $e) {
throw new RuntimeException( throw new \RuntimeException(
"Unable to enable plugin '" . get_called_class() . "': " "Unable to enable plugin '" . get_called_class() . "': "
. "Required plugin '" . $pluginName . "' not found" . "Required plugin '" . $pluginName . "' not found"
); );
} }
// plugins which don't implement PicoPluginInterface are always enabled // plugins which don't implement PicoPluginInterface are always enabled
if (($plugin instanceof PicoPluginInterface) && !$plugin->isEnabled()) { if (($plugin instanceof PluginInterface) && !$plugin->isEnabled()) {
if ($recursive) { if ($recursive) {
if (!$plugin->isStatusChanged()) { if (!$plugin->isStatusChanged()) {
$plugin->setEnabled(true, true, true); $plugin->setEnabled(true, true, true);
} else { } else {
throw new RuntimeException( throw new \RuntimeException(
"Unable to enable plugin '" . get_called_class() . "': " "Unable to enable plugin '" . get_called_class() . "': "
. "Required plugin '" . $pluginName . "' was disabled manually" . "Required plugin '" . $pluginName . "' was disabled manually"
); );
} }
} else { } else {
throw new RuntimeException( throw new \RuntimeException(
"Unable to enable plugin '" . get_called_class() . "': " "Unable to enable plugin '" . get_called_class() . "': "
. "Required plugin '" . $pluginName . "' is disabled" . "Required plugin '" . $pluginName . "' is disabled"
); );
@ -270,11 +272,11 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
/** /**
* Disables all plugins which depend on this plugin * Disables all plugins which depend on this plugin
* *
* @see PicoPluginInterface::getDependants() * @see PluginInterface::getDependants()
* *
* @param bool $recursive disabled dependant plugins automatically * @param bool $recursive disabled dependant plugins automatically
* *
* @throws RuntimeException thrown when a dependency fails * @throws \RuntimeException thrown when a dependency fails
*/ */
protected function checkDependants($recursive) protected function checkDependants($recursive)
{ {
@ -286,7 +288,7 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
if (!$plugin->isStatusChanged()) { if (!$plugin->isStatusChanged()) {
$plugin->setEnabled(false, true, true); $plugin->setEnabled(false, true, true);
} else { } else {
throw new RuntimeException( throw new \RuntimeException(
"Unable to disable plugin '" . get_called_class() . "': " "Unable to disable plugin '" . get_called_class() . "': "
. "Required by manually enabled plugin '" . $pluginName . "'" . "Required by manually enabled plugin '" . $pluginName . "'"
); );
@ -296,7 +298,7 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
} else { } else {
$dependantsList = 'plugin' . ((count($dependants) > 1) ? 's' : '') . ' ' $dependantsList = 'plugin' . ((count($dependants) > 1) ? 's' : '') . ' '
. "'" . implode("', '", array_keys($dependants)) . "'"; . "'" . implode("', '", array_keys($dependants)) . "'";
throw new RuntimeException( throw new \RuntimeException(
"Unable to disable plugin '" . get_called_class() . "': " "Unable to disable plugin '" . get_called_class() . "': "
. "Required by " . $dependantsList . "Required by " . $dependantsList
); );
@ -313,7 +315,7 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
$this->dependants = array(); $this->dependants = array();
foreach ($this->getPico()->getPlugins() as $pluginName => $plugin) { foreach ($this->getPico()->getPlugins() as $pluginName => $plugin) {
// only plugins which implement PicoPluginInterface support dependencies // only plugins which implement PicoPluginInterface support dependencies
if ($plugin instanceof PicoPluginInterface) { if ($plugin instanceof PluginInterface) {
$dependencies = $plugin->getDependencies(); $dependencies = $plugin->getDependencies();
if (in_array(get_called_class(), $dependencies)) { if (in_array(get_called_class(), $dependencies)) {
$this->dependants[$pluginName] = $plugin; $this->dependants[$pluginName] = $plugin;
@ -335,7 +337,7 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
* newer API versions, what requires some special (version specific) * newer API versions, what requires some special (version specific)
* precaution and is therefore usually not the case. * precaution and is therefore usually not the case.
* *
* @throws RuntimeException thrown when the plugin's and Pico's API aren't * @throws \RuntimeException thrown when the plugin's and Pico's API aren't
* compatible * compatible
*/ */
protected function checkCompatibility() protected function checkCompatibility()
@ -348,7 +350,7 @@ abstract class AbstractPicoPlugin implements PicoPluginInterface
$this->nativePlugin = ($pluginApiVersion === $picoApiVersion); $this->nativePlugin = ($pluginApiVersion === $picoApiVersion);
if (!$this->nativePlugin && ($pluginApiVersion > $picoApiVersion)) { if (!$this->nativePlugin && ($pluginApiVersion > $picoApiVersion)) {
throw new RuntimeException( throw new \RuntimeException(
"Unable to enable plugin '" . get_called_class() . "': The plugin's API (version " "Unable to enable plugin '" . get_called_class() . "': The plugin's API (version "
. $pluginApiVersion . ") isn't compatible with Pico's API (version " . $picoApiVersion . ")" . $pluginApiVersion . ") isn't compatible with Pico's API (version " . $picoApiVersion . ")"
); );

View File

@ -16,6 +16,8 @@
* License-Filename: LICENSE * License-Filename: LICENSE
*/ */
namespace picocms\Pico;
/** /**
* Pico * Pico
* *
@ -147,7 +149,7 @@ class Pico
/** /**
* List of loaded plugins using the current API version * List of loaded plugins using the current API version
* *
* @var PicoPluginInterface[] * @var PluginInterface[]
*/ */
protected $nativePlugins = array(); protected $nativePlugins = array();
@ -251,7 +253,7 @@ class Pico
* Parsedown Extra instance used for markdown parsing * Parsedown Extra instance used for markdown parsing
* *
* @see Pico::getParsedown() * @see Pico::getParsedown()
* @var Parsedown|null * @var \Parsedown|null
*/ */
protected $parsedown; protected $parsedown;
@ -307,7 +309,7 @@ class Pico
* Twig instance used for template parsing * Twig instance used for template parsing
* *
* @see Pico::getTwig() * @see Pico::getTwig()
* @var Twig_Environment|null * @var \Twig_Environment|null
*/ */
protected $twig; protected $twig;
@ -408,13 +410,13 @@ class Pico
* *
* @return string rendered Pico contents * @return string rendered Pico contents
* *
* @throws Exception thrown when a irrecoverable error occurs * @throws \Exception thrown when a irrecoverable error occurs
*/ */
public function run() public function run()
{ {
// check lock // check lock
if ($this->locked) { if ($this->locked) {
throw new LogicException('You cannot run the same Pico instance multiple times'); throw new \LogicException('You cannot run the same Pico instance multiple times');
} }
// lock Pico // lock Pico
@ -431,7 +433,7 @@ class Pico
// check content dir // check content dir
if (!is_dir($this->getConfig('content_dir'))) { if (!is_dir($this->getConfig('content_dir'))) {
throw new RuntimeException('Invalid content directory "' . $this->getConfig('content_dir') . '"'); throw new \RuntimeException('Invalid content directory "' . $this->getConfig('content_dir') . '"');
} }
// load theme // load theme
@ -542,7 +544,7 @@ class Pico
* @see Pico::getPlugin() * @see Pico::getPlugin()
* @see Pico::getPlugins() * @see Pico::getPlugins()
* *
* @throws RuntimeException thrown when a plugin couldn't be loaded * @throws \RuntimeException thrown when a plugin couldn't be loaded
*/ */
protected function loadPlugins() protected function loadPlugins()
{ {
@ -553,7 +555,7 @@ class Pico
} }
if (!isset($this->plugins['PicoDeprecated']) && (count($this->plugins) !== count($this->nativePlugins))) { if (!isset($this->plugins['PicoDeprecated']) && (count($this->plugins) !== count($this->nativePlugins))) {
throw new RuntimeException( throw new \RuntimeException(
"Plugins using an older API than version " . static::API_VERSION . " found, " "Plugins using an older API than version " . static::API_VERSION . " found, "
. "but PicoDeprecated isn't loaded" . "but PicoDeprecated isn't loaded"
); );
@ -574,7 +576,7 @@ class Pico
* *
* @return string[] installer names of the loaded plugins * @return string[] installer names of the loaded plugins
* *
* @throws RuntimeException thrown when a plugin couldn't be loaded * @throws \RuntimeException thrown when a plugin couldn't be loaded
*/ */
protected function loadComposerPlugins(array $pluginBlacklist = array()) protected function loadComposerPlugins(array $pluginBlacklist = array())
{ {
@ -601,8 +603,8 @@ class Pico
continue; continue;
} }
if (!($plugin instanceof PicoPluginInterface)) { if (!($plugin instanceof PluginInterface)) {
throw new RuntimeException( throw new \RuntimeException(
"Unable to load plugin '" . $className . "' via 'vendor/pico-plugin.php': " "Unable to load plugin '" . $className . "' via 'vendor/pico-plugin.php': "
. "Plugins installed by composer must implement 'PicoPluginInterface'" . "Plugins installed by composer must implement 'PicoPluginInterface'"
); );
@ -642,7 +644,7 @@ class Pico
* *
* @param string[] $pluginBlacklist class names of plugins not to load * @param string[] $pluginBlacklist class names of plugins not to load
* *
* @throws RuntimeException thrown when a plugin couldn't be loaded * @throws \RuntimeException thrown when a plugin couldn't be loaded
*/ */
protected function loadLocalPlugins(array $pluginBlacklist = array()) protected function loadLocalPlugins(array $pluginBlacklist = array())
{ {
@ -668,7 +670,7 @@ class Pico
$pluginFile = $file . '/' . $className . '.php'; $pluginFile = $file . '/' . $className . '.php';
if (!is_file($this->getPluginsDir() . $pluginFile)) { if (!is_file($this->getPluginsDir() . $pluginFile)) {
throw new RuntimeException( throw new \RuntimeException(
"Unable to load plugin '" . $className . "' from '" . $pluginFile . "': File not found" "Unable to load plugin '" . $className . "' from '" . $pluginFile . "': File not found"
); );
} }
@ -676,7 +678,7 @@ class Pico
$className = preg_replace('/^[0-9]+-/', '', substr($file, 0, -4)); $className = preg_replace('/^[0-9]+-/', '', substr($file, 0, -4));
$pluginFile = $file; $pluginFile = $file;
} else { } else {
throw new RuntimeException("Unable to load plugin from '" . $file . "': Not a valid plugin file"); throw new \RuntimeException("Unable to load plugin from '" . $file . "': Not a valid plugin file");
} }
if (isset($this->plugins[$className]) || isset($pluginBlacklist[$className])) { if (isset($this->plugins[$className]) || isset($pluginBlacklist[$className])) {
@ -692,13 +694,13 @@ class Pico
$this->plugins[$className] = $plugin; $this->plugins[$className] = $plugin;
if ($plugin instanceof PicoPluginInterface) { if ($plugin instanceof PluginInterface) {
if (defined($className . '::API_VERSION') && ($className::API_VERSION >= static::API_VERSION)) { if (defined($className . '::API_VERSION') && ($className::API_VERSION >= static::API_VERSION)) {
$this->nativePlugins[$className] = $plugin; $this->nativePlugins[$className] = $plugin;
} }
} }
} else { } else {
throw new RuntimeException( throw new \RuntimeException(
"Unable to load plugin '" . $className . "' from '" . $pluginFile . "': Plugin class not found" "Unable to load plugin '" . $className . "' from '" . $pluginFile . "': Plugin class not found"
); );
} }
@ -708,11 +710,11 @@ class Pico
/** /**
* Manually loads a plugin * Manually loads a plugin
* *
* Manually loaded plugins MUST implement {@see PicoPluginInterface}. They * Manually loaded plugins MUST implement {@see PluginInterface}. They are
* are simply appended to the plugins array without any additional checks, * simply appended to the plugins array without any additional checks, so
* so you might get unexpected results, depending on *when* you're loading * you might get unexpected results, depending on *when* you're loading a
* a plugin. You SHOULD NOT load plugins after a event has been triggered * plugin. You SHOULD NOT load plugins after a event has been triggered by
* by Pico. In-depth knowledge of Pico's inner workings is strongly advised * Pico. In-depth knowledge of Pico's inner workings is strongly advised
* otherwise, and you MUST NOT rely on {@see PicoDeprecated} to maintain * otherwise, and you MUST NOT rely on {@see PicoDeprecated} to maintain
* backward compatibility in such cases. * backward compatibility in such cases.
* *
@ -730,12 +732,12 @@ class Pico
* @see Pico::getPlugin() * @see Pico::getPlugin()
* @see Pico::getPlugins() * @see Pico::getPlugins()
* *
* @param PicoPluginInterface|string $plugin either the class name of a * @param PluginInterface|string $plugin either the class name of a plugin
* plugin to instantiate or a plugin instance * to instantiate or a plugin instance
* *
* @return PicoPluginInterface instance of the loaded plugin * @return PluginInterface instance of the loaded plugin
* *
* @throws RuntimeException thrown when the plugin couldn't be loaded * @throws \RuntimeException thrown when the plugin couldn't be loaded
*/ */
public function loadPlugin($plugin) public function loadPlugin($plugin)
{ {
@ -744,14 +746,14 @@ class Pico
if (class_exists($className)) { if (class_exists($className)) {
$plugin = new $className($this); $plugin = new $className($this);
} else { } else {
throw new RuntimeException("Unable to load plugin '" . $className . "': Class not found"); throw new \RuntimeException("Unable to load plugin '" . $className . "': Class not found");
} }
} }
$className = get_class($plugin); $className = get_class($plugin);
if (!($plugin instanceof PicoPluginInterface)) { if (!($plugin instanceof PluginInterface)) {
throw new RuntimeException( throw new \RuntimeException(
"Unable to load plugin '" . $className . "': " "Unable to load plugin '" . $className . "': "
. "Manually loaded plugins must implement 'PicoPluginInterface'" . "Manually loaded plugins must implement 'PicoPluginInterface'"
); );
@ -820,7 +822,7 @@ class Pico
$visitedPlugins[$pluginName] = true; $visitedPlugins[$pluginName] = true;
$dependencies = array(); $dependencies = array();
if ($plugin instanceof PicoPluginInterface) { if ($plugin instanceof PluginInterface) {
$dependencies = $plugin->getDependencies(); $dependencies = $plugin->getDependencies();
} }
if (!isset($nativePlugins[$pluginName])) { if (!isset($nativePlugins[$pluginName])) {
@ -857,8 +859,8 @@ class Pico
/** /**
* Returns the instance of a named plugin * Returns the instance of a named plugin
* *
* Plugins SHOULD implement {@see PicoPluginInterface}, but you MUST NOT * Plugins SHOULD implement {@see PluginInterface}, but you MUST NOT rely
* rely on it. For more information see {@see PicoPluginInterface}. * on it. For more information see {@see PluginInterface}.
* *
* @see Pico::loadPlugins() * @see Pico::loadPlugins()
* @see Pico::getPlugins() * @see Pico::getPlugins()
@ -867,7 +869,7 @@ class Pico
* *
* @return object instance of the plugin * @return object instance of the plugin
* *
* @throws RuntimeException thrown when the plugin wasn't found * @throws \RuntimeException thrown when the plugin wasn't found
*/ */
public function getPlugin($pluginName) public function getPlugin($pluginName)
{ {
@ -875,7 +877,7 @@ class Pico
return $this->plugins[$pluginName]; return $this->plugins[$pluginName];
} }
throw new RuntimeException("Missing plugin '" . $pluginName . "'"); throw new \RuntimeException("Missing plugin '" . $pluginName . "'");
} }
/** /**
@ -1035,12 +1037,12 @@ class Pico
* *
* @param array $config array with config variables * @param array $config array with config variables
* *
* @throws LogicException thrown if Pico already started processing * @throws \LogicException thrown if Pico already started processing
*/ */
public function setConfig(array $config) public function setConfig(array $config)
{ {
if ($this->locked) { if ($this->locked) {
throw new LogicException("You cannot modify Pico's config after processing has started"); throw new \LogicException("You cannot modify Pico's config after processing has started");
} }
$this->config = $config; $this->config = $config;
@ -1141,7 +1143,7 @@ class Pico
// check for theme compatibility // check for theme compatibility
if (!isset($this->plugins['PicoDeprecated']) && ($this->themeApiVersion < static::API_VERSION)) { if (!isset($this->plugins['PicoDeprecated']) && ($this->themeApiVersion < static::API_VERSION)) {
throw new RuntimeException( throw new \RuntimeException(
'Current theme "' . $this->theme . '" uses API version ' . $this->themeApiVersion . ', but Pico ' 'Current theme "' . $this->theme . '" uses API version ' . $this->themeApiVersion . ', but Pico '
. 'provides API version ' . static::API_VERSION . ' and PicoDeprecated isn\'t loaded' . 'provides API version ' . static::API_VERSION . ' and PicoDeprecated isn\'t loaded'
); );
@ -1542,12 +1544,12 @@ class Pico
* This method triggers the `onParsedownRegistered` event when the * This method triggers the `onParsedownRegistered` event when the
* Parsedown markdown parser wasn't initiated yet. * Parsedown markdown parser wasn't initiated yet.
* *
* @return Parsedown Parsedown markdown parser * @return \Parsedown Parsedown markdown parser
*/ */
public function getParsedown() public function getParsedown()
{ {
if ($this->parsedown === null) { if ($this->parsedown === null) {
$className = $this->config['content_config']['extra'] ? 'ParsedownExtra' : 'Parsedown'; $className = $this->config['content_config']['extra'] ? '\ParsedownExtra' : '\Parsedown';
$this->parsedown = new $className(); $this->parsedown = new $className();
$this->parsedown->setBreaksEnabled((bool) $this->config['content_config']['breaks']); $this->parsedown->setBreaksEnabled((bool) $this->config['content_config']['breaks']);
@ -2075,25 +2077,25 @@ class Pico
* This method triggers the `onTwigRegistered` event when the Twig template * This method triggers the `onTwigRegistered` event when the Twig template
* engine wasn't initiated yet. When initiating Twig, this method also * engine wasn't initiated yet. When initiating Twig, this method also
* registers Pico's core Twig filter `content` as well as Pico's * registers Pico's core Twig filter `content` as well as Pico's
* {@see PicoTwigExtension} Twig extension. * {@see TwigExtension} Twig extension.
* *
* @see Pico::getTwig() * @see Pico::getTwig()
* @see http://twig.sensiolabs.org/ Twig website * @see http://twig.sensiolabs.org/ Twig website
* @see https://github.com/twigphp/Twig Twig on GitHub * @see https://github.com/twigphp/Twig Twig on GitHub
* *
* @return Twig_Environment|null Twig template engine * @return \Twig_Environment|null Twig template engine
*/ */
public function getTwig() public function getTwig()
{ {
if ($this->twig === null) { if ($this->twig === null) {
$twigConfig = $this->getConfig('twig_config'); $twigConfig = $this->getConfig('twig_config');
$twigLoader = new Twig_Loader_Filesystem($this->getThemesDir() . $this->getTheme()); $twigLoader = new \Twig_Loader_Filesystem($this->getThemesDir() . $this->getTheme());
$this->twig = new Twig_Environment($twigLoader, $twigConfig); $this->twig = new \Twig_Environment($twigLoader, $twigConfig);
$this->twig->addExtension(new PicoTwigExtension($this)); $this->twig->addExtension(new TwigExtension($this));
if (!empty($twigConfig['debug'])) { if (!empty($twigConfig['debug'])) {
$this->twig->addExtension(new Twig_Extension_Debug()); $this->twig->addExtension(new \Twig_Extension_Debug());
} }
// register content filter // register content filter
@ -2101,7 +2103,7 @@ class Pico
// this is the reason why we can't register this filter as part of PicoTwigExtension // this is the reason why we can't register this filter as part of PicoTwigExtension
$pico = $this; $pico = $this;
$pages = &$this->pages; $pages = &$this->pages;
$this->twig->addFilter(new Twig_SimpleFilter( $this->twig->addFilter(new \Twig_SimpleFilter(
'content', 'content',
function ($page) use ($pico, &$pages) { function ($page) use ($pico, &$pages) {
if (isset($pages[$page])) { if (isset($pages[$page])) {
@ -2142,7 +2144,7 @@ class Pico
'theme_url' => $this->getConfig('themes_url') . $this->getTheme(), 'theme_url' => $this->getConfig('themes_url') . $this->getTheme(),
'site_title' => $this->getConfig('site_title'), 'site_title' => $this->getConfig('site_title'),
'meta' => $this->meta, 'meta' => $this->meta,
'content' => new Twig_Markup($this->content, 'UTF-8'), 'content' => new \Twig_Markup($this->content, 'UTF-8'),
'pages' => $this->pages, 'pages' => $this->pages,
'previous_page' => $this->previousPage, 'previous_page' => $this->previousPage,
'current_page' => $this->currentPage, 'current_page' => $this->currentPage,
@ -2281,14 +2283,14 @@ class Pico
* *
* @return string URL * @return string URL
* *
* @throws InvalidArgumentException thrown when invalid arguments got passed * @throws \InvalidArgumentException thrown when invalid arguments got passed
*/ */
public function getPageUrl($page, $queryData = null, $dropIndex = true) public function getPageUrl($page, $queryData = null, $dropIndex = true)
{ {
if (is_array($queryData)) { if (is_array($queryData)) {
$queryData = http_build_query($queryData, '', '&'); $queryData = http_build_query($queryData, '', '&');
} elseif (($queryData !== null) && !is_string($queryData)) { } elseif (($queryData !== null) && !is_string($queryData)) {
throw new InvalidArgumentException( throw new \InvalidArgumentException(
'Argument 2 passed to ' . __METHOD__ . ' must be of the type array or string, ' 'Argument 2 passed to ' . __METHOD__ . ' must be of the type array or string, '
. (is_object($queryData) ? get_class($queryData) : gettype($queryData)) . ' given' . (is_object($queryData) ? get_class($queryData) : gettype($queryData)) . ' given'
); );
@ -2682,7 +2684,7 @@ class Pico
* *
* @return string normalized path * @return string normalized path
* *
* @throws UnexpectedValueException thrown when a absolute path is passed * @throws \UnexpectedValueException thrown when a absolute path is passed
* although absolute paths aren't allowed * although absolute paths aren't allowed
*/ */
public function getNormalizedPath($path, $allowAbsolutePath = false, $endSlash = true) public function getNormalizedPath($path, $allowAbsolutePath = false, $endSlash = true)
@ -2701,7 +2703,7 @@ class Pico
} }
if ($absolutePath && !$allowAbsolutePath) { if ($absolutePath && !$allowAbsolutePath) {
throw new UnexpectedValueException( throw new \UnexpectedValueException(
'Argument 1 passed to ' . __METHOD__ . ' must be a relative path, absolute path "' . $path . '" given' 'Argument 1 passed to ' . __METHOD__ . ' must be a relative path, absolute path "' . $path . '" given'
); );
} }
@ -2736,7 +2738,7 @@ class Pico
* @param string $url relative or absolute URL * @param string $url relative or absolute URL
* @param string $baseUrl treat relative URLs relative to the given URL; * @param string $baseUrl treat relative URLs relative to the given URL;
* defaults to Pico::getBaseUrl() * defaults to Pico::getBaseUrl()
* @param bool $endSlash whether to add a trailing slash to the absolute * @param bool $endSlash whether to add a trailing slash to the absolute
* URL or not (defaults to TRUE) * URL or not (defaults to TRUE)
* *
* @return string absolute URL * @return string absolute URL
@ -2761,8 +2763,8 @@ class Pico
* *
* You MUST NOT trigger events of Pico's core with a plugin! * You MUST NOT trigger events of Pico's core with a plugin!
* *
* @see PicoPluginInterface * @see PluginInterface
* @see AbstractPicoPlugin * @see AbstractPlugin
* @see DummyPlugin * @see DummyPlugin
* *
* @param string $eventName name of the event to trigger * @param string $eventName name of the event to trigger

View File

@ -10,6 +10,8 @@
* License-Filename: LICENSE * License-Filename: LICENSE
*/ */
namespace picocms\Pico;
/** /**
* Common interface for Pico plugins * Common interface for Pico plugins
* *
@ -28,7 +30,7 @@
* @license http://opensource.org/licenses/MIT The MIT License * @license http://opensource.org/licenses/MIT The MIT License
* @version 3.0 * @version 3.0
*/ */
interface PicoPluginInterface interface PluginInterface
{ {
/** /**
* Handles a event that was triggered by Pico * Handles a event that was triggered by Pico
@ -41,8 +43,8 @@ interface PicoPluginInterface
/** /**
* Enables or disables this plugin * Enables or disables this plugin
* *
* @see PicoPluginInterface::isEnabled() * @see PluginInterface::isEnabled()
* @see PicoPluginInterface::isStatusChanged() * @see PluginInterface::isStatusChanged()
* *
* @param bool $enabled enable (TRUE) or disable (FALSE) this plugin * @param bool $enabled enable (TRUE) or disable (FALSE) this plugin
* @param bool $recursive when TRUE, enable or disable recursively. * @param bool $recursive when TRUE, enable or disable recursively.
@ -54,7 +56,7 @@ interface PicoPluginInterface
* @param bool $auto enable or disable to fulfill a dependency. This * @param bool $auto enable or disable to fulfill a dependency. This
* parameter is optional and defaults to FALSE. * parameter is optional and defaults to FALSE.
* *
* @throws RuntimeException thrown when a dependency fails * @throws \RuntimeException thrown when a dependency fails
*/ */
public function setEnabled($enabled, $recursive = true, $auto = false); public function setEnabled($enabled, $recursive = true, $auto = false);
@ -65,7 +67,7 @@ interface PicoPluginInterface
* wasn't triggered on all plugins yet. This method might even return NULL * wasn't triggered on all plugins yet. This method might even return NULL
* then. The plugin's status might change later. * then. The plugin's status might change later.
* *
* @see PicoPluginInterface::setEnabled() * @see PluginInterface::setEnabled()
* *
* @return bool|null plugin is enabled (TRUE) or disabled (FALSE) * @return bool|null plugin is enabled (TRUE) or disabled (FALSE)
*/ */
@ -74,7 +76,7 @@ interface PicoPluginInterface
/** /**
* Returns TRUE if the plugin was ever enabled/disabled manually * Returns TRUE if the plugin was ever enabled/disabled manually
* *
* @see PicoPluginInterface::setEnabled() * @see PluginInterface::setEnabled()
* *
* @return bool plugin is in its default state (TRUE), FALSE otherwise * @return bool plugin is in its default state (TRUE), FALSE otherwise
*/ */

View File

@ -10,6 +10,8 @@
* License-Filename: LICENSE * License-Filename: LICENSE
*/ */
namespace picocms\Pico;
/** /**
* Pico's Twig extension to implement additional filters * Pico's Twig extension to implement additional filters
* *
@ -18,12 +20,12 @@
* @license http://opensource.org/licenses/MIT The MIT License * @license http://opensource.org/licenses/MIT The MIT License
* @version 3.0 * @version 3.0
*/ */
class PicoTwigExtension extends Twig_Extension class TwigExtension extends \Twig_Extension
{ {
/** /**
* Current instance of Pico * Current instance of Pico
* *
* @see PicoTwigExtension::getPico() * @see TwigExtension::getPico()
* @var Pico * @var Pico
*/ */
private $pico; private $pico;
@ -67,20 +69,20 @@ class PicoTwigExtension extends Twig_Extension
* *
* @see Twig_ExtensionInterface::getFilters() * @see Twig_ExtensionInterface::getFilters()
* *
* @return Twig_SimpleFilter[] array of Pico's Twig filters * @return \Twig_SimpleFilter[] array of Pico's Twig filters
*/ */
public function getFilters() public function getFilters()
{ {
return array( return array(
'markdown' => new Twig_SimpleFilter( 'markdown' => new \Twig_SimpleFilter(
'markdown', 'markdown',
array($this, 'markdownFilter'), array($this, 'markdownFilter'),
array('is_safe' => array('html')) array('is_safe' => array('html'))
), ),
'map' => new Twig_SimpleFilter('map', array($this, 'mapFilter')), 'map' => new \Twig_SimpleFilter('map', array($this, 'mapFilter')),
'sort_by' => new Twig_SimpleFilter('sort_by', array($this, 'sortByFilter')), 'sort_by' => new \Twig_SimpleFilter('sort_by', array($this, 'sortByFilter')),
'link' => new Twig_SimpleFilter('link', array($this->pico, 'getPageUrl')), 'link' => new \Twig_SimpleFilter('link', array($this->pico, 'getPageUrl')),
'url' => new Twig_SimpleFilter('url', array($this->pico, 'substituteUrl')) 'url' => new \Twig_SimpleFilter('url', array($this->pico, 'substituteUrl'))
); );
} }
@ -89,14 +91,14 @@ class PicoTwigExtension extends Twig_Extension
* *
* @see Twig_ExtensionInterface::getFunctions() * @see Twig_ExtensionInterface::getFunctions()
* *
* @return Twig_SimpleFunction[] array of Pico's Twig functions * @return \Twig_SimpleFunction[] array of Pico's Twig functions
*/ */
public function getFunctions() public function getFunctions()
{ {
return array( return array(
'url_param' => new Twig_SimpleFunction('url_param', array($this, 'urlParamFunction')), 'url_param' => new \Twig_SimpleFunction('url_param', array($this, 'urlParamFunction')),
'form_param' => new Twig_SimpleFunction('form_param', array($this, 'formParamFunction')), 'form_param' => new \Twig_SimpleFunction('form_param', array($this, 'formParamFunction')),
'pages' => new Twig_SimpleFunction('pages', array($this, 'pagesFunction')) 'pages' => new \Twig_SimpleFunction('pages', array($this, 'pagesFunction'))
); );
} }
@ -129,19 +131,19 @@ class PicoTwigExtension extends Twig_Extension
* This method is registered as the Twig `map` filter. You can use this * This method is registered as the Twig `map` filter. You can use this
* filter to e.g. get all page titles (`{{ pages|map("title") }}`). * filter to e.g. get all page titles (`{{ pages|map("title") }}`).
* *
* @param array|Traversable $var variable to map * @param array|\Traversable $var variable to map
* @param mixed $mapKeyPath key to map; either a scalar or a * @param mixed $mapKeyPath key to map; either a scalar or a
* array interpreted as key path (i.e. ['foo', 'bar'] will return all * array interpreted as key path (i.e. ['foo', 'bar'] will return all
* $item['foo']['bar'] values) * $item['foo']['bar'] values)
* *
* @return array mapped values * @return array mapped values
* *
* @throws Twig_Error_Runtime * @throws \Twig_Error_Runtime
*/ */
public function mapFilter($var, $mapKeyPath) public function mapFilter($var, $mapKeyPath)
{ {
if (!is_array($var) && (!is_object($var) || !($var instanceof Traversable))) { if (!is_array($var) && (!is_object($var) || !($var instanceof \Traversable))) {
throw new Twig_Error_Runtime(sprintf( throw new \Twig_Error_Runtime(sprintf(
'The map filter only works with arrays or "Traversable", got "%s"', 'The map filter only works with arrays or "Traversable", got "%s"',
is_object($var) ? get_class($var) : gettype($var) is_object($var) ? get_class($var) : gettype($var)
)); ));
@ -166,11 +168,11 @@ class PicoTwigExtension extends Twig_Extension
* always sorted in ascending order, apply Twigs `reverse` filter to * always sorted in ascending order, apply Twigs `reverse` filter to
* achieve a descending order. * achieve a descending order.
* *
* @param array|Traversable $var variable to sort * @param array|\Traversable $var variable to sort
* @param mixed $sortKeyPath key to use for sorting; either * @param mixed $sortKeyPath key to use for sorting; either
* a scalar or a array interpreted as key path (i.e. ['foo', 'bar'] * a scalar or a array interpreted as key path (i.e. ['foo', 'bar']
* will sort $var by $item['foo']['bar']) * will sort $var by $item['foo']['bar'])
* @param string $fallback specify what to do with items * @param string $fallback specify what to do with items
* which don't contain the specified sort key; use "bottom" (default) * which don't contain the specified sort key; use "bottom" (default)
* to move these items to the end of the sorted array, "top" to rank * to move these items to the end of the sorted array, "top" to rank
* them first, "keep" to keep the original order, or "remove" to remove * them first, "keep" to keep the original order, or "remove" to remove
@ -178,20 +180,20 @@ class PicoTwigExtension extends Twig_Extension
* *
* @return array sorted array * @return array sorted array
* *
* @throws Twig_Error_Runtime * @throws \Twig_Error_Runtime
*/ */
public function sortByFilter($var, $sortKeyPath, $fallback = 'bottom') public function sortByFilter($var, $sortKeyPath, $fallback = 'bottom')
{ {
if (is_object($var) && ($var instanceof Traversable)) { if (is_object($var) && ($var instanceof \Traversable)) {
$var = iterator_to_array($var, true); $var = iterator_to_array($var, true);
} elseif (!is_array($var)) { } elseif (!is_array($var)) {
throw new Twig_Error_Runtime(sprintf( throw new \Twig_Error_Runtime(sprintf(
'The sort_by filter only works with arrays or "Traversable", got "%s"', 'The sort_by filter only works with arrays or "Traversable", got "%s"',
is_object($var) ? get_class($var) : gettype($var) is_object($var) ? get_class($var) : gettype($var)
)); ));
} }
if (($fallback !== 'top') && ($fallback !== 'bottom') && ($fallback !== 'keep') && ($fallback !== "remove")) { if (($fallback !== 'top') && ($fallback !== 'bottom') && ($fallback !== 'keep') && ($fallback !== "remove")) {
throw new Twig_Error_Runtime( throw new \Twig_Error_Runtime(
'The sort_by filter only supports the "top", "bottom", "keep" and "remove" fallbacks' 'The sort_by filter only supports the "top", "bottom", "keep" and "remove" fallbacks'
); );
} }
@ -243,10 +245,10 @@ class PicoTwigExtension extends Twig_Extension
* Returns the value of a variable item specified by a scalar key or a * Returns the value of a variable item specified by a scalar key or a
* arbitrary deep sub-key using a key path * arbitrary deep sub-key using a key path
* *
* @param array|Traversable|ArrayAccess|object $var base variable * @param array|\Traversable|\ArrayAccess|object $var base variable
* @param mixed $keyPath scalar key or a * @param mixed $keyPath scalar key or a
* array interpreted as key path (when passing e.g. ['foo', 'bar'], * array interpreted as key path (when passing e.g. ['foo', 'bar'], the
* the method will return $var['foo']['bar']) specifying the value * method will return $var['foo']['bar']) specifying the value
* *
* @return mixed the requested value or NULL when the given key or key path * @return mixed the requested value or NULL when the given key or key path
* didn't match * didn't match
@ -261,9 +263,9 @@ class PicoTwigExtension extends Twig_Extension
foreach ($keyPath as $key) { foreach ($keyPath as $key) {
if (is_object($var)) { if (is_object($var)) {
if ($var instanceof ArrayAccess) { if ($var instanceof \ArrayAccess) {
// use ArrayAccess, see below // use ArrayAccess, see below
} elseif ($var instanceof Traversable) { } elseif ($var instanceof \Traversable) {
$var = iterator_to_array($var); $var = iterator_to_array($var);
} elseif (isset($var->{$key})) { } elseif (isset($var->{$key})) {
$var = $var->{$key}; $var = $var->{$key};
@ -272,7 +274,7 @@ class PicoTwigExtension extends Twig_Extension
try { try {
$var = call_user_func(array($var, 'get' . ucfirst($key))); $var = call_user_func(array($var, 'get' . ucfirst($key)));
continue; continue;
} catch (BadMethodCallException $e) { } catch (\BadMethodCallException $e) {
return null; return null;
} }
} else { } else {
@ -421,7 +423,7 @@ class PicoTwigExtension extends Twig_Extension
* *
* @return array[] the data of the matched pages * @return array[] the data of the matched pages
* *
* @throws Twig_Error_Runtime * @throws \Twig_Error_Runtime
*/ */
public function pagesFunction($start = '', $depth = 0, $depthOffset = 0, $offset = 1) public function pagesFunction($start = '', $depth = 0, $depthOffset = 0, $offset = 1)
{ {
@ -443,7 +445,7 @@ class PicoTwigExtension extends Twig_Extension
$depthOffset = $depthOffset + $offset; $depthOffset = $depthOffset + $offset;
if (($depth !== null) && ($depth < 0)) { if (($depth !== null) && ($depth < 0)) {
throw new Twig_Error_Runtime('The pages function doesn\'t support negative depths'); throw new \Twig_Error_Runtime('The pages function doesn\'t support negative depths');
} }
$pageTree = $this->getPico()->getPageTree(); $pageTree = $this->getPico()->getPageTree();

View File

@ -10,6 +10,9 @@
* License-Filename: LICENSE * License-Filename: LICENSE
*/ */
use picocms\Pico\AbstractPlugin;
use picocms\Pico\Pico;
/** /**
* Pico dummy plugin - a template for plugins * Pico dummy plugin - a template for plugins
* *
@ -21,7 +24,7 @@
* @license http://opensource.org/licenses/MIT The MIT License * @license http://opensource.org/licenses/MIT The MIT License
* @version 3.0 * @version 3.0
*/ */
class DummyPlugin extends AbstractPicoPlugin class DummyPlugin extends AbstractPlugin
{ {
/** /**
* API version used by this plugin * API version used by this plugin
@ -52,7 +55,7 @@ class DummyPlugin extends AbstractPicoPlugin
* No matter what, the user can always explicitly enable or disable this * No matter what, the user can always explicitly enable or disable this
* plugin in Pico's config. * plugin in Pico's config.
* *
* @see AbstractPicoPlugin::$enabled * @see AbstractPlugin::$enabled
* @var bool|null * @var bool|null
*/ */
protected $enabled = false; protected $enabled = false;
@ -63,7 +66,7 @@ class DummyPlugin extends AbstractPicoPlugin
* If your plugin doesn't depend on any other plugin, remove this class * If your plugin doesn't depend on any other plugin, remove this class
* property. * property.
* *
* @see AbstractPicoPlugin::$dependsOn * @see AbstractPlugin::$dependsOn
* @var string[] * @var string[]
*/ */
protected $dependsOn = array(); protected $dependsOn = array();