Merge branches 'develop' and 'feature/streamwrappers' of https://github.com/getgrav/grav into feature/streamwrappers

Conflicts:
	system/src/Grav/Common/Grav.php
This commit is contained in:
Matias Griese 2014-08-19 19:39:48 +03:00
commit 7561ace5e2
18 changed files with 315 additions and 77 deletions

View File

@ -17,6 +17,7 @@
"erusev/parsedown-extra": "dev-master",
"symfony/yaml": "2.5.*@dev",
"symfony/console": "2.5.*@dev",
"symfony/event-dispatcher": "2.5.*@dev",
"doctrine/cache": "1.4.*@dev",
"tracy/tracy": "dev-master",
"gregwar/image": "dev-master",

View File

@ -30,7 +30,7 @@ try {
$grav->process();
} catch (\Exception $e) {
$grav->fireEvent('onFatalException', $e);
$grav->fireEvent('onFatalException');
throw $e;
}

View File

@ -1,7 +1,6 @@
<?php
namespace Grav\Common;
use \Tracy\Debugger;
use Closure;
use Exception;
use FilesystemIterator;
@ -99,7 +98,7 @@ class Assets
/** @var Config $config */
$config = self::$grav['config'];
$base_url = trim($config->get('system.base_url_relative'));
$theme = $config->get('system.pages.theme');
$theme = trim($config->get('system.pages.theme'));
$asset_config = (array)$config->get('system.assets');
$this->config($asset_config);

View File

@ -3,6 +3,8 @@ namespace Grav\Common;
use Grav\Common\Service\StreamsServiceProvider;
use Grav\Component\DI\Container;
use Grav\Component\EventDispatcher\Event;
use Grav\Component\EventDispatcher\EventDispatcher;
use Grav\Component\Filesystem\ResourceLocator;
/**
@ -53,6 +55,9 @@ class Grav extends Container
$container['grav'] = $container;
$container['events'] = function ($c) {
return new EventDispatcher;
};
$container['uri'] = function ($c) {
return new Uri($c);
};
@ -81,7 +86,18 @@ class Grav extends Container
return new Assets();
};
$container['page'] = function ($c) {
return $c['pages']->dispatch($c['uri']->route());
$page = $c['pages']->dispatch($c['uri']->route());
if (!$page || !$page->routable()) {
$event = $c->fireEvent('onPageNotFound');
if (isset($event->page)) {
$page = $event->page;
} else {
throw new \RuntimeException('Page Not Found', 404);
}
}
return $page;
};
$container['output'] = function ($c) {
return $c['twig']->processSite($c['uri']->extension());
@ -115,11 +131,6 @@ class Grav extends Container
$this->fireEvent('onAfterGetPage');
// If there's no page, throw exception
if (!$this['page']) {
throw new \RuntimeException('Page Not Found', 404);
}
// Process whole page as required
$this->output = $this['output'];
@ -179,34 +190,16 @@ class Grav extends Container
}
/**
* Processes any hooks and runs them.
* Fires an event with optional parameters.
*
* @param string $eventName
* @param Event $event
* @return Event
*/
public function fireEvent()
public function fireEvent($eventName, Event $event = null)
{
$args = func_get_args();
$hook_id = array_shift($args);
$no_timing_hooks = array('onAfterPageProcessed','onAfterFolderProcessed', 'onAfterCollectionProcessed');
/** @var Plugins $plugins */
$plugins = $this['plugins'];
if (!empty($plugins)) {
foreach ($plugins as $plugin) {
if (is_callable(array($plugin, $hook_id))) {
call_user_func_array(array($plugin, $hook_id), $args);
}
}
}
/** @var Config $config */
$config = $this['config'];
if ($config && $config->get('system.debugger.log.timing') && !in_array($hook_id, $no_timing_hooks)) {
/** @var Debugger $debugger */
$debugger = isset($this['debugger']) ? $this['debugger'] : null;
if ($debugger) {
$debugger->log($hook_id.': %f ms');
}
}
/** @var EventDispatcher $events */
$events = $this['events'];
return $events->dispatch($eventName, $event);
}
}

