Merge branch 'release/0.9.5'

This commit is contained in:
Andy Miller
2014-11-09 19:20:39 -07:00
17 changed files with 191 additions and 70 deletions

View File

@@ -1,3 +1,26 @@
# v0.9.5 beta
## 11/09/2014
1. [](#new)
* Added quality setting to medium for compression configuration of images
* Added new onPageContentProcessed() event that is post-content processing but pre-caching
2. [](#improved)
* Added support for AND and OR taxonomy filtering. AND by default (was OR)
* Added specific clearing options for CLI clear-cache command
* Moved environment method to URI so it can be accessible in plugins and themes
* Set Grav's output variable to public so it can be manipulated in onOutputGenerated event
* Updated vendor libraries to latest versions
* Better handing of 'home' in active menu state detection
* Various PSR code tidying
* Improved some error messages and notices
3. [](#bugfix)
* Force route rebuild when configuration changes
* Fix for 'installed undefined' error in CLI versions command
* Do not remove the JSON/Text error handlers
* Fix for supporting inline JS and CSS when Asset pipeline enabled
* Fix for Data URLs in CSS being badly formed
* Fix Markdown links with fragment and query elements
# v0.9.4 beta
## 10/29/2014

View File

@@ -27,10 +27,6 @@
{
"type": "vcs",
"url": "https://github.com/rockettheme/toolbox"
},
{
"type": "vcs",
"url": "https://github.com/rhukster/minify"
}
],
"autoload": {

View File

@@ -2,7 +2,7 @@
// Some standard defines
define('GRAV', true);
define('GRAV_VERSION', '0.9.4');
define('GRAV_VERSION', '0.9.5');
define('DS', '/');
// Directories and Paths

View File

@@ -338,12 +338,10 @@ class Assets
foreach ($this->css_no_pipeline as $file) {
$output .= '<link href="'.$file['asset'].'"'.$attributes.' />'."\n";
}
return $output;
}
foreach($this->css as $file) {
$output .= '<link href="' . $file['asset'] . '"' . $attributes . ' />' . "\n";
} else {
foreach($this->css as $file) {
$output .= '<link href="' . $file['asset'] . '"' . $attributes . ' />' . "\n";
}
}
// Render Inline CSS
@@ -387,12 +385,10 @@ class Assets
foreach ($this->js_no_pipeline as $file) {
$output .= '<script src="'.$file['asset'].'"'.$attributes.' ></script>'."\n";
}
return $output;
}
foreach($this->js as $file) {
$output .= '<script src="' . $file['asset'] . '"' . $attributes . ' ></script>' . "\n";
} else {
foreach($this->js as $file) {
$output .= '<script src="' . $file['asset'] . '"' . $attributes . ' ></script>' . "\n";
}
}
// Render Inline JS
@@ -632,6 +628,10 @@ class Assets
function($matches) use ($relative_path) {
$old_url = $matches[1];
// ensure this is not a data url
if (strpos($old_url, 'data:') === 0) return $matches[0];
$newpath = array();
$paths = explode('/', $old_url);

View File

@@ -45,8 +45,6 @@ class Errors extends \Whoops\Run
$config = $grav['config']->get('system.errors');
if (isset($config['display']) && !$config['display']) {
unset($this->handlerStack['pretty']);
unset($this->handlerStack['text']);
unset($this->handlerStack['json']);
$this->handlerStack = array('simple' => new SimplePageHandler()) + $this->handlerStack;
}
if (isset($config['log']) && !$config['log']) {

View File

@@ -25,7 +25,7 @@ class Grav extends Container
/**
* @var string
*/
protected $output;
public $output;
/**
* @var static
@@ -112,7 +112,7 @@ class Grav extends Container
$medium = $media[$media_file];
// loop through actions for the image and call them
foreach ($c['uri']->query(null,true) as $action => $params) {
foreach ($c['uri']->query(null, true) as $action => $params) {
if (in_array($action, Medium::$valid_actions)) {
call_user_func_array(array(&$medium, $action), explode(',', $params));
}
@@ -294,7 +294,7 @@ class Grav extends Container
*/
public function shutdown()
{
if($this['config']->get('system.debugger.shutdown.close_connection')) {
if ($this['config']->get('system.debugger.shutdown.close_connection')) {
set_time_limit(0);
ignore_user_abort(true);

View File

@@ -33,7 +33,7 @@ trait MarkdownGravLinkTrait
if (!isset($url['host']) && isset($url['path'])) {
// convert the URl is required
$Excerpt['element']['attributes']['href'] = $this->convertUrl($url['path']);
$Excerpt['element']['attributes']['href'] = $this->convertUrl(Uri::build_url($url));
}
}

View File

@@ -114,6 +114,16 @@ class Medium extends Data
return $output;
}
/**
* Sets the quality of the image
* @param Int $quality 0-100 quality
* @return Medium
*/
public function quality($quality) {
$this->quality = $quality;
return $this;
}
/**
* Return URL to file.
*
@@ -149,6 +159,7 @@ class Medium extends Data
$this->type = $type;
$this->quality = $quality;
return $this;
}
/**

View File

@@ -358,11 +358,34 @@ class Page
$this->content = $content;
// Process any post-processing but pre-caching functionality
self::$grav->fireEvent('onPageContentProcessed', new Event(['page' => $this]));
}
return $this->content;
}
/**
* Needed by the onPageContentProcessed event to get the raw page content
*
* @return string the current page content
*/
public function getRawContent()
{
return $this->content;
}
/**
* Needed by the onPageContentProcessed event to set the raw page content
*
* @param $content
*/
public function setRawContent($content)
{
$this->content = $content;
}
/**
* Get value from a page variable (used mostly for creating edit forms).
*
@@ -1326,10 +1349,21 @@ class Page
{
/** @var Uri $uri */
$uri = self::$grav['uri'];
$config = self::$grav['config'];
if (!$this->home() && (strpos($uri->url(), $this->url()) === 0)) {
return true;
// Special check when item is home
if ($this->home()) {
$paths = $uri->paths();
$home = ltrim($config->get('system.home.alias'), '/');
if ($paths[0] == $home) {
return true;
}
} else {
if (strpos($uri->url(), $this->url()) === 0) {
return true;
}
}
return false;
}
@@ -1418,8 +1452,6 @@ class Page
}
}
}
$config->set('system.cache.enabled', false); // TODO: Do we still need this?
}
}
// TODO: END OF MOVE

