Merge branch 'release/0.9.1'

This commit is contained in:
user.email
2014-09-02 14:05:39 -07:00
41 changed files with 505 additions and 265 deletions

View File

@@ -1,7 +1,5 @@
<IfModule mod_rewrite.c>
Options -Multiviews
RewriteEngine On
##

View File

@@ -7,7 +7,12 @@ The underlying architecture of Grav has been designed to use well-established an
* [Twig Templating](http://twig.sensiolabs.org/): for powerful control of the user interface
* [Markdown](http://en.wikipedia.org/wiki/Markdown): for easy content creation
* [YAML](http://yaml.org): for simple configuration
* [Doctrine Cache](http://docs.doctrine-project.org/en/2.0.x/reference/caching.html): layer for incredible performance
* [Parsedown](http://parsedown.org/): for fast Markdown and Mardown Extra support
* [Doctrine Cache](http://docs.doctrine-project.org/en/2.0.x/reference/caching.html): layer for performance
* [Pimple Dependency Injection Container](http://pimple.sensiolabs.org/): for extensibility and maintainability
* [Symfony Event Dispacher](http://symfony.com/doc/current/components/event_dispatcher/introduction.html): for plugin event handling
* [Symfony Console](http://symfony.com/doc/current/components/console/introduction.html): for CLI interface
* [Gregwar Image Library](https://github.com/Gregwar/Image): for dynamic image manipulation
# QuickStart

View File

@@ -1 +1 @@
0.9.0
0.9.1

View File

@@ -16,17 +16,23 @@
"tracy/tracy": "~2.2",
"gregwar/image": "~2.0",
"ircmaxell/password-compat": "1.0.*",
"mrclay/minify": "~2.2",
"mrclay/minify": "dev-master",
"donatj/phpuseragentparser": "dev-master",
"pimple/pimple": "~3.0"
},
"autoload": {
"psr-4": {
"psr-0": {
"Grav\\": "system/src/"
},
"files": ["system/defines.php"]
},
"archive": {
"exclude": ["VERSION"]
}
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/rhukster/minify"
}
]
}

View File

@@ -5,20 +5,25 @@ schemes:
- user/plugins
- system/plugins
# asset:
# type: ReadOnlyStream
# paths:
# - assets
asset:
type: ReadOnlyStream
paths:
- assets
# cache:
# type: ReadOnlyStream
# paths:
# - cache
cache:
type: ReadOnlyStream
paths:
- cache
# log:
# type: ReadOnlyStream
# paths:
# - logs
log:
type: ReadOnlyStream
paths:
- logs
user:
type: ReadOnlyStream
paths:
- user
page:
type: ReadOnlyStream
@@ -34,3 +39,9 @@ schemes:
type: ReadOnlyStream
paths:
- user/data
theme:
type: ReadOnlyStream
prefixes:
'/':
- user/themes

View File

@@ -22,7 +22,7 @@ pages:
cache:
enabled: true # Set to true to enable caching
check:
pages: true # Check to see if page has been modifying to flush the cache
method: file # Method to check for updates in pages: file|folder|none
driver: auto # One of: auto|file|apc|xcache|memcache|memcached|wincache
prefix: 'g' # Cache prefix string (prevents cache conflicts)

View File

@@ -2,13 +2,14 @@
// Some standard defines
define('GRAV', true);
define('GRAV_VERSION', '0.9.0');
define('GRAV_VERSION', '0.9.1');
define('DS', '/');
// Directories and Paths
if (!defined('ROOT_DIR')) {
define('ROOT_DIR', getcwd() .'/');
if (!defined('GRAV_ROOT')) {
define('GRAV_ROOT', getcwd());
}
define('ROOT_DIR', GRAV_ROOT . '/');
define('USER_PATH', 'user/');
define('USER_DIR', ROOT_DIR . USER_PATH);
define('SYSTEM_DIR', ROOT_DIR .'system/');

View File

@@ -66,6 +66,9 @@ class Cache extends Getters
$this->key = substr(md5(($prefix ? $prefix : 'g') . $uri->rootUrl(true) . $this->config->key . GRAV_VERSION), 2, 8);
$this->driver = $this->getCacheDriver();
// Set the cache namespace to our unique key
$this->driver->setNamespace($this->key);
}
/**
@@ -132,7 +135,6 @@ class Cache extends Getters
public function fetch($id)
{
if ($this->enabled) {
$id = $this->key . $id;
return $this->driver->fetch($id);
} else {
return false;
@@ -149,7 +151,6 @@ class Cache extends Getters
public function save($id, $data, $lifetime = null)
{
if ($this->enabled) {
$id = $this->key . $id;
$this->driver->save($id, $data, $lifetime);
}
}

View File

@@ -109,7 +109,7 @@ class Markdown extends General
$var = preg_replace("/(\r\n|\r)/", "\n", $var);
// Parse header.
preg_match("/---\n(.+?)\n---(\n\n|$)/uism", $this->raw(), $m);
preg_match("/---\n(.+?)\n---(\n\n|$)/uism", $var, $m);
$content['header'] = isset($m[1]) ? YamlParser::parse(preg_replace("/\n\t/", "\n ", $m[1])) : array();
// Strip header to get content.

View File

@@ -15,13 +15,13 @@ abstract class Folder
* @param string $path
* @return int
*/
public static function lastModified($path)
public static function lastModifiedFolder($path)
{
$last_modified = 0;
$directory = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
$iterator = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST);
$last_modified = 0;
/** @var \RecursiveDirectoryIterator $file */
foreach ($iterator as $file) {
$dir_modified = $file->getMTime();
@@ -32,6 +32,34 @@ abstract class Folder
return $last_modified;
}
/**
* Recursively find the last modified time under given path by file.
*
* @param string $path
* @return int
*/
public static function lastModifiedFile($path)
{
$last_modified = 0;
$dirItr = new \RecursiveDirectoryIterator($path);
$filterItr = new GravRecursiveFilterIterator($dirItr);
$itr = new \RecursiveIteratorIterator($filterItr, \RecursiveIteratorIterator::SELF_FIRST);
/** @var \RecursiveDirectoryIterator $file */
foreach ($itr as $file) {
if (!$file->isDir()) {
$file_modified = $file->getMTime();
if ($file_modified > $last_modified) {
$last_modified = $file_modified;
}
}
}
return $last_modified;
}
/**
* Return recursive list of all files and directories under given path.
*
@@ -219,3 +247,19 @@ abstract class Folder
}
}
}
class GravRecursiveFilterIterator extends \RecursiveFilterIterator {
public static $FILTERS = array(
'.', '..', '.DS_Store'
);
public function accept() {
return !in_array(
$this->current()->getFilename(),
self::$FILTERS,
true
);
}
}

View File

@@ -2,19 +2,34 @@
namespace Grav\Common\Markdown;
use Grav\Common\Debugger;
use Grav\Common\GravTrait;
/**
* A trait to add some custom processing to the identifyLink() method in Parsedown and ParsedownExtra
*/
trait MarkdownGravLinkTrait
{
use GravTrait;
protected function identifyLink($Excerpt)
{
// Run the parent method to get the actual results
$Excerpt = parent::identifyLink($Excerpt);
$actions = array();
$command = '';
$this->base_url = trim(self::$grav['config']->get('system.base_url_relative'));
// if this is a link
if (isset($Excerpt['element']['attributes']['href'])) {
$url = parse_url(htmlspecialchars_decode($Excerpt['element']['attributes']['href']));
// if there is no host set but there is a path, the file is local
if (!isset($url['host']) && isset($url['path'])) {
// convert the URl is required
$Excerpt['element']['attributes']['href'] = $this->convertUrl($url['path']);
}
}
// if this is an image
if (isset($Excerpt['element']['attributes']['src'])) {
@@ -75,9 +90,58 @@ trait MarkdownGravLinkTrait
// Set the lightbox element on the Excerpt
$Excerpt['element'] = $Element;
}
} else {
// not a current page media file, see if it needs converting to relative
$Excerpt['element']['attributes']['src'] = $this->convertUrl($url['path']);
}
}
}
return $Excerpt;
}
/**
* Converts links from absolute '/' or relative (../..) to a grav friendly format
* @param string $markdown_url the URL as it was written in the markdown
* @return string the more friendly formatted url
*/
protected function convertUrl($markdown_url)
{
// if absolue and starts with a base_url move on
if (strpos($markdown_url, $this->base_url) === 0) {
$new_url = $markdown_url;
// if its absolute with /
} elseif (strpos($markdown_url, '/') === 0) {
$new_url = rtrim($this->base_url, '/') . $markdown_url;
} else {
$relative_path = rtrim($this->base_url, '/') . $this->page->route();
// If this is a 'real' filepath clean it up
if (file_exists($this->page->path().'/'.$markdown_url)) {
$relative_path = rtrim($this->base_url, '/') .
preg_replace('/\/([\d]+.)/', '/',
str_replace(PAGES_DIR, '/', $this->page->path()));
$markdown_url = preg_replace('/^([\d]+.)/', '',
preg_replace('/\/([\d]+.)/', '/',
trim(preg_replace('/[^\/]+(\.md$)/', '', $markdown_url), '/')));
}
// else its a relative path already
$newpath = array();
$paths = explode('/', $markdown_url);
// remove the updirectory references (..)
foreach ($paths as $path) {
if ($path == '..') {
$relative_path = dirname($relative_path);
} else {
$newpath[] = $path;
}
}
// build the new url
$new_url = $relative_path . '/' . implode('/', $newpath);
}
return $new_url;
}
}

View File

@@ -106,7 +106,7 @@ class Page
public function init($file)
{
$this->filePath($file->getPathName());
$this->modified(filemtime($file->getPath()));
$this->modified($file->getMTime());
$this->id($this->modified().md5($this->filePath()));
$this->header();
$this->slug();

View File

@@ -356,8 +356,22 @@ class Pages
$cache = $this->grav['cache'];
/** @var Taxonomy $taxonomy */
$taxonomy = $this->grav['taxonomy'];
$last_modified = $config->get('system.cache.check.pages', true)
? Folder::lastModified(PAGES_DIR) : 0;
$last_modified = 0;
// how should we check for last modified? Default is by file
switch (strtolower($config->get('system.cache.check.method', 'file'))) {
case 'none':
case 'off':
$last_modified = 0;
break;
case 'folder':
$last_modified = Folder::lastModifiedFolder(PAGES_DIR);
break;
default:
$last_modified = Folder::lastModifiedFile(PAGES_DIR);
}
$page_cache_id = md5(USER_DIR.$last_modified);
list($this->instances, $this->routes, $this->children, $taxonomy_map, $this->sort) = $cache->fetch($page_cache_id);
@@ -412,10 +426,17 @@ class Pages
throw new \RuntimeException('Fatal error when creating page instances.');
}
$last_modified = 0;
/** @var \DirectoryIterator $file */
foreach ($iterator as $file) {
$name = $file->getFilename();
$date = $file->getMTime();
if ($date > $last_modified) {
$last_modified = $date;
}
if ($file->isFile() && Utils::endsWith($name, CONTENT_EXT)) {
$page->init($file);
@@ -451,8 +472,14 @@ class Pages
$this->grav->fireEvent('onFolderProcessed', new Event(['page' => $page]));
}
}
}
// Override the modified and ID so that it takes the latest change
// into account
$page->modified($last_modified);
$page->id($last_modified.md5($page->filePath()));
// Sort based on Defaults or Page Overridden sort order
$this->children[$page->path()] = $this->sort($page);
@@ -546,7 +573,7 @@ class Pages
// else just sort the list according to specified key
asort($list);
}
// Move manually ordered items into the beginning of the list. Order of the unlisted items does not change.
if (is_array($manual) && !empty($manual)) {

View File

@@ -60,8 +60,10 @@ class Plugins extends Iterator
}
}
$instance = $this->grav['themes']->load();
$instance->configure();
/** @var Themes $themes */
$themes = $this->grav['themes'];
$themes->configure();
$instance = $themes->load();
if ($instance instanceof EventSubscriberInterface) {
$events->addSubscriber($instance);
}
@@ -84,7 +86,7 @@ class Plugins extends Iterator
static public function all()
{
$list = array();
$iterator = new \DirectoryIterator('plugin://');
$iterator = new \DirectoryIterator('plugin:///');
/** @var \DirectoryIterator $directory */
foreach ($iterator as $directory) {

View File

@@ -21,44 +21,4 @@ class Theme extends Plugin
parent::__construct($grav, $config);
}
public function configure() {
$themeConfig = Yaml::instance(THEMES_DIR . "{$this->name}/{$this->name}.yaml")->content();
$this->config->merge(['themes' => [$this->name => $themeConfig]]);
/** @var ResourceLocator $locator */
$locator = $this->grav['locator'];
// TODO: move
$registered = stream_get_wrappers();
$schemes = $this->config->get(
"themes.{$this->name}.streams.scheme",
['theme' => ['paths' => ["user/themes/{$this->name}"]]]
);
foreach ($schemes as $scheme => $config) {
if (isset($config['paths'])) {
$locator->addPath($scheme, '', $config['paths']);
}
if (isset($config['prefixes'])) {
foreach ($config['prefixes'] as $prefix => $paths) {
$locator->addPath($scheme, $prefix, $paths);
}
}
if (in_array($scheme, $registered)) {
stream_wrapper_unregister($scheme);
}
$type = !empty($config['type']) ? $config['type'] : 'ReadOnlyStream';
if ($type[0] != '\\') {
$type = '\\Grav\\Component\\Filesystem\\StreamWrapper\\' . $type;
}
if (!stream_wrapper_register($scheme, $type)) {
throw new \InvalidArgumentException("Stream '{$type}' could not be initialized.");
}
}
}
}

View File

@@ -1,7 +1,10 @@
<?php
namespace Grav\Common;
use Grav\Common\Filesystem\File;
use Grav\Common\Data\Data;
use Grav\Common\Data\Blueprints;
use Grav\Common\Filesystem\File\Yaml;
use Grav\Component\Filesystem\ResourceLocator;
/**
* The Themes object holds an array of all the theme objects that Grav knows about.
@@ -24,7 +27,7 @@ class Themes
/**
* Return list of all theme data with their blueprints.
*
* @return array|Data\Data[]
* @return array|Data[]
*/
public function all()
{
@@ -49,33 +52,35 @@ class Themes
/**
* Get theme or throw exception if it cannot be found.
*
* @param string $type
* @return Data\Data
* @param string $name
* @return Data
* @throws \RuntimeException
*/
public function get($type)
public function get($name)
{
if (!$type) {
if (!$name) {
throw new \RuntimeException('Theme name not provided.');
}
$blueprints = new Data\Blueprints(THEMES_DIR . $type);
$blueprints = new Blueprints("theme:///{$name}");
$blueprint = $blueprints->get('blueprints');
$blueprint->name = $type;
$blueprint->name = $name;
/** @var Config $config */
$config = $this->grav['config'];
// Find thumbnail.
$thumb = THEMES_DIR . "{$type}/thumbnail.jpg";
$thumb = "theme:///{$name}/thumbnail.jpg";
if (file_exists($thumb)) {
// TODO: use real URL with base path.
$blueprint->set('thumbnail', "/user/themes/{$type}/thumbnail.jpg");
$blueprint->set('thumbnail', $config->get('system.base_url_relative') . "/user/themes/{$name}/thumbnail.jpg");
}
// Load default configuration.
$file = File\Yaml::instance(THEMES_DIR . "{$type}/{$type}" . YAML_EXT);
$obj = new Data\Data($file->content(), $blueprint);
$file = Yaml::instance("theme:///{$name}/{$name}.yaml");
$obj = new Data($file->content(), $blueprint);
// Override with user configuration.
$file = File\Yaml::instance(USER_DIR . "config/themes/{$type}" . YAML_EXT);
$file = Yaml::instance("user://config/themes/{$name}.yaml");
$obj->merge($file->content());
// Save configuration always to user/config.
@@ -84,7 +89,7 @@ class Themes
return $obj;
}
public function load($name = null)
public function current($name = null)
{
/** @var Config $config */
$config = $this->grav['config'];
@@ -93,23 +98,83 @@ class Themes
$name = $config->get('system.pages.theme');
}
$file = THEMES_DIR . "{$name}/{$name}.php";
if (file_exists($file)) {
$class = require_once $file;
return $name;
}
public function load($name = null)
{
$name = $this->current($name);
$grav = $this->grav;
/** @var Config $config */
$config = $grav['config'];
/** @var ResourceLocator $locator */
$locator = $grav['locator'];
$file = $locator("theme://theme.php") ?: $locator("theme://{$name}.php");
if ($file) {
// Local variables available in the file: $grav, $config, $name, $path, $file
$class = include $file;
if (!is_object($class)) {
$className = '\\Grav\\Theme\\' . ucfirst($name);
if (class_exists($className)) {
$class = new $className($this->grav, $config, $name);
$class = new $className($grav, $config, $name);
}
}
}
if (empty($class)) {
$class = new Theme($this->grav, $config, $name);
$class = new Theme($grav, $config, $name);
}
return $class;
}
public function configure($name = null) {
$name = $this->current($name);
/** @var Config $config */
$config = $this->grav['config'];
$themeConfig = Yaml::instance(THEMES_DIR . "{$name}/{$name}.yaml")->content();
$config->merge(['themes' => [$name => $themeConfig]]);
/** @var ResourceLocator $locator */
$locator = $this->grav['locator'];
// TODO: move
$registered = stream_get_wrappers();
$schemes = $config->get(
"themes.{$name}.streams.schemes",
['theme' => ['paths' => ["user/themes/{$name}"]]]
);
foreach ($schemes as $scheme => $config) {
if (isset($config['paths'])) {
$locator->addPath($scheme, '', $config['paths']);
}
if (isset($config['prefixes'])) {
foreach ($config['prefixes'] as $prefix => $paths) {
$locator->addPath($scheme, $prefix, $paths);
}
}
if (in_array($scheme, $registered)) {
stream_wrapper_unregister($scheme);
}
$type = !empty($config['type']) ? $config['type'] : 'ReadOnlyStream';
if ($type[0] != '\\') {
$type = '\\Grav\\Component\\Filesystem\\StreamWrapper\\' . $type;
}
if (!stream_wrapper_register($scheme, $type)) {
throw new \InvalidArgumentException("Stream '{$type}' could not be initialized.");
}
}
}
}

View File

@@ -2,6 +2,7 @@
namespace Grav\Common;
use \Grav\Common\Page\Page;
use Grav\Component\Filesystem\ResourceLocator;
/**
* The Twig object handles all the Twig template rendering for Grav. It's a singleton object
@@ -66,8 +67,10 @@ class Twig
if (!isset($this->twig)) {
/** @var Config $config */
$config = $this->grav['config'];
/** @var ResourceLocator $locator */
$locator = $this->grav['locator'];
$this->twig_paths = array(THEMES_DIR . $config->get('system.pages.theme') . '/templates');
$this->twig_paths = $locator->findResources('theme://templates');
$this->grav->fireEvent('onTwigTemplatePaths');
$this->loader = new \Twig_Loader_Filesystem($this->twig_paths);
@@ -76,7 +79,7 @@ class Twig
$params = $config->get('system.twig');
if (!empty($params['cache'])) {
$params['cache'] = CACHE_DIR;
$params['cache'] = $locator->findResource('cache://');
}
$this->twig = new \Twig_Environment($loader_chain, $params);
@@ -106,7 +109,7 @@ class Twig
'base_dir' => rtrim(ROOT_DIR, '/'),
'base_url_absolute' => $baseUrlAbsolute,
'base_url_relative' => $baseUrlRelative,
'theme_dir' => THEMES_DIR . $theme,
'theme_dir' => $locator->findResource('theme://'),
'theme_url' => $themeUrl,
'site' => $config->get('site'),
'assets' => $this->grav['assets'],
@@ -181,24 +184,6 @@ class Twig
return $output;
}
/**
* @param string $string string to render.
* @param array $vars Optional variables
* @return string
*/
public function processString($string, array $vars = array())
{
// override the twig header vars for local resolution
$this->grav->fireEvent('onTwigStringVariables');
$vars += $this->twig_vars;
$name = '@Var:' . $string;
$this->setTemplate($name, $string);
$output = $this->twig->render($name, $vars);
return $output;
}
/**
* Twig process that renders the site layout. This is the main twig process that renders the overall
* page and handles all the layout for the site display.

View File

@@ -1,5 +1,6 @@
<?php
namespace Grav\Common;
use Grav\Component\Filesystem\ResourceLocator;
/**
* The Twig extension adds some filters and functions that are useful for Grav
@@ -44,7 +45,8 @@ class TwigExtension extends \Twig_Extension
public function getFunctions()
{
return array(
new \Twig_SimpleFunction('repeat', array($this, 'repeatFunc'))
new \Twig_SimpleFunction('repeat', array($this, 'repeatFunc')),
new \Twig_SimpleFunction('url', array($this, 'urlFunc'))
);
}
@@ -195,4 +197,22 @@ class TwigExtension extends \Twig_Extension
{
return str_repeat($input, $multiplier);
}
/**
* Return URL to the resource.
*
* @param string $input
* @param bool $domain
* @return string
*/
public function urlFunc($input, $domain = false)
{
$grav = Grav::instance();
/** @var ResourceLocator $locator */
$locator = $grav['locator'];
/** @var Uri $uri */
$uri = $grav['uri'];
return $uri->rootUrl($domain) . $locator->findResource($input, false);
}
}