View File

@ -1,18 +1,19 @@
<?php
namespace Grav\Common\Page;
use \Grav\Common\Config;
use Grav\Common\Config;
use Grav\Common\GravTrait;
use \Grav\Common\Utils;
use \Grav\Common\Cache;
use \Grav\Common\Twig;
use \Grav\Common\Filesystem\File;
use \Grav\Common\Filesystem\Folder;
use \Grav\Common\Data;
use \Grav\Common\Uri;
use \Grav\Common\Grav;
use \Grav\Common\Taxonomy;
use \Symfony\Component\Yaml\Yaml;
use Grav\Common\Utils;
use Grav\Common\Cache;
use Grav\Common\Twig;
use Grav\Common\Filesystem\File;
use Grav\Common\Filesystem\Folder;
use Grav\Common\Data;
use Grav\Common\Uri;
use Grav\Common\Grav;
use Grav\Common\Taxonomy;
use Grav\Component\EventDispatcher\Event;
use Symfony\Component\Yaml\Yaml;
/**
* The Page object, or "Page" object is the main powerhouse of Grav. It contains all the information
@ -1330,7 +1331,7 @@ class Page
$grav = self::$grav['grav'];
// New Custom event to handle things like pagination.
$grav->fireEvent('onAfterCollectionProcessed', $collection);
$grav->fireEvent('onAfterCollectionProcessed', new Event(['collection' => $collection]));
$params = $collection->params();

View File

@ -1,13 +1,14 @@
<?php
namespace Grav\Common\Page;
use \Grav\Common\Filesystem\Folder;
use \Grav\Common\Grav;
use \Grav\Common\Config;
use \Grav\Common\Data;
use \Grav\Common\Utils;
use \Grav\Common\Cache;
use \Grav\Common\Taxonomy;
use Grav\Common\Filesystem\Folder;
use Grav\Common\Grav;
use Grav\Common\Config;
use Grav\Common\Data;
use Grav\Common\Utils;
use Grav\Common\Cache;
use Grav\Common\Taxonomy;
use Grav\Component\EventDispatcher\Event;
/**
* GravPages is the class that is the entry point into the hierarchy of pages
@ -269,7 +270,7 @@ class Pages
}
if (!$blueprint->initialized) {
$this->grav->fireEvent('onCreateBlueprint', $blueprint);
$this->grav->fireEvent('onCreateBlueprint', new Event(['blueprint' => $blueprint]));
$blueprint->initialized = true;
}
@ -420,7 +421,7 @@ class Pages
$page->init($file);
if ($config->get('system.pages.events.page')) {
$this->grav->fireEvent('onAfterPageProcessed', $page);
$this->grav->fireEvent('onAfterPageProcessed', new Event(['page' => $page]));
}
} elseif ($file->isDir() && !$file->isDot()) {
@ -447,7 +448,7 @@ class Pages
$this->lastModified($file->getMTime());
if ($config->get('system.pages.events.page')) {
$this->grav->fireEvent('onAfterFolderProcessed', $page);
$this->grav->fireEvent('onAfterFolderProcessed', new Event(['page' => $page]));
}
}
}

View File

@ -1,26 +1,75 @@
<?php
namespace Grav\Common;
use Grav\Component\EventDispatcher\EventDispatcher;
use Grav\Component\EventDispatcher\EventSubscriberInterface;
/**
* The Plugin object just holds the id and path to a plugin.
*
* @author RocketTheme
* @license MIT
*/
class Plugin
class Plugin implements EventSubscriberInterface
{
/**
* @var Grav
*/
protected $grav;
/**
* @var Config
*/
public $config;
protected $config;
/**
* By default assign all methods as listeners using the default priority.
*
* @return array
*/
public static function getSubscribedEvents() {
$methods = get_class_methods(get_called_class());
$list = array();
foreach ($methods as $method) {
if (strpos($method, 'on') === 0) {
$list[$method] = [$method, 0];
}
}
return $list;
}
/**
* Constructor.
*
* @param Grav $grav
* @param Config $config
*/
public function __construct(Config $config)
public function __construct(Grav $grav, Config $config)
{
$this->grav = $grav;
$this->config = $config;
}
/**
* @param array $events
*/
protected function enable(array $events)
{
/** @var EventDispatcher $dispatcher */
$dispatcher = $this->grav['events'];
foreach ($events as $eventName => $params) {
if (is_string($params)) {
$dispatcher->addListener($eventName, array($this, $params));
} elseif (is_string($params[0])) {
$dispatcher->addListener($eventName, array($this, $params[0]), isset($params[1]) ? $params[1] : 0);
} else {
foreach ($params as $listener) {
$dispatcher->addListener($eventName, array($this, $listener[0]), isset($listener[1]) ? $listener[1] : 0);
}
}
}
}
}

View File

@ -2,6 +2,8 @@
namespace Grav\Common;
use Grav\Common\Filesystem\File;
use Grav\Component\EventDispatcher\EventDispatcher;
use Grav\Component\EventDispatcher\EventSubscriberInterface;
/**
* The Plugins object holds an array of all the plugin objects that
@ -30,7 +32,9 @@ class Plugins extends Iterator
$config = $this->grav['config'];
$plugins = (array) $config->get('plugins');
$instances = ['theme' => $this->grav['themes']->load()];
/** @var EventDispatcher $events */
$events = $this->grav['events'];
foreach ($plugins as $plugin => $data) {
if (empty($data['enabled'])) {
// Only load enabled plugins.
@ -50,10 +54,18 @@ class Plugins extends Iterator
throw new \RuntimeException(sprintf("Plugin '%s' class not found!", $plugin));
}
$instances[$pluginClass] = new $pluginClass($config);
$instance = new $pluginClass($this->grav, $config);
if ($instance instanceof EventSubscriberInterface) {
$events->addSubscriber($instance);
}
}
return $instances;
$instance = $this->grav['themes']->load();
if ($instance instanceof EventSubscriberInterface) {
$events->addSubscriber($instance);
}
return $this->items;
}
public function add($plugin)

View File

@ -1,6 +1,6 @@
<?php
namespace Grav\Common;
class Theme
class Theme extends Plugin
{
}

View File

@ -86,9 +86,10 @@ class Themes
public function load($name = null)
{
/** @var Config $config */
$config = $this->grav['config'];
if (!$name) {
/** @var Config $config */
$config = $this->grav['config'];
$name = $config->get('system.pages.theme');
}
@ -100,13 +101,13 @@ class Themes
$className = '\\Grav\\Theme\\' . ucfirst($name);
if (class_exists($className)) {
$class = new $className;
$class = new $className($this->grav, $config);
}
}
}
if (empty($class)) {
$class = new Theme;
$class = new Theme($this->grav, $config);
}
return $class;

View File

