diff --git a/CHANGELOG.md b/CHANGELOG.md index 972507d9c..6d81ab63e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/composer.json b/composer.json index 70ad4cbc6..236f32257 100644 --- a/composer.json +++ b/composer.json @@ -27,10 +27,6 @@ { "type": "vcs", "url": "https://github.com/rockettheme/toolbox" - }, - { - "type": "vcs", - "url": "https://github.com/rhukster/minify" } ], "autoload": { diff --git a/system/defines.php b/system/defines.php index 51b2203f2..8e7b035ef 100644 --- a/system/defines.php +++ b/system/defines.php @@ -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 diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index c89a6282f..4f332ab36 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -338,12 +338,10 @@ class Assets foreach ($this->css_no_pipeline as $file) { $output .= ''."\n"; } - return $output; - } - - - foreach($this->css as $file) { - $output .= '' . "\n"; + } else { + foreach($this->css as $file) { + $output .= '' . "\n"; + } } // Render Inline CSS @@ -387,12 +385,10 @@ class Assets foreach ($this->js_no_pipeline as $file) { $output .= ''."\n"; } - return $output; - } - - - foreach($this->js as $file) { - $output .= '' . "\n"; + } else { + foreach($this->js as $file) { + $output .= '' . "\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); diff --git a/system/src/Grav/Common/Errors/Errors.php b/system/src/Grav/Common/Errors/Errors.php index 591eba2b2..57dfbd85a 100644 --- a/system/src/Grav/Common/Errors/Errors.php +++ b/system/src/Grav/Common/Errors/Errors.php @@ -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']) { diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 35c8f6b1f..8ed8c499d 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -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); diff --git a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php index 7ac0b2000..1357c686b 100644 --- a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php +++ b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php @@ -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)); } } diff --git a/system/src/Grav/Common/Page/Medium.php b/system/src/Grav/Common/Page/Medium.php index bbee389c7..f98c0d2c3 100644 --- a/system/src/Grav/Common/Page/Medium.php +++ b/system/src/Grav/Common/Page/Medium.php @@ -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; } /** diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index c99e51f84..6a49b0a56 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -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 diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 23e30792f..9b58304e6 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -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]; } diff --git a/system/src/Grav/Common/Service/ConfigServiceProvider.php b/system/src/Grav/Common/Service/ConfigServiceProvider.php index a2885876f..0945ce038 100644 --- a/system/src/Grav/Common/Service/ConfigServiceProvider.php +++ b/system/src/Grav/Common/Service/ConfigServiceProvider.php @@ -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; diff --git a/system/src/Grav/Common/Taxonomy.php b/system/src/Grav/Common/Taxonomy.php index 1224cbee2..6ea5a3591 100644 --- a/system/src/Grav/Common/Taxonomy.php +++ b/system/src/Grav/Common/Taxonomy.php @@ -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]); } diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index eb580889c..f5648391c 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -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); diff --git a/system/src/Grav/Common/Twig.php b/system/src/Grav/Common/Twig.php index d10636f8e..acdf04bd0 100644 --- a/system/src/Grav/Common/Twig.php +++ b/system/src/Grav/Common/Twig.php @@ -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; diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index 3e914334d..4dbdb14d0 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -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'] : ''; diff --git a/system/src/Grav/Console/Cli/ClearCacheCommand.php b/system/src/Grav/Console/Cli/ClearCacheCommand.php index aaad55c9a..148d24634 100644 --- a/system/src/Grav/Console/Cli/ClearCacheCommand.php +++ b/system/src/Grav/Console/Cli/ClearCacheCommand.php @@ -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 clear-cache 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; } diff --git a/system/src/Grav/Console/Gpm/VersionCommand.php b/system/src/Grav/Console/Gpm/VersionCommand.php index 8840423d2..c1068d8ab 100644 --- a/system/src/Grav/Console/Gpm/VersionCommand.php +++ b/system/src/Grav/Console/Gpm/VersionCommand.php @@ -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']; }