View File

@@ -82,7 +82,7 @@ class Uri
// remove the extension if there is one set
$parts = pathinfo($uri);
if (strpos($parts['basename'], '.')) {
if (preg_match("/\.(txt|xml|html|json|rss|atom)$/", $parts['basename'])) {
$uri = rtrim($parts['dirname'], '/').'/'.$parts['filename'];
$this->extension = $parts['extension'];
}

View File

@@ -11,6 +11,8 @@ use Grav\Common\Data\Data;
*/
class User extends Data
{
protected $password;
/**
* Authenticate user.
*

View File

@@ -83,14 +83,14 @@ class ResourceLocator
$scheme = 'file';
}
if (!$file || $uri[0] == ':') {
throw new \InvalidArgumentException('Invalid resource URI');
}
if (!isset($this->schemes[$scheme])) {
throw new \InvalidArgumentException("Invalid resource {$scheme}://");
}
if (!$file && $scheme == 'file') {
$file = getcwd();
}
$paths = $array ? [] : false;
$results = $array ? [] : false;
foreach ($this->schemes[$scheme] as $prefix => $paths) {
if ($prefix && strpos($file, $prefix) !== 0) {
continue;
@@ -104,11 +104,11 @@ class ResourceLocator
if (!$array) {
return $absolute ? $lookup : $filename;
}
$paths[] = $absolute ? $lookup : $filename;
$results[] = $absolute ? $lookup : $filename;
}
}
}
return $paths;
return $results;
}
}

View File

@@ -11,7 +11,7 @@ pages:
cache:
enabled: true
check:
pages: true
method: file
driver: auto
prefix: 'g'
@@ -22,7 +22,7 @@ twig:
autoescape: false
assets:
css_pipeline: false
css_pipeline: true
css_minify: true
css_rewrite: true
js_pipeline: false

View File

@@ -0,0 +1,5 @@
---
title: Test
---
# Testing

2
vendor/autoload.php vendored
View File

@@ -4,4 +4,4 @@
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInitc72d8fa047c31604816395255e8b35b9::getLoader();
return ComposerAutoloaderInit836e000af2692cba78dada56c083fe42::getLoader();

View File

@@ -27,7 +27,7 @@ return array(
'DooDigestAuth' => $vendorDir . '/mrclay/minify/min/lib/DooDigestAuth.php',
'FirePHP' => $vendorDir . '/mrclay/minify/min/lib/FirePHP.php',
'Grav\\Common\\Assets' => $baseDir . '/system/src/Grav/Common/Assets.php',
'Grav\\Common\\Browser' => $baseDir . '/system/src/Grav/Browser.php',
'Grav\\Common\\Browser' => $baseDir . '/system/src/Grav/Common/Browser.php',
'Grav\\Common\\Cache' => $baseDir . '/system/src/Grav/Common/Cache.php',
'Grav\\Common\\Config' => $baseDir . '/system/src/Grav/Common/Config.php',
'Grav\\Common\\Data\\Blueprint' => $baseDir . '/system/src/Grav/Common/Data/Blueprint.php',
@@ -44,6 +44,7 @@ return array(
'Grav\\Common\\Filesystem\\File\\Markdown' => $baseDir . '/system/src/Grav/Common/Filesystem/File/Markdown.php',
'Grav\\Common\\Filesystem\\File\\Yaml' => $baseDir . '/system/src/Grav/Common/Filesystem/File/Yaml.php',
'Grav\\Common\\Filesystem\\Folder' => $baseDir . '/system/src/Grav/Common/Filesystem/Folder.php',
'Grav\\Common\\Filesystem\\GravRecursiveFilterIterator' => $baseDir . '/system/src/Grav/Common/Filesystem/Folder.php',
'Grav\\Common\\Getters' => $baseDir . '/system/src/Grav/Common/Getters.php',
'Grav\\Common\\Grav' => $baseDir . '/system/src/Grav/Common/Grav.php',
'Grav\\Common\\GravTrait' => $baseDir . '/system/src/Grav/Common/GravTrait.php',
@@ -131,6 +132,7 @@ return array(
'Minify_Cache_XCache' => $vendorDir . '/mrclay/minify/min/lib/Minify/Cache/XCache.php',
'Minify_Cache_ZendPlatform' => $vendorDir . '/mrclay/minify/min/lib/Minify/Cache/ZendPlatform.php',
'Minify_ClosureCompiler' => $vendorDir . '/mrclay/minify/min/lib/Minify/ClosureCompiler.php',
'Minify_ClosureCompiler_Exception' => $vendorDir . '/mrclay/minify/min/lib/Minify/ClosureCompiler.php',
'Minify_CommentPreserver' => $vendorDir . '/mrclay/minify/min/lib/Minify/CommentPreserver.php',
'Minify_Controller_Base' => $vendorDir . '/mrclay/minify/min/lib/Minify/Controller/Base.php',
'Minify_Controller_Files' => $vendorDir . '/mrclay/minify/min/lib/Minify/Controller/Files.php',

View File

@@ -6,8 +6,8 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
$vendorDir . '/tracy/tracy/src/shortcuts.php',
$vendorDir . '/ircmaxell/password-compat/lib/password.php',
$vendorDir . '/donatj/phpuseragentparser/Source/UserAgentParser.php',
$vendorDir . '/tracy/tracy/src/shortcuts.php',
$baseDir . '/system/defines.php',
);

View File

@@ -2,7 +2,7 @@
// autoload_real.php @generated by Composer
class ComposerAutoloaderInitc72d8fa047c31604816395255e8b35b9
class ComposerAutoloaderInit836e000af2692cba78dada56c083fe42
{
private static $loader;
@@ -19,9 +19,9 @@ class ComposerAutoloaderInitc72d8fa047c31604816395255e8b35b9
return self::$loader;
}
spl_autoload_register(array('ComposerAutoloaderInitc72d8fa047c31604816395255e8b35b9', 'loadClassLoader'), true, true);
spl_autoload_register(array('ComposerAutoloaderInit836e000af2692cba78dada56c083fe42', 'loadClassLoader'), true, true);
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
spl_autoload_unregister(array('ComposerAutoloaderInitc72d8fa047c31604816395255e8b35b9', 'loadClassLoader'));
spl_autoload_unregister(array('ComposerAutoloaderInit836e000af2692cba78dada56c083fe42', 'loadClassLoader'));
$map = require __DIR__ . '/autoload_namespaces.php';
foreach ($map as $namespace => $path) {
@@ -42,14 +42,14 @@ class ComposerAutoloaderInitc72d8fa047c31604816395255e8b35b9
$includeFiles = require __DIR__ . '/autoload_files.php';
foreach ($includeFiles as $file) {
composerRequirec72d8fa047c31604816395255e8b35b9($file);
composerRequire836e000af2692cba78dada56c083fe42($file);
}
return $loader;
}
}
function composerRequirec72d8fa047c31604816395255e8b35b9($file)
function composerRequire836e000af2692cba78dada56c083fe42($file)
{
require $file;
}

View File

@@ -116,48 +116,6 @@
"caching"
]
},
{
"name": "mrclay/minify",
"version": "2.2.0",
"version_normalized": "2.2.0.0",
"source": {
"type": "git",
"url": "https://github.com/mrclay/minify.git",
"reference": "d245bca4987dec197d1e6d7dc117614b60ff7494"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mrclay/minify/zipball/d245bca4987dec197d1e6d7dc117614b60ff7494",
"reference": "d245bca4987dec197d1e6d7dc117614b60ff7494",
"shasum": ""
},
"require": {
"ext-pcre": "*",
"php": ">=5.2.1"
},
"time": "2014-03-12 12:54:23",
"type": "library",
"installation-source": "dist",
"autoload": {
"classmap": [
"min/lib/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Steve Clay",
"email": "steve@mrclay.org",
"homepage": "http://www.mrclay.org/",
"role": "Developer"
}
],
"description": "Minify is a PHP5 app that helps you follow several rules for client-side performance. It combines multiple CSS or Javascript files, removes unnecessary whitespace and comments, and serves them with gzip encoding and optimal client-side cache headers",
"homepage": "http://code.google.com/p/minify/"
},
{
"name": "pimple/pimple",
"version": "v3.0.0",
@@ -371,62 +329,6 @@
"description": "Symfony EventDispatcher Component",
"homepage": "http://symfony.com"
},
{
"name": "tracy/tracy",
"version": "v2.2.2",
"version_normalized": "2.2.2.0",
"source": {
"type": "git",
"url": "https://github.com/nette/tracy.git",
"reference": "f5a2647c9d0174d218d626eab3952ea3a523c6e7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/tracy/zipball/f5a2647c9d0174d218d626eab3952ea3a523c6e7",
"reference": "f5a2647c9d0174d218d626eab3952ea3a523c6e7",
"shasum": ""
},
"require": {
"php": ">=5.3.1"
},
"require-dev": {
"nette/tester": "~1.0"
},
"time": "2014-06-24 01:18:03",
"type": "library",
"installation-source": "dist",
"autoload": {
"classmap": [
"src/Tracy"
],
"files": [
"src/shortcuts.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause",
"GPL-2.0",
"GPL-3.0"
],
"authors": [
{
"name": "David Grudl",
"homepage": "http://davidgrudl.com"
},
{
"name": "Nette Community",
"homepage": "http://nette.org/contributors"
}
],
"description": "Tracy: useful PHP debugger",
"homepage": "http://tracy.nette.org",
"keywords": [
"debug",
"debugger",
"nette"
]
},
{
"name": "gregwar/cache",
"version": "v1.0.7",
@@ -666,6 +568,62 @@
"useragent"
]
},
{
"name": "tracy/tracy",
"version": "v2.2.3",
"version_normalized": "2.2.3.0",
"source": {
"type": "git",
"url": "https://github.com/nette/tracy.git",
"reference": "97889d2b8cfb7607cc370ca0ddb97c6f5b43deb9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/tracy/zipball/97889d2b8cfb7607cc370ca0ddb97c6f5b43deb9",
"reference": "97889d2b8cfb7607cc370ca0ddb97c6f5b43deb9",
"shasum": ""
},
"require": {
"php": ">=5.3.1"
},
"require-dev": {
"nette/tester": "~1.0"
},
"time": "2014-08-24 23:36:30",
"type": "library",
"installation-source": "dist",
"autoload": {
"classmap": [
"src/Tracy"
],
"files": [
"src/shortcuts.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause",
"GPL-2.0",
"GPL-3.0"
],
"authors": [
{
"name": "David Grudl",
"homepage": "http://davidgrudl.com"
},
{
"name": "Nette Community",
"homepage": "http://nette.org/contributors"
}
],
"description": "Tracy: useful PHP debugger",
"homepage": "http://tracy.nette.org",
"keywords": [
"debug",
"debugger",
"nette"
]
},
{
"name": "erusev/parsedown-extra",
"version": "dev-master",
@@ -673,18 +631,18 @@
"source": {
"type": "git",
"url": "https://github.com/erusev/parsedown-extra.git",
"reference": "7578fe28ce42e7a1fff4ba2aada3807c4c03d04b"
"reference": "424e63fef5299f2a5a0464cd22a666b7a7b48657"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/erusev/parsedown-extra/zipball/7578fe28ce42e7a1fff4ba2aada3807c4c03d04b",
"reference": "7578fe28ce42e7a1fff4ba2aada3807c4c03d04b",
"url": "https://api.github.com/repos/erusev/parsedown-extra/zipball/424e63fef5299f2a5a0464cd22a666b7a7b48657",
"reference": "424e63fef5299f2a5a0464cd22a666b7a7b48657",
"shasum": ""
},
"require": {
"erusev/parsedown": "~1.0"
},
"time": "2014-08-16 11:20:35",
"time": "2014-08-25 10:49:57",
"type": "library",
"installation-source": "source",
"autoload": {
@@ -711,5 +669,51 @@
"parsedown",
"parser"
]
},
{
"name": "mrclay/minify",
"version": "dev-master",
"version_normalized": "9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/rhukster/minify.git",
"reference": "fdf68abf30ccd86a65f66fa6eb98434eb29bef74"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rhukster/minify/zipball/fdf68abf30ccd86a65f66fa6eb98434eb29bef74",
"reference": "fdf68abf30ccd86a65f66fa6eb98434eb29bef74",
"shasum": ""
},
"require": {
"ext-pcre": "*",
"php": ">=5.2.1"
},
"time": "2014-08-29 23:07:55",
"type": "library",
"installation-source": "source",
"autoload": {
"classmap": [
"min/lib/"
]
},
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Stephen Clay",
"email": "steve@mrclay.org",
"role": "Developer"
}
],
"description": "Minify is a PHP5 app that helps you follow several rules for client-side performance. It combines multiple CSS or Javascript files, removes unnecessary whitespace and comments, and serves them with gzip encoding and optimal client-side cache headers",
"homepage": "http://code.google.com/p/minify/",
"support": {
"email": "minify@googlegroups.com",
"issues": "http://code.google.com/p/minify/issues/list",
"wiki": "http://code.google.com/p/minify/w/list",
"source": "https://github.com/rhukster/minify/tree/master"
}
}
]

View File

@@ -166,7 +166,12 @@ class ParsedownExtra extends Parsedown
{
$DOMDocument = new DOMDocument;
$DOMDocument->loadXML($Block['element']);
$DOMDocument->loadXML($Block['element'], LIBXML_NOERROR | LIBXML_NOWARNING);
if ($DOMDocument->documentElement === null)
{
return $Block;
}
$result = $DOMDocument->documentElement->getAttribute('markdown');

View File

@@ -1,5 +1,8 @@
Minify Release History
(master)
* Builder styled with Bootstrap (thanks to help from acidvertigo)
Version 2.2.0
* Fix handling of RegEx in certain situations in JSMin
* Thanks to Vovan-VE for reporting this

View File

@@ -325,6 +325,10 @@ class CSSmin
// @media screen and (-webkit-min-device-pixel-ratio:0){
$css = preg_replace('/\band\(/i', 'and (', $css);
// Put the space back in for @support tag
// @supports (display: flex) and @supports not (display: flex)
$css = preg_replace('/\b(supports|not)\(/i', '$1 (', $css);
// Remove the spaces after the things that should not have spaces after them.
$css = preg_replace('/([\!\{\}\:;\>\+\(\[\~\=,])\s+/S', '$1', $css);
@@ -772,4 +776,4 @@ class CSSmin
return (int) $size;
}
}
}

View File

@@ -70,7 +70,7 @@ class Minify_CSS_UriRewriter {
// rewrite
$css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
,array(self::$className, '_processUriCB'), $css);
$css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
$css = preg_replace_callback('/url\\(\\s*([\'"](.*?)[\'"]|[^\\)\\s]+)\\s*\\)/'
,array(self::$className, '_processUriCB'), $css);
return $css;
@@ -94,7 +94,7 @@ class Minify_CSS_UriRewriter {
// append
$css = preg_replace_callback('/@import\\s+([\'"])(.*?)[\'"]/'
,array(self::$className, '_processUriCB'), $css);
$css = preg_replace_callback('/url\\(\\s*([^\\)\\s]+)\\s*\\)/'
$css = preg_replace_callback('/url\\(\\s*([\'"](.*?)[\'"]|[^\\)\\s]+)\\s*\\)/'
,array(self::$className, '_processUriCB'), $css);
self::$_prependPath = null;

View File

@@ -98,6 +98,9 @@ class Minify_Cache_File {
{
if ($this->_locking) {
$fp = fopen($this->_path . '/' . $id, 'rb');
if (!$fp) {
return false;
}
flock($fp, LOCK_SH);
$ret = stream_get_contents($fp);
flock($fp, LOCK_UN);

View File

@@ -33,6 +33,11 @@
*/
class Minify_ClosureCompiler {
const OPTION_CHARSET = 'charset';
const OPTION_COMPILATION_LEVEL = 'compilation_level';
public static $isDebug = false;
/**
* Filepath of the Closure Compiler jar file. This must be set before
* calling minifyJs().
@@ -65,18 +70,28 @@ class Minify_ClosureCompiler {
* @see https://code.google.com/p/closure-compiler/source/browse/trunk/README
*
* @return string
*
* @throws Minify_ClosureCompiler_Exception
*/
public static function minify($js, $options = array())
{
self::_prepare();
if (! ($tmpFile = tempnam(self::$tempDir, 'cc_'))) {
throw new Exception('Minify_ClosureCompiler : could not create temp file in "'.self::$tempDir.'".');
throw new Minify_ClosureCompiler_Exception('Minify_ClosureCompiler : could not create temp file in "'.self::$tempDir.'".');
}
file_put_contents($tmpFile, $js);
exec(self::_getCmd($options, $tmpFile), $output, $result_code);
$cmd = self::_getCmd($options, $tmpFile);
exec($cmd, $output, $result_code);
unlink($tmpFile);
if ($result_code != 0) {
throw new Exception('Minify_ClosureCompiler : Closure Compiler execution failed.');
$message = 'Minify_ClosureCompiler : Closure Compiler execution failed.';
if (self::$isDebug) {
exec($cmd . ' 2>&1', $error);
if ($error) {
$message .= "\nReason:\n" . join("\n", $error);
}
}
throw new Minify_ClosureCompiler_Exception($message);
}
return implode("\n", $output);
}
@@ -85,17 +100,18 @@ class Minify_ClosureCompiler {
{
$o = array_merge(
array(
'charset' => 'utf-8',
'compilation_level' => 'SIMPLE_OPTIMIZATIONS',
self::OPTION_CHARSET => 'utf-8',
self::OPTION_COMPILATION_LEVEL => 'SIMPLE_OPTIMIZATIONS',
),
$userOptions
);
$charsetOption = $o[self::OPTION_CHARSET];
$cmd = self::$javaExecutable . ' -jar ' . escapeshellarg(self::$jarFile)
. (preg_match('/^[\\da-zA-Z0-9\\-]+$/', $o['charset'])
? " --charset {$o['charset']}"
. (preg_match('/^[\\da-zA-Z0-9\\-]+$/', $charsetOption)
? " --charset {$charsetOption}"
: '');
foreach (array('compilation_level') as $opt) {
foreach (array(self::OPTION_COMPILATION_LEVEL) as $opt) {
if ($o[$opt]) {
$cmd .= " --{$opt} ". escapeshellarg($o[$opt]);
}
@@ -106,18 +122,18 @@ class Minify_ClosureCompiler {
private static function _prepare()
{
if (! is_file(self::$jarFile)) {
throw new Exception('Minify_ClosureCompiler : $jarFile('.self::$jarFile.') is not a valid file.');
throw new Minify_ClosureCompiler_Exception('Minify_ClosureCompiler : $jarFile('.self::$jarFile.') is not a valid file.');
}
if (! is_readable(self::$jarFile)) {
throw new Exception('Minify_ClosureCompiler : $jarFile('.self::$jarFile.') is not readable.');
throw new Minify_ClosureCompiler_Exception('Minify_ClosureCompiler : $jarFile('.self::$jarFile.') is not readable.');
}
if (! is_dir(self::$tempDir)) {
throw new Exception('Minify_ClosureCompiler : $tempDir('.self::$tempDir.') is not a valid direcotry.');
throw new Minify_ClosureCompiler_Exception('Minify_ClosureCompiler : $tempDir('.self::$tempDir.') is not a valid direcotry.');
}
if (! is_writable(self::$tempDir)) {
throw new Exception('Minify_ClosureCompiler : $tempDir('.self::$tempDir.') is not writable.');
throw new Minify_ClosureCompiler_Exception('Minify_ClosureCompiler : $tempDir('.self::$tempDir.') is not writable.');
}
}
}
/* vim:ts=4:sw=4:et */
class Minify_ClosureCompiler_Exception extends Exception {}

View File

@@ -103,6 +103,9 @@ class Debugger
/** @var string name of the directory where errors should be logged */
public static $logDirectory;
/** @var int log bluescreen in production mode for this error severity */
public static $logSeverity = 0;
/** @var string|array email(s) to which send error notifications */
public static $email;
@@ -475,6 +478,12 @@ class Debugger
} elseif (($severity & error_reporting()) !== $severity) {
return FALSE; // calls normal error handler to fill-in error_get_last()
} elseif (($severity & self::$logSeverity) === $severity) {
$e = new ErrorException($message, 0, $severity, $file, $line);
$e->context = $context;
self::log($e, self::ERROR);
return NULL;
} elseif (!self::$productionMode && (is_bool(self::$strictMode) ? self::$strictMode : ((self::$strictMode & $severity) === $severity))) {
$e = new ErrorException($message, 0, $severity, $file, $line);
$e->context = $context;

View File

@@ -79,6 +79,7 @@ class Helpers
}
/** @internal */
public static function fixStack($exception)
{
if (function_exists('xdebug_get_function_stack')) {
@@ -104,11 +105,7 @@ class Helpers
}
/**
* Returns correctly UTF-8 encoded string.
* @param string byte stream to fix
* @return string
*/
/** @internal */
public static function fixEncoding($s)
{
if (PHP_VERSION_ID < 50400) {

View File

@@ -72,6 +72,7 @@ class Logger
* @param string
* @param string
* @return void
* @internal
*/
public static function defaultMailer($message, $email)
{

View File

@@ -42,6 +42,7 @@ class OutputDebugger
}
/** @internal */
public function handler($s, $phase)
{
$trace = debug_backtrace(FALSE);
@@ -62,7 +63,6 @@ class OutputDebugger
{
$res = '<style>code, pre {white-space:nowrap} a {text-decoration:none} pre {color:gray;display:inline} big {color:red}</style><code>';
foreach ($this->list as $item) {
list($file, $line, $s) = $item;
$res .= Helpers::editorLink($item[0], $item[1]) . ' '
. str_replace(self::BOM, '<big>BOM</big>', Dumper::toHtml($item[2])) . "<br>\n";
}

View File

@@ -14,6 +14,7 @@ html {
background: white;
color: #333;
position: absolute;
z-index: 20000;
left: 0;
top: 0;
width: 100%;
@@ -54,7 +55,6 @@ html {
position: absolute;
right: .5em;
top: .5em;
z-index: 20000;
text-decoration: none;
background: #CD1818;
color: white !important;

View File

@@ -117,7 +117,7 @@ $counter = 0;
<i>inner-code</i><?php if (isset($row['line'])) echo ':', $row['line'] ?>
<?php endif ?>
<?php if (isset($row['file']) && is_file($row['file'])): ?><a href="#tracyBsSrc<?php echo "$level-$key" ?>" class="tracy-toggle tracy-collapsed">source</a>&nbsp; <?php endif ?>
<?php if (isset($row['file']) && is_file($row['file'])): ?><a href="#tracyBsSrc<?php echo "$level-$key" ?>" class="tracy-toggle<?php if ($expanded !== $key) echo ' tracy-collapsed' ?>">source</a>&nbsp; <?php endif ?>
<?php if (isset($row['object'])) echo "<a href='#tracyBsObj$level-$key' class='tracy-toggle tracy-collapsed'>" ?>
<?php if (isset($row['class'])) echo htmlspecialchars($row['class'] . $row['type']) ?>
@@ -128,11 +128,11 @@ $counter = 0;
</p>
<?php if (isset($row['file']) && is_file($row['file'])): ?>
<div <?php if ($expanded !== $key) echo 'class="tracy-collapsed"'; ?> id="tracyBsSrc<?php echo "$level-$key" ?>"><?php echo self::highlightFile($row['file'], $row['line']) ?></div>
<div <?php if ($expanded !== $key) echo 'class="tracy-collapsed"' ?> id="tracyBsSrc<?php echo "$level-$key" ?>"><?php echo self::highlightFile($row['file'], $row['line']) ?></div>
<?php endif ?>
<?php if (isset($row['object'])): ?>
<div class="tracy-collapsed outer" id="tracyBsObj<?php echo "$level-$key" ?>"><?php echo Dumper::toHtml($row['object']); ?></div>
<div class="tracy-collapsed outer" id="tracyBsObj<?php echo "$level-$key" ?>"><?php echo Dumper::toHtml($row['object']) ?></div>
<?php endif ?>
<?php if (!empty($row['args'])): ?>