View File

@@ -206,7 +206,9 @@ class Pages
*/
public function get($path)
{
if (!is_null($path) && !is_string($path)) throw new \Exception();
if (!is_null($path) && !is_string($path)) {
throw new \Exception();
}
return isset($this->instances[(string) $path]) ? $this->instances[(string) $path] : null;
}
@@ -319,7 +321,7 @@ class Pages
*
* @return Types
*/
static public function getTypes()
public static function getTypes()
{
if (!self::$types) {
self::$types = new Types();
@@ -339,7 +341,7 @@ class Pages
*
* @return array
*/
static public function types()
public static function types()
{
$types = self::getTypes();
@@ -351,7 +353,7 @@ class Pages
*
* @return array
*/
static public function modularTypes()
public static function modularTypes()
{
$types = self::getTypes();
@@ -363,7 +365,7 @@ class Pages
*
* @return array
*/
static public function parents()
public static function parents()
{
$grav = Grav::instance();
@@ -404,10 +406,11 @@ class Pages
$last_modified = Folder::lastModifiedFile(PAGES_DIR);
}
$page_cache_id = md5(USER_DIR.$last_modified);
$page_cache_id = md5(USER_DIR.$last_modified.$config->checksum());
list($this->instances, $this->routes, $this->children, $taxonomy_map, $this->sort) = $cache->fetch($page_cache_id);
if (!$this->instances) {
$this->grav['debugger']->addMessage('Page cache missed, rebuilding pages..');
$this->recurse();
$this->buildRoutes();
@@ -418,6 +421,7 @@ class Pages
);
} else {
// If pages was found in cache, set the taxonomy
$this->grav['debugger']->addMessage('Page cache hit.');
$taxonomy->taxonomy($taxonomy_map);
}
} else {
@@ -445,7 +449,9 @@ class Pages
$config = $this->grav['config'];
$page->path($directory);
if ($parent) $page->parent($parent);
if ($parent) {
$page->parent($parent);
}
$page->orderDir($config->get('system.pages.order.dir'));
$page->orderBy($config->get('system.pages.order.by'));
@@ -608,7 +614,7 @@ class Pages
// handle special case when order_by is random
if ($order_by == 'random') {
$list = $this->array_shuffle($list);
$list = $this->arrayShuffle($list);
} else {
// else just sort the list according to specified key
asort($list);
@@ -643,12 +649,13 @@ class Pages
}
// Shuffles and associative array
protected function array_shuffle($list) {
protected function arrayShuffle($list)
{
$keys = array_keys($list);
shuffle($keys);
$new = array();
foreach($keys as $key) {
foreach ($keys as $key) {
$new[$key] = $list[$key];
}

View File

@@ -3,6 +3,7 @@ namespace Grav\Common\Service;
use Grav\Common\Config\Config;
use Grav\Common\Grav;
use Grav\Common\Uri;
use Grav\Common\Filesystem\Folder;
use Pimple\Container;
use Pimple\ServiceProviderInterface;
@@ -33,7 +34,7 @@ class ConfigServiceProvider implements ServiceProviderInterface
public function loadMasterConfig(Container $container)
{
$environment = $this->getEnvironment();
$environment = $this->getEnvironment($container);
$file = CACHE_DIR . 'compiled/config/master-'.$environment.'.php';
$data = is_file($file) ? (array) include $file : [];
if ($data) {
@@ -54,25 +55,17 @@ class ConfigServiceProvider implements ServiceProviderInterface
public function loadMasterBlueprints(Container $container)
{
$environment = $this->getEnvironment();
$environment = $this->getEnvironment($container);
$file = CACHE_DIR . 'compiled/blueprints/master-'.$environment.'.php';
$data = is_file($file) ? (array) include $file : [];
return new Blueprints($data, $container);
}
public function getEnvironment()
public function getEnvironment(Container $container)
{
if (!$this->environment) {
$address = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '::1';
// check for localhost variations
if ($address == '::1' || $address == '127.0.0.1') {
$hostname = 'localhost';
} else {
$hostname = gethostname();
}
$this->environment = $hostname;
if (!isset($this->environment)) {
$this->environment = $container['uri']->environment();
}
return $this->environment;

View File

@@ -71,20 +71,33 @@ class Taxonomy
* particular taxonomy.
*
* @param array $taxonomies taxonomies to search, eg ['tag'=>['animal','cat']]
* @return Page page object with sub-pages set to contain matches found in the taxonomy map
* @param string $operator can be 'or' or 'and' (defaults to 'or')
* @return Colleciton Collection object set to contain matches found in the taxonomy map
*/
public function findTaxonomy($taxonomies)
public function findTaxonomy($taxonomies, $operator = 'and')
{
$results = array();
$matches = [];
$results = [];
foreach ((array)$taxonomies as $taxonomy => $items) {
foreach ((array) $items as $item) {
if (isset($this->taxonomy_map[$taxonomy][$item])) {
$results = array_merge($results, $this->taxonomy_map[$taxonomy][$item]);
$matches[] = $this->taxonomy_map[$taxonomy][$item];
}
}
}
if (strtolower($operator) == 'or') {
foreach ($matches as $match) {
$results = array_merge($results, $match);
}
} else {
$results = $matches ? array_pop($matches) : [];
foreach ($matches as $match) {
$results = array_intersect_key($results, $match);
}
}
return new Collection($results, ['taxonomies' => $taxonomies]);
}

View File

@@ -37,7 +37,12 @@ class Themes extends Iterator
/** @var Themes $themes */
$themes = $this->grav['themes'];
$themes->configure();
$instance = $themes->load();
try {
$instance = $themes->load();
} catch (\InvalidArgumentException $e) {
throw new \RuntimeException($this->current(). ' theme could not be found');
}
if ($instance instanceof EventSubscriberInterface) {
$events->addSubscriber($instance);

View File

@@ -240,7 +240,7 @@ class Twig
try {
$output = $this->twig->render($template, $twig_vars);
} catch (\Twig_Error_Loader $e) {
throw new \RuntimeException('Twig template not found: '.$template, 404, $e);
throw new \RuntimeException($e->getRawMessage(), 404, $e);
}
return $output;

View File

@@ -9,6 +9,8 @@ namespace Grav\Common;
*/
class Uri
{
public $url;
protected $base;
protected $root;
protected $bits;
@@ -17,7 +19,6 @@ class Uri
protected $content_path;
protected $path;
protected $paths;
protected $url;
protected $query;
protected $params;
@@ -50,6 +51,16 @@ class Uri
$root_path = substr($uri, 0, strpos($uri, '/', 1)) . $root_path;
}
// set hostname
$address = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '::1';
// check for localhost variations
if ($address == '::1' || $address == '127.0.0.1') {
$this->host = 'localhost';
} else {
$this->host = gethostname();
}
$this->base = $base;
$this->root = $base . $root_path;
$this->url = $base . $uri;
@@ -120,7 +131,7 @@ class Uri
if (isset($id)) {
return $this->paths[$id];
} else {
return implode('/', $this->paths);
return $this->paths;
}
}
@@ -213,7 +224,8 @@ class Uri
*
* @return String The path of the URI
*/
public function path() {
public function path()
{
return $this->path;
}
@@ -222,7 +234,8 @@ class Uri
*
* @return String The extension of the URI
*/
public function extension($default = null) {
public function extension($default = null)
{
if (!$this->extension) {
$this->extension = $default;
}
@@ -234,16 +247,28 @@ class Uri
*
* @return String The host of the URI
*/
public function host() {
public function host()
{
return $this->host;
}
/**
* Gets the environment name
*
* @return String
*/
public function environment()
{
return $this->host();
}
/**
* Return the base of the URI
*
* @return String The base of the URI
*/
public function base() {
public function base()
{
return $this->base;
}
@@ -340,7 +365,8 @@ class Uri
* @param $parsed_url
* @return string
*/
public static function build_url($parsed_url) {
public static function build_url($parsed_url)
{
$scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
$host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
$port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';

View File

@@ -17,9 +17,6 @@ use Symfony\Component\Yaml\Yaml;
class ClearCacheCommand extends Command
{
/**
* @var array
*/
protected $standard_remove = [
'cache/twig/',
'cache/doctrine/',
@@ -29,15 +26,24 @@ class ClearCacheCommand extends Command
'assets/',
];
/**
* @var array
*/
protected $all_remove = [
'cache/',
'images/',
'assets/'
];
protected $assets_remove = [
'assets/'
];
protected $images_remove = [
'images/'
];
protected $cache_remove = [
'cache/'
];
/**
*
*/
@@ -46,7 +52,10 @@ class ClearCacheCommand extends Command
$this
->setName("clear-cache")
->setDescription("Clears Grav cache")
->addOption('all', null, InputOption::VALUE_NONE, 'If set will remove all')
->addOption('all', null, InputOption::VALUE_NONE, 'If set will remove all including compiled, twig, doctrine caches')
->addOption('assets-only', null, InputOption::VALUE_NONE, 'If set will remove only assets/*')
->addOption('images-only', null, InputOption::VALUE_NONE, 'If set will remove only images/*')
->addOption('cache-only', null, InputOption::VALUE_NONE, 'If set will remove only cache/*')
->setHelp('The <info>clear-cache</info> deletes all cache files');
}
@@ -84,6 +93,12 @@ class ClearCacheCommand extends Command
if ($input->getOption('all')) {
$remove_paths = $this->all_remove;
} elseif ($input->getOption('assets-only')) {
$remove_paths = $this->assets_remove;
} elseif ($input->getOption('images-only')) {
$remove_paths = $this->images_remove;
} elseif ($input->getOption('cache-only')) {
$remove_paths = $this->cache_remove;
} else {
$remove_paths = $this->standard_remove;
}

View File

@@ -58,6 +58,8 @@ class VersionCommand extends Command
$this->gpm = new GPM($this->input->getOption('force'));
$packages = $this->input->getArgument('package');
$installed = false;
if (!count($packages)) {
$packages = ['grav'];
}