@ -26,21 +26,29 @@ class Uri
*/
public function __construct()
{
$base = 'http://';
$uri = $_SERVER["REQUEST_URI"];
if (isset($_SERVER["HTTPS"])) {
$base = (@$_SERVER["HTTPS"] == "on") ? "https://" : "http://";
$base = 'http://';
$uri = $_SERVER['REQUEST_URI'];
$root_path = rtrim(substr($_SERVER['PHP_SELF'], 0, strpos($_SERVER['PHP_SELF'], 'index.php')), '/');
if (isset($_SERVER['HTTPS'])) {
$base = (@$_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://';
}
$base .= $_SERVER["SERVER_NAME"];
$base .= $_SERVER['SERVER_NAME'];
if ($_SERVER["SERVER_PORT"] != "80" && $_SERVER["SERVER_PORT"] != "443") {
$base .= ":".$_SERVER["SERVER_PORT"];
if ($_SERVER['SERVER_PORT'] != '80' && $_SERVER['SERVER_PORT'] != '443') {
$base .= ":".$_SERVER['SERVER_PORT'];
}
// check if userdir in the path and workaround PHP bug with PHP_SELF
if (strpos($_SERVER['REQUEST_URI'], '/~') !== false && strpos($_SERVER['PHP_SELF'], '/~') === false) {
$root_path = substr($_SERVER['REQUEST_URI'], 0, strpos($_SERVER['REQUEST_URI'], '/', 1)) . $root_path;
}
$this->base = $base;
$this->root = $base . rtrim(substr($_SERVER['PHP_SELF'], 0, strpos($_SERVER['PHP_SELF'], 'index.php')), '/');
$this->root = $base . $root_path;
$this->url = $base . $uri;
$this->init();

View File

@ -0,0 +1,46 @@
<?php
namespace Grav\Component\ArrayTraits;
/**
* Class ArrayAccess
* @package Grav\Component\ArrayTraits
*
* @property array $items
*/
trait ArrayAccess
{
/**
* @param mixed $offset
* @return bool
*/
public function offsetExists($offset)
{
return isset($this->items[$offset]);
}
/**
* @param mixed $offset
* @return mixed
*/
public function offsetGet($offset)
{
return isset($this->items[$offset]) ? $this->items[$offset] : null;
}
/**
* @param mixed $offset
* @param mixed $value
*/
public function offsetSet($offset, $value)
{
$this->items[$offset] = $value;
}
/**
* @param mixed $offset
*/
public function offsetUnset($offset)
{
unset($this->items[$offset]);
}
}

View File

@ -0,0 +1,21 @@
<?php
namespace Grav\Component\ArrayTraits;
/**
* Class Constructor
* @package Grav\Component\ArrayTraits
*
* @property array $items
*/
trait Constructor
{
/**
* Constructor.
*
* @param array $items Initial items inside the iterator.
*/
public function __construct(array $items = array())
{
$this->items = $items;
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace Grav\Component\ArrayTraits;
/**
* Class Countable
* @package Grav\Component\ArrayTraits
*
* @property array $items;
*/
trait Countable
{
/**
* @return int
*/
public function count()
{
count($this->items);
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace Grav\Component\ArrayTraits;
trait Getters
{
use ArrayAccess;
/**
* Magic setter method
*
* @param mixed $offset Asset name value
* @param mixed $value Asset value
*/
public function __set($offset, $value)
{
$this->offsetSet($offset, $value);
}
/**
* Magic getter method
*
* @param mixed $offset Asset name value
* @return mixed Asset value
*/
public function __get($offset)
{
return $this->offsetGet($offset);
}
/**
* Magic method to determine if the attribute is set
*
* @param mixed $offset Asset name value
* @return boolean True if the value is set
*/
public function __isset($offset)
{
return $this->offsetExists($offset);
}
/**
* Magic method to unset the attribute
*
* @param mixed $offset The name value to unset
*/
public function __unset($offset)
{
$this->offsetUnset($offset);
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace Grav\Component\EventDispatcher;
use Grav\Component\ArrayTraits\ArrayAccess;
use Grav\Component\ArrayTraits\Constructor;
class Event extends \Symfony\Component\EventDispatcher\Event implements \ArrayAccess
{
use ArrayAccess, Constructor;
/**
* @var array
*/
protected $items = array();
}

View File

@ -0,0 +1,16 @@
<?php
namespace Grav\Component\EventDispatcher;
use \Symfony\Component\EventDispatcher\Event as BaseEvent;
class EventDispatcher extends \Symfony\Component\EventDispatcher\EventDispatcher
{
public function dispatch($eventName, BaseEvent $event = null)
{
if (null === $event) {
$event = new Event();
}
return parent::dispatch($eventName, $event);
}
}

View File

@ -0,0 +1,6 @@
<?php
namespace Grav\Component\EventDispatcher;
interface EventSubscriberInterface extends \Symfony\Component\EventDispatcher\EventSubscriberInterface
{
}