From 2d95b3bb09032ce17d1e9cca6ecdba2ccf5e5c00 Mon Sep 17 00:00:00 2001 From: Jan Chren Date: Sun, 14 Sep 2014 22:44:59 +0200 Subject: [PATCH 01/55] PHPUnit testing introduced --- composer.json | 8 ++++++++ system/tests/Grav/Test/.gitkeep | 0 system/tests/Grav/TestCase.php | 8 ++++++++ system/tests/bootstrap.php | 6 ++++++ system/tests/phpunit.xml | 18 ++++++++++++++++++ 5 files changed, 40 insertions(+) create mode 100644 system/tests/Grav/Test/.gitkeep create mode 100644 system/tests/Grav/TestCase.php create mode 100644 system/tests/bootstrap.php create mode 100644 system/tests/phpunit.xml diff --git a/composer.json b/composer.json index 82067afc3..aee73b504 100644 --- a/composer.json +++ b/composer.json @@ -20,12 +20,20 @@ "donatj/phpuseragentparser": "dev-master", "pimple/pimple": "~3.0" }, + "require-dev": { + "phpunit/phpunit": "~4.2" + }, "autoload": { "psr-4": { "Grav\\": "system/src/Grav" }, "files": ["system/defines.php"] }, + "autoload-dev": { + "psr-4": { + "Grav\\Test\\": "system/tests/Grav/Test/" + } + }, "archive": { "exclude": ["VERSION"] }, diff --git a/system/tests/Grav/Test/.gitkeep b/system/tests/Grav/Test/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/system/tests/Grav/TestCase.php b/system/tests/Grav/TestCase.php new file mode 100644 index 000000000..718bbadcb --- /dev/null +++ b/system/tests/Grav/TestCase.php @@ -0,0 +1,8 @@ + + + + + ./Grav/ + + + From 260f200d6fa79c2c0f08fe09662b998489dce0a3 Mon Sep 17 00:00:00 2001 From: Jan Chren Date: Sun, 14 Sep 2014 23:08:56 +0200 Subject: [PATCH 02/55] fixed problems with multiloading of includes https://github.com/sebastianbergmann/phpunit/issues/314 --- system/tests/phpunit.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/tests/phpunit.xml b/system/tests/phpunit.xml index 9eb7c6526..e9695379b 100644 --- a/system/tests/phpunit.xml +++ b/system/tests/phpunit.xml @@ -5,7 +5,7 @@ convertErrorsToExceptions="true" convertNoticesToExceptions="true" convertWarningsToExceptions="true" - processIsolation="true" + processIsolation="false" stopOnFailure="false" syntaxCheck="false" bootstrap="./bootstrap.php" From a9894902be1f1a98b97aa1516862fe8e7ec975a7 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Sat, 10 Jan 2015 11:55:01 +0200 Subject: [PATCH 03/55] Fix RewriteBase getting run only after exploit checks in .htaccess --- htaccess.txt | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/htaccess.txt b/htaccess.txt index 4fd10f335..ce48b2674 100644 --- a/htaccess.txt +++ b/htaccess.txt @@ -2,6 +2,17 @@ RewriteEngine On +## Begin RewriteBase +# If you are getting 404 errors on subpages, you may have to uncomment the RewriteBase entry +# You should change the '/' to your appropriate subfolder. For example if you have +# your Grav install at the root of your site '/' should work, else it might be something +# along the lines of: RewriteBase / +## + +# RewriteBase / + +## End - RewriteBase + ## Begin - Exploits # If you experience problems on your site block out the operations listed below # This attempts to block the most common type of exploit `attempts` to Grav @@ -19,17 +30,6 @@ RewriteRule .* index.php [F] # ## End - Exploits -## Begin RewriteBase -# If you are getting 404 errors on subpages, you may have to uncomment the RewriteBase entry -# You should change the '/' to your appropriate subfolder. For example if you have -# your Grav install at the root of your site '/' should work, else it might be something -# along the lines of: RewriteBase / -## - -# RewriteBase / - -## End - RewriteBase - ## Begin - Index # If the requested path and file is not /index.php and the request # has not already been internally rewritten to the index.php script From dde6b2cd8b8012c7b74d3d04130746b48b98f216 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Sat, 10 Jan 2015 11:55:57 +0200 Subject: [PATCH 04/55] Add support for multiple configurations by setup.php --- .../src/Grav/Common/Service/ConfigServiceProvider.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/system/src/Grav/Common/Service/ConfigServiceProvider.php b/system/src/Grav/Common/Service/ConfigServiceProvider.php index 0945ce038..ce6b76fa0 100644 --- a/system/src/Grav/Common/Service/ConfigServiceProvider.php +++ b/system/src/Grav/Common/Service/ConfigServiceProvider.php @@ -18,11 +18,17 @@ use RocketTheme\Toolbox\Blueprints\Blueprints; class ConfigServiceProvider implements ServiceProviderInterface { private $environment; + private $setup; public function register(Container $container) { $self = $this; + // Pre-load setup.php as it contains our initial configuration. + $file = GRAV_ROOT . '/setup.php'; + $this->setup = is_file($file) ? (array) include $file : []; + $this->environment = isset($this->setup['environment']) ? $this->setup['environment'] : null; + $container['blueprints'] = function ($c) use ($self) { return $self->loadMasterBlueprints($c); }; @@ -45,9 +51,7 @@ class ConfigServiceProvider implements ServiceProviderInterface } if (!isset($config)) { - $file = GRAV_ROOT . '/setup.php'; - $data = is_file($file) ? (array) include $file : []; - $config = new Config($data, $container, $environment); + $config = new Config($this->setup, $container, $environment); } return $config; From 9ddfced969c1be33af3177a2983948d6e4dddc76 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Sat, 10 Jan 2015 14:23:16 +0200 Subject: [PATCH 05/55] Fix a bug with missing streams when configuration was not loaded from cache --- system/src/Grav/Common/Config/Config.php | 45 +++++++++++++++++++ .../Common/Service/StreamsServiceProvider.php | 38 ++++------------ 2 files changed, 54 insertions(+), 29 deletions(-) diff --git a/system/src/Grav/Common/Config/Config.php b/system/src/Grav/Common/Config/Config.php index 7cc1cce51..14cfffe61 100644 --- a/system/src/Grav/Common/Config/Config.php +++ b/system/src/Grav/Common/Config/Config.php @@ -168,6 +168,8 @@ class Config extends Data $this->loadCompiledBlueprints($this->blueprintLookup, $this->pluginLookup, 'master'); $this->loadCompiledConfig($this->configLookup, $this->pluginLookup, 'master'); + + $this->initializeLocator($locator); } public function checksum() @@ -331,4 +333,47 @@ class Config extends Data $this->join($name, $file->content(), '/'); } } + + /** + * Initialize resource locator by using the configuration. + * + * @param UniformResourceLocator $locator + */ + public function initializeLocator(UniformResourceLocator $locator) + { + $locator->reset(); + + $schemes = (array) $this->get('streams.schemes', []); + + 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); + } + } + } + } + + /** + * Get available streams and their types from the configuration. + * + * @return array + */ + public function getStreams() + { + $schemes = []; + foreach ((array) $this->get('streams.schemes') as $scheme => $config) { + $type = !empty($config['type']) ? $config['type'] : 'ReadOnlyStream'; + if ($type[0] != '\\') { + $type = '\\RocketTheme\\Toolbox\\StreamWrapper\\' . $type; + } + + $schemes[$scheme] = $type; + } + + return $schemes; + } } diff --git a/system/src/Grav/Common/Service/StreamsServiceProvider.php b/system/src/Grav/Common/Service/StreamsServiceProvider.php index 7cfa187eb..ae251cb72 100644 --- a/system/src/Grav/Common/Service/StreamsServiceProvider.php +++ b/system/src/Grav/Common/Service/StreamsServiceProvider.php @@ -11,52 +11,32 @@ use RocketTheme\Toolbox\StreamWrapper\StreamBuilder; class StreamsServiceProvider implements ServiceProviderInterface { - protected $schemes = []; - public function register(Container $container) { $self = $this; $container['locator'] = function($c) use ($self) { $locator = new UniformResourceLocator(ROOT_DIR); - $self->init($c, $locator); + + /** @var Config $config */ + $config = $c['config']; + $config->initializeLocator($locator); return $locator; }; $container['streams'] = function($c) use ($self) { + /** @var Config $config */ + $config = $c['config']; + + /** @var UniformResourceLocator $locator */ $locator = $c['locator']; // Set locator to both streams. Stream::setLocator($locator); ReadOnlyStream::setLocator($locator); - return new StreamBuilder($this->schemes); + return new StreamBuilder($config->getStreams($c)); }; } - - protected function init(Container $container, UniformResourceLocator $locator) - { - /** @var Config $config */ - $config = $container['config']; - $schemes = (array) $config->get('streams.schemes', []); - - 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); - } - } - - $type = !empty($config['type']) ? $config['type'] : 'ReadOnlyStream'; - if ($type[0] != '\\') { - $type = '\\RocketTheme\\Toolbox\\StreamWrapper\\' . $type; - } - - $this->schemes[$scheme] = $type; - } - } } From 6e39107d458f802f8496ec459f8459f70dc2bc02 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Sat, 10 Jan 2015 17:54:09 +0200 Subject: [PATCH 06/55] Add support for path prefixes like /en for multisite/multilanguage support --- system/src/Grav/Common/Filesystem/Folder.php | 38 +++++++++++++--- system/src/Grav/Common/Grav.php | 12 ++++-- .../Common/Markdown/MarkdownGravLinkTrait.php | 4 +- system/src/Grav/Common/Page/Page.php | 6 ++- system/src/Grav/Common/Page/Pages.php | 43 +++++++++++++++---- 5 files changed, 82 insertions(+), 21 deletions(-) diff --git a/system/src/Grav/Common/Filesystem/Folder.php b/system/src/Grav/Common/Filesystem/Folder.php index c54e019fe..3e04117ce 100644 --- a/system/src/Grav/Common/Filesystem/Folder.php +++ b/system/src/Grav/Common/Filesystem/Folder.php @@ -33,17 +33,41 @@ abstract class Folder return $last_modified; } - - public static function getRelativePath($to, $from = ROOT_DIR) + /** + * Get relative path between target and base path. If path isn't relative, return full path. + * + * @param string $path + * @param string $base + * @return string + */ + public static function getRelativePath($path, $base = GRAV_ROOT) { - $from = preg_replace('![\\|/]+!', '/', $from); - $to = preg_replace('![\\|/]+!', '/', $to); - if (strpos($to, $from) === 0) { - $to = substr($to, strlen($from)); + if ($base) { + $base = preg_replace('![\\|/]+!', '/', $base); + $path = preg_replace('![\\|/]+!', '/', $path); + if (strpos($path, $base) === 0) { + $path = ltrim(substr($path, strlen($base)), '/'); + } } - return $to; + return $path; } + + /** + * Shift first directory out of the path. + * + * @param string $path + * @return string + */ + public static function shift(&$path) + { + $parts = explode('/', trim($path, '/'), 2); + $result = array_shift($parts); + $path = array_shift($parts); + + return $result ?: null; + } + /** * Recursively find the last modified time under given path by file. * diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 5f731d742..04ce831e8 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -1,6 +1,7 @@ dispatch($c['uri']->route()); + + // If base URI is set, we want to remove it from the URL. + $path = '/' . ltrim(Folder::getRelativePath($c['uri']->route(), $pages->base()), '/'); + + $page = $pages->dispatch($path); if (!$page || !$page->routable()) { // special case where a media file is requested if (!$page) { - $path_parts = pathinfo($c['uri']->route()); + $path_parts = pathinfo($path); + $page = $c['pages']->dispatch($path_parts['dirname']); if ($page) { $media = $page->media()->all(); - $media_file = urldecode($path_parts['basename']); + $media_file = urldecode($path_parts['dirname']); if (isset($media[$media_file])) { $medium = $media[$media_file]; diff --git a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php index 6242ef01c..30d1113ae 100644 --- a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php +++ b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php @@ -129,7 +129,7 @@ trait MarkdownGravLinkTrait */ protected function convertUrl($markdown_url) { - // if absolue and starts with a base_url move on + // if absolute and starts with a base_url move on if ($this->base_url != '' && strpos($markdown_url, $this->base_url) === 0) { $new_url = $markdown_url; // if its absolute with / @@ -139,7 +139,7 @@ trait MarkdownGravLinkTrait $relative_path = rtrim($this->base_url, '/') . $this->page->route(); // If this is a 'real' filepath clean it up - if (file_exists($this->page->path().'/'.parse_url($markdown_url, PHP_URL_PATH))) { + if (file_exists($this->page->path() . '/' . parse_url($markdown_url, PHP_URL_PATH))) { $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), '/'))); } diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 9909c2568..d090a4cce 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -966,9 +966,13 @@ class Page */ public function url($include_host = false) { + /** @var Pages $pages */ + $pages = self::$grav['pages']; + /** @var Uri $uri */ $uri = self::$grav['uri']; - $rootUrl = $uri->rootUrl($include_host); + + $rootUrl = $uri->rootUrl($include_host) . $pages->base(); $url = $rootUrl.'/'.trim($this->route(), '/'); // trim trailing / if not root diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 0f8c0f4ac..0479dbe59 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -10,6 +10,7 @@ use Grav\Common\Data\Blueprint; use Grav\Common\Data\Blueprints; use Grav\Common\Filesystem\Folder; use RocketTheme\Toolbox\Event\Event; +use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator; /** * GravPages is the class that is the entry point into the hierarchy of pages @@ -34,6 +35,11 @@ class Pages */ protected $children; + /** + * @var string + */ + protected $base; + /** * @var array|string[] */ @@ -69,6 +75,22 @@ class Pages $this->grav = $c; } + /** + * Get or set base path for the pages. + * + * @param string $path + * @return string + */ + public function base($path = null) + { + if ($path !== null) { + $path = trim($path, '/'); + $this->base = $path ? '/' . $path : null; + } + + return $this->base; + } + /** * Class initialization. Must be called before using this class. */ @@ -236,8 +258,6 @@ class Pages // Fetch page if there's a defined route to it. $page = isset($this->routes[$url]) ? $this->get($this->routes[$url]) : null; - - // If the page cannot be reached, look into site wide redirects, routes + wildcards if (!$all && (!$page || !$page->routable())) { /** @var Config $config */ @@ -278,7 +298,10 @@ class Pages */ public function root() { - return $this->instances[rtrim(PAGES_DIR, DS)]; + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + return $this->instances[rtrim($locator->findResource('page://'), DS)]; } /** @@ -408,6 +431,10 @@ class Pages /** @var Config $config */ $config = $this->grav['config']; + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + $pagesDir = $locator->findResource('page://'); + if ($config->get('system.cache.enabled')) { /** @var Cache $cache */ $cache = $this->grav['cache']; @@ -421,10 +448,10 @@ class Pages $last_modified = 0; break; case 'folder': - $last_modified = Folder::lastModifiedFolder(PAGES_DIR); + $last_modified = Folder::lastModifiedFolder($pagesDir); break; default: - $last_modified = Folder::lastModifiedFile(PAGES_DIR); + $last_modified = Folder::lastModifiedFile($pagesDir); } $page_cache_id = md5(USER_DIR.$last_modified.$config->checksum()); @@ -432,7 +459,7 @@ class Pages 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->recurse($pagesDir); $this->buildRoutes(); // save pages, routes, taxonomy, and sort to cache @@ -446,7 +473,7 @@ class Pages $taxonomy->taxonomy($taxonomy_map); } } else { - $this->recurse(); + $this->recurse($pagesDir); $this->buildRoutes(); } } @@ -460,7 +487,7 @@ class Pages * @throws \RuntimeException * @internal */ - protected function recurse($directory = PAGES_DIR, Page &$parent = null) + protected function recurse($directory, Page &$parent = null) { $directory = rtrim($directory, DS); $iterator = new \DirectoryIterator($directory); From 7f526cea7642d22f97beb3fa11021b3d3c4b3159 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Sat, 10 Jan 2015 17:55:28 +0200 Subject: [PATCH 07/55] Fix fixed path in theme_url Twig variable --- system/defines.php | 8 +++++--- system/src/Grav/Common/Twig.php | 5 +---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/system/defines.php b/system/defines.php index 473292fdf..f3818d69b 100644 --- a/system/defines.php +++ b/system/defines.php @@ -17,14 +17,16 @@ define('ASSETS_DIR', ROOT_DIR . 'assets/'); define('CACHE_DIR', ROOT_DIR . 'cache/'); define('IMAGES_DIR', ROOT_DIR . 'images/'); define('LOG_DIR', ROOT_DIR .'logs/'); -define('VENDOR_DIR', ROOT_DIR .'vendor/'); -define('LIB_DIR', SYSTEM_DIR .'src/'); define('ACCOUNTS_DIR', USER_DIR .'accounts/'); -define('DATA_DIR', USER_DIR .'data/'); define('PAGES_DIR', USER_DIR .'pages/'); +// DEPRECATED: Do not use! +define('DATA_DIR', USER_DIR .'data/'); +define('LIB_DIR', SYSTEM_DIR .'src/'); define('PLUGINS_DIR', USER_DIR .'plugins/'); define('THEMES_DIR', USER_DIR .'themes/'); +define('VENDOR_DIR', ROOT_DIR .'vendor/'); +// END DEPRECATED // Some extensions define('CONTENT_EXT', '.md'); diff --git a/system/src/Grav/Common/Twig.php b/system/src/Grav/Common/Twig.php index 081f7e6d4..0fbdb81fc 100644 --- a/system/src/Grav/Common/Twig.php +++ b/system/src/Grav/Common/Twig.php @@ -125,9 +125,6 @@ class Twig $this->grav->fireEvent('onTwigExtensions'); - $theme = $config->get('system.pages.theme'); - $themeUrl = $this->grav['base_url'] .'/'. USER_PATH . basename(THEMES_DIR) .'/'. $theme; - // Set some standard variables for twig $this->twig_vars = array( 'grav' => $this->grav, @@ -138,7 +135,7 @@ class Twig 'base_url_absolute' => $this->grav['base_url_absolute'], 'base_url_relative' => $this->grav['base_url_relative'], 'theme_dir' => $locator->findResource('theme://'), - 'theme_url' => $themeUrl, + 'theme_url' => $this->grav['base_url'] .'/'. $locator->findResource('theme://', false), 'site' => $config->get('site'), 'assets' => $this->grav['assets'], 'taxonomy' => $this->grav['taxonomy'], From 4cf0a71a45bf214400aef486fcc781f909e509e5 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 10 Jan 2015 14:31:03 -0700 Subject: [PATCH 08/55] fixes for Parsedown update --- .../Common/Markdown/MarkdownGravLinkTrait.php | 38 ++++++++++--------- 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php index 30d1113ae..0d0a074ad 100644 --- a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php +++ b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php @@ -17,47 +17,49 @@ trait MarkdownGravLinkTrait /** * Ensure Twig tags are treated as block level items with no

tags */ - protected function identifyTwigTag($Line) + protected function blockTwigTag($Line) { if (preg_match('/[{%|{{|{#].*[#}|}}|%}]/', $Line['body'], $matches)) { $Block = array( - 'element' => $Line['body'], + 'element' => array( + 'text' => $Line['body'] + ) ); return $Block; } } - protected function identifyLink($Excerpt) + protected function inlineLink($excerpt) { /** @var Config $config */ $config = self::$grav['config']; // Run the parent method to get the actual results - $Excerpt = parent::identifyLink($Excerpt); + $excerpt = parent::inlineLink($excerpt); $actions = array(); $this->base_url = self::$grav['base_url']; // if this is a link - if (isset($Excerpt['element']['attributes']['href'])) { + if (isset($excerpt['element']['attributes']['href'])) { - $url = parse_url(htmlspecialchars_decode($Excerpt['element']['attributes']['href'])); + $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['href'])); // if there is no scheme, the file is local if (!isset($url['scheme'])) { // convert the URl is required - $Excerpt['element']['attributes']['href'] = $this->convertUrl(Uri::build_url($url)); + $excerpt['element']['attributes']['href'] = $this->convertUrl(Uri::build_url($url)); } } // if this is an image - if (isset($Excerpt['element']['attributes']['src'])) { + if (isset($excerpt['element']['attributes']['src'])) { - $alt = isset($Excerpt['element']['attributes']['alt']) ? $Excerpt['element']['attributes']['alt'] : ''; - $title = isset($Excerpt['element']['attributes']['title']) ? $Excerpt['element']['attributes']['title'] : ''; + $alt = isset($excerpt['element']['attributes']['alt']) ? $excerpt['element']['attributes']['alt'] : ''; + $title = isset($excerpt['element']['attributes']['title']) ? $excerpt['element']['attributes']['title'] : ''; //get the url and parse it - $url = parse_url(htmlspecialchars_decode($Excerpt['element']['attributes']['src'])); + $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['src'])); // if there is no host set but there is a path, the file is local if (!isset($url['host']) && isset($url['path'])) { @@ -92,10 +94,10 @@ trait MarkdownGravLinkTrait // set the src element with the new generated url if (!isset($actions['lightbox']) && !is_array($src)) { - $Excerpt['element']['attributes']['src'] = $src; + $excerpt['element']['attributes']['src'] = $src; } else { // Create the custom lightbox element - $Element = array( + $element = array( 'name' => 'a', 'attributes' => array('rel' => $src['a_rel'], 'href' => $src['a_url']), 'handler' => 'element', @@ -106,20 +108,20 @@ trait MarkdownGravLinkTrait ); // Set any custom classes on the lightbox element - if (isset($Excerpt['element']['attributes']['class'])) { - $Element['attributes']['class'] = $Excerpt['element']['attributes']['class']; + if (isset($excerpt['element']['attributes']['class'])) { + $element['attributes']['class'] = $excerpt['element']['attributes']['class']; } // Set the lightbox element on the Excerpt - $Excerpt['element'] = $Element; + $excerpt['element'] = $element; } } else { // not a current page media file, see if it needs converting to relative - $Excerpt['element']['attributes']['src'] = $this->convertUrl(Uri::build_url($url)); + $excerpt['element']['attributes']['src'] = $this->convertUrl(Uri::build_url($url)); } } } - return $Excerpt; + return $excerpt; } /** From 2d33f745baab73c35f82743c223e87ab4bb11404 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 10 Jan 2015 15:58:24 -0700 Subject: [PATCH 09/55] fix for bug cause by commit: 6e39107d458f802f8496ec459f8459f70dc2bc02 --- system/src/Grav/Common/Grav.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 04ce831e8..f4bd7ba8e 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -113,7 +113,7 @@ class Grav extends Container $page = $c['pages']->dispatch($path_parts['dirname']); if ($page) { $media = $page->media()->all(); - $media_file = urldecode($path_parts['dirname']); + $media_file = urldecode($path_parts['basename']); if (isset($media[$media_file])) { $medium = $media[$media_file]; From ceb3626c940bec60a46011ecbcd058254d6ec5e2 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 10 Jan 2015 15:58:44 -0700 Subject: [PATCH 10/55] More fixes for markdown images --- .../Common/Markdown/MarkdownGravLinkTrait.php | 53 +++++++++++++------ 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php index 0d0a074ad..b5b2defb7 100644 --- a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php +++ b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php @@ -14,6 +14,8 @@ trait MarkdownGravLinkTrait { use GravTrait; + protected $base_url; + /** * Ensure Twig tags are treated as block level items with no

tags */ @@ -29,29 +31,16 @@ trait MarkdownGravLinkTrait } } - protected function inlineLink($excerpt) + protected function inlineImage($excerpt) { /** @var Config $config */ $config = self::$grav['config']; // Run the parent method to get the actual results - $excerpt = parent::inlineLink($excerpt); + $excerpt = parent::inlineImage($excerpt); $actions = array(); $this->base_url = self::$grav['base_url']; - // if this is a link - if (isset($excerpt['element']['attributes']['href'])) { - - $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['href'])); - - // if there is no scheme, the file is local - if (!isset($url['scheme'])) { - - // convert the URl is required - $excerpt['element']['attributes']['href'] = $this->convertUrl(Uri::build_url($url)); - } - } - // if this is an image if (isset($excerpt['element']['attributes']['src'])) { @@ -61,11 +50,18 @@ trait MarkdownGravLinkTrait //get the url and parse it $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['src'])); + //get back to current page if possible + // if there is no host set but there is a path, the file is local if (!isset($url['host']) && isset($url['path'])) { // get the media objects for this page $media = $this->page->media(); + // get the local path to page media if possible + if (strpos($url['path'], $this->page->url()) !== false) { + $url['path'] = ltrim(str_replace($this->page->url(), '', $url['path']), '/'); + } + // if there is a media file that matches the path referenced.. if (isset($media->images()[$url['path']])) { // get the medium object @@ -121,6 +117,33 @@ trait MarkdownGravLinkTrait } } } + + return $excerpt; + } + + protected function inlineLink($excerpt) + { + /** @var Config $config */ + $config = self::$grav['config']; + + // Run the parent method to get the actual results + $excerpt = parent::inlineLink($excerpt); + $actions = array(); + $this->base_url = self::$grav['base_url']; + + // if this is a link + if (isset($excerpt['element']['attributes']['href'])) { + + $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['href'])); + + // if there is no scheme, the file is local + if (!isset($url['scheme'])) { + + // convert the URl is required + $excerpt['element']['attributes']['href'] = $this->convertUrl(Uri::build_url($url)); + } + } + return $excerpt; } From e433150a5a2a026eed1a798246812349848e295e Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 10 Jan 2015 16:07:33 -0700 Subject: [PATCH 11/55] Use page:// stream rather than PAGES_DIR constant --- system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php index b5b2defb7..ca67e6486 100644 --- a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php +++ b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php @@ -165,7 +165,8 @@ trait MarkdownGravLinkTrait // If this is a 'real' filepath clean it up if (file_exists($this->page->path() . '/' . parse_url($markdown_url, PHP_URL_PATH))) { - $relative_path = rtrim($this->base_url, '/') . preg_replace('/\/([\d]+.)/', '/', str_replace(PAGES_DIR, '/', $this->page->path())); + $pages_dir = self::$grav['locator']->findResource('page://'); + $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), '/'))); } From c550faa843fdb39b087ae02ec58aec0468682fec Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 11 Jan 2015 11:54:40 -0700 Subject: [PATCH 12/55] fix for `published` setting having precedents over `publish_date` and `unpublish_date` --- system/src/Grav/Common/Page/Page.php | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index d090a4cce..7e4ef0b7e 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -122,11 +122,9 @@ class Page $this->visible(); $this->modularTwig($this->slug[0] == '_'); - // Handle publishing dates - $config = self::$grav['config']; - - if ($config->get('system.pages.publish_dates')) { - + // Handle publishing dates if no explict published option set + if (self::$grav['config']->get('system.pages.publish_dates') && !isset($this->header->published)) { + // unpublish if required, if not clear cache right before page should be unpublished if ($this->unpublishDate()) { if ($this->unpublishDate() < time()) { $this->published(false); @@ -135,14 +133,13 @@ class Page self::$grav['cache']->setLifeTime($this->unpublishDate()); } } - + // publish if required, if not clear cache right before page is published if ($this->publishDate() != $this->modified() && $this->publishDate() > time()) { $this->published(false); self::$grav['cache']->setLifeTime($this->publishDate()); } } $this->published(); - } /** From 4c2ed0ee3d07642cca980a8a00815b34a15c136b Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 11 Jan 2015 11:54:55 -0700 Subject: [PATCH 13/55] Updated included composer package --- bin/composer.phar | Bin 1038661 -> 1048439 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/composer.phar b/bin/composer.phar index 3d0e95105a1fbc853c2f873b9266fd72a9db2dad..e46677b91013df91437beaa34aabc07d890b1bc8 100755 GIT binary patch delta 13727 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 F|KANGISBv& From e293050ea1383f28800b0c61926d70d6396a4543 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 11 Jan 2015 12:14:22 -0700 Subject: [PATCH 14/55] Rolled back Parsedown to 1.1.4 and ParsedownExtra to 0.2.6 until next Parsedown Release --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b84698dfb..b808308fc 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,8 @@ "require": { "php": ">=5.4.0", "twig/twig": "~1.16", - "erusev/parsedown-extra": "dev-master", + "erusev/parsedown": "1.1.*", + "erusev/parsedown-extra": "0.2.6", "symfony/yaml": "~2.6", "symfony/console": "~2.6", "symfony/event-dispatcher": "~2.6", From c4797a2d6f53c7a32d3ec192f1594d0d62210677 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 11 Jan 2015 12:14:43 -0700 Subject: [PATCH 15/55] Rolled back previous MarkdownTrait until next Parsedown release --- .../Common/Markdown/MarkdownGravLinkTrait.php | 89 +++++++------------ 1 file changed, 32 insertions(+), 57 deletions(-) diff --git a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php index ca67e6486..999023a1b 100644 --- a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php +++ b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php @@ -14,54 +14,56 @@ trait MarkdownGravLinkTrait { use GravTrait; - protected $base_url; - /** * Ensure Twig tags are treated as block level items with no

tags */ - protected function blockTwigTag($Line) + protected function identifyTwigTag($Line) { if (preg_match('/[{%|{{|{#].*[#}|}}|%}]/', $Line['body'], $matches)) { $Block = array( - 'element' => array( - 'text' => $Line['body'] - ) + 'element' => $Line['body'], ); return $Block; } } - protected function inlineImage($excerpt) + protected function identifyLink($Excerpt) { /** @var Config $config */ $config = self::$grav['config']; // Run the parent method to get the actual results - $excerpt = parent::inlineImage($excerpt); + $Excerpt = parent::identifyLink($Excerpt); $actions = array(); $this->base_url = self::$grav['base_url']; - // if this is an image - if (isset($excerpt['element']['attributes']['src'])) { + // if this is a link + if (isset($Excerpt['element']['attributes']['href'])) { - $alt = isset($excerpt['element']['attributes']['alt']) ? $excerpt['element']['attributes']['alt'] : ''; - $title = isset($excerpt['element']['attributes']['title']) ? $excerpt['element']['attributes']['title'] : ''; + $url = parse_url(htmlspecialchars_decode($Excerpt['element']['attributes']['href'])); + + // if there is no scheme, the file is local + if (!isset($url['scheme'])) { + + // convert the URl is required + $Excerpt['element']['attributes']['href'] = $this->convertUrl(Uri::build_url($url)); + } + } + + // if this is an image + if (isset($Excerpt['element']['attributes']['src'])) { + + $alt = isset($Excerpt['element']['attributes']['alt']) ? $Excerpt['element']['attributes']['alt'] : ''; + $title = isset($Excerpt['element']['attributes']['title']) ? $Excerpt['element']['attributes']['title'] : ''; //get the url and parse it - $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['src'])); - - //get back to current page if possible + $url = parse_url(htmlspecialchars_decode($Excerpt['element']['attributes']['src'])); // if there is no host set but there is a path, the file is local if (!isset($url['host']) && isset($url['path'])) { // get the media objects for this page $media = $this->page->media(); - // get the local path to page media if possible - if (strpos($url['path'], $this->page->url()) !== false) { - $url['path'] = ltrim(str_replace($this->page->url(), '', $url['path']), '/'); - } - // if there is a media file that matches the path referenced.. if (isset($media->images()[$url['path']])) { // get the medium object @@ -90,10 +92,10 @@ trait MarkdownGravLinkTrait // set the src element with the new generated url if (!isset($actions['lightbox']) && !is_array($src)) { - $excerpt['element']['attributes']['src'] = $src; + $Excerpt['element']['attributes']['src'] = $src; } else { // Create the custom lightbox element - $element = array( + $Element = array( 'name' => 'a', 'attributes' => array('rel' => $src['a_rel'], 'href' => $src['a_url']), 'handler' => 'element', @@ -104,47 +106,20 @@ trait MarkdownGravLinkTrait ); // Set any custom classes on the lightbox element - if (isset($excerpt['element']['attributes']['class'])) { - $element['attributes']['class'] = $excerpt['element']['attributes']['class']; + if (isset($Excerpt['element']['attributes']['class'])) { + $Element['attributes']['class'] = $Excerpt['element']['attributes']['class']; } // Set the lightbox element on the Excerpt - $excerpt['element'] = $element; + $Excerpt['element'] = $Element; } } else { // not a current page media file, see if it needs converting to relative - $excerpt['element']['attributes']['src'] = $this->convertUrl(Uri::build_url($url)); + $Excerpt['element']['attributes']['src'] = $this->convertUrl(Uri::build_url($url)); } } } - - return $excerpt; - } - - protected function inlineLink($excerpt) - { - /** @var Config $config */ - $config = self::$grav['config']; - - // Run the parent method to get the actual results - $excerpt = parent::inlineLink($excerpt); - $actions = array(); - $this->base_url = self::$grav['base_url']; - - // if this is a link - if (isset($excerpt['element']['attributes']['href'])) { - - $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['href'])); - - // if there is no scheme, the file is local - if (!isset($url['scheme'])) { - - // convert the URl is required - $excerpt['element']['attributes']['href'] = $this->convertUrl(Uri::build_url($url)); - } - } - - return $excerpt; + return $Excerpt; } /** @@ -154,17 +129,17 @@ trait MarkdownGravLinkTrait */ protected function convertUrl($markdown_url) { - // if absolute and starts with a base_url move on + // if absolue and starts with a base_url move on if ($this->base_url != '' && strpos($markdown_url, $this->base_url) === 0) { $new_url = $markdown_url; - // if its absolute with / + // 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() . '/' . parse_url($markdown_url, PHP_URL_PATH))) { + if (file_exists($this->page->path().'/'.parse_url($markdown_url, PHP_URL_PATH))) { $pages_dir = self::$grav['locator']->findResource('page://'); $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), '/'))); From 977b7d29368a2a510d86ceaa9a22faf46008079c Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 11 Jan 2015 15:23:22 -0700 Subject: [PATCH 16/55] Force modular pages to be non-visible in menus --- system/src/Grav/Common/Page/Page.php | 1 + 1 file changed, 1 insertion(+) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 7e4ef0b7e..7a7da6aad 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -1210,6 +1210,7 @@ class Page $this->modular_twig = (bool) $var; if ($var) { $this->process['twig'] = true; + $this->visible(false); } } return $this->modular_twig; From 4f4974aae4ad02b48129b166eed01d09a7acffe4 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 11 Jan 2015 15:57:55 -0700 Subject: [PATCH 17/55] forgot to change this one back --- system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php index 999023a1b..91cdfb407 100644 --- a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php +++ b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php @@ -17,7 +17,7 @@ trait MarkdownGravLinkTrait /** * Ensure Twig tags are treated as block level items with no

tags */ - protected function identifyTwigTag($Line) + protected function blockTwigTag($Line) { if (preg_match('/[{%|{{|{#].*[#}|}}|%}]/', $Line['body'], $matches)) { $Block = array( From 50ebdeddadc39da4f527bbb34dab93e17c59c363 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 11 Jan 2015 16:00:14 -0700 Subject: [PATCH 18/55] Revert "forgot to change this one back" This reverts commit 4f4974aae4ad02b48129b166eed01d09a7acffe4. --- system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php index 91cdfb407..999023a1b 100644 --- a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php +++ b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php @@ -17,7 +17,7 @@ trait MarkdownGravLinkTrait /** * Ensure Twig tags are treated as block level items with no

tags */ - protected function blockTwigTag($Line) + protected function identifyTwigTag($Line) { if (preg_match('/[{%|{{|{#].*[#}|}}|%}]/', $Line['body'], $matches)) { $Block = array( From f6da7c93443d4a6206ff6a7148b9d096ff27da48 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 12 Jan 2015 17:29:15 -0700 Subject: [PATCH 19/55] Fixes for most recent Parsedown + ParsedownExtra --- .../Common/Markdown/MarkdownGravLinkTrait.php | 83 ++++++++++++------- 1 file changed, 53 insertions(+), 30 deletions(-) diff --git a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php index 999023a1b..d061f6224 100644 --- a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php +++ b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php @@ -14,56 +14,52 @@ trait MarkdownGravLinkTrait { use GravTrait; + protected $base_url; + /** * Ensure Twig tags are treated as block level items with no

tags */ - protected function identifyTwigTag($Line) + protected function blockTwigTag($Line) { if (preg_match('/[{%|{{|{#].*[#}|}}|%}]/', $Line['body'], $matches)) { $Block = array( - 'element' => $Line['body'], + 'markup' => $Line['body'], ); return $Block; } } - protected function identifyLink($Excerpt) + protected function inlineImage($excerpt) { /** @var Config $config */ $config = self::$grav['config']; // Run the parent method to get the actual results - $Excerpt = parent::identifyLink($Excerpt); + $excerpt = parent::inlineImage($excerpt); $actions = array(); $this->base_url = self::$grav['base_url']; - // if this is a link - if (isset($Excerpt['element']['attributes']['href'])) { - - $url = parse_url(htmlspecialchars_decode($Excerpt['element']['attributes']['href'])); - - // if there is no scheme, the file is local - if (!isset($url['scheme'])) { - - // convert the URl is required - $Excerpt['element']['attributes']['href'] = $this->convertUrl(Uri::build_url($url)); - } - } - // if this is an image - if (isset($Excerpt['element']['attributes']['src'])) { + if (isset($excerpt['element']['attributes']['src'])) { - $alt = isset($Excerpt['element']['attributes']['alt']) ? $Excerpt['element']['attributes']['alt'] : ''; - $title = isset($Excerpt['element']['attributes']['title']) ? $Excerpt['element']['attributes']['title'] : ''; + $alt = $excerpt['element']['attributes']['alt'] ?: ''; + $title = $excerpt['element']['attributes']['title'] ?: ''; //get the url and parse it - $url = parse_url(htmlspecialchars_decode($Excerpt['element']['attributes']['src'])); + $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['src'])); + + //get back to current page if possible // if there is no host set but there is a path, the file is local if (!isset($url['host']) && isset($url['path'])) { // get the media objects for this page $media = $this->page->media(); + // get the local path to page media if possible + if (strpos($url['path'], $this->page->url()) !== false) { + $url['path'] = ltrim(str_replace($this->page->url(), '', $url['path']), '/'); + } + // if there is a media file that matches the path referenced.. if (isset($media->images()[$url['path']])) { // get the medium object @@ -92,10 +88,10 @@ trait MarkdownGravLinkTrait // set the src element with the new generated url if (!isset($actions['lightbox']) && !is_array($src)) { - $Excerpt['element']['attributes']['src'] = $src; + $excerpt['element']['attributes']['src'] = $src; } else { // Create the custom lightbox element - $Element = array( + $element = array( 'name' => 'a', 'attributes' => array('rel' => $src['a_rel'], 'href' => $src['a_url']), 'handler' => 'element', @@ -106,20 +102,47 @@ trait MarkdownGravLinkTrait ); // Set any custom classes on the lightbox element - if (isset($Excerpt['element']['attributes']['class'])) { - $Element['attributes']['class'] = $Excerpt['element']['attributes']['class']; + if (isset($excerpt['element']['attributes']['class'])) { + $element['attributes']['class'] = $excerpt['element']['attributes']['class']; } // Set the lightbox element on the Excerpt - $Excerpt['element'] = $Element; + $excerpt['element'] = $element; } } else { // not a current page media file, see if it needs converting to relative - $Excerpt['element']['attributes']['src'] = $this->convertUrl(Uri::build_url($url)); + $excerpt['element']['attributes']['src'] = $this->convertUrl(Uri::build_url($url)); } } } - return $Excerpt; + + return $excerpt; + } + + protected function inlineLink($excerpt) + { + /** @var Config $config */ + $config = self::$grav['config']; + + // Run the parent method to get the actual results + $excerpt = parent::inlineLink($excerpt); + $actions = array(); + $this->base_url = self::$grav['base_url']; + + // if this is a link + if (isset($excerpt['element']['attributes']['href'])) { + + $url = parse_url(htmlspecialchars_decode($excerpt['element']['attributes']['href'])); + + // if there is no scheme, the file is local + if (!isset($url['scheme'])) { + + // convert the URl is required + $excerpt['element']['attributes']['href'] = $this->convertUrl(Uri::build_url($url)); + } + } + + return $excerpt; } /** @@ -129,7 +152,7 @@ trait MarkdownGravLinkTrait */ protected function convertUrl($markdown_url) { - // if absolue and starts with a base_url move on + // if absolute and starts with a base_url move on if ($this->base_url != '' && strpos($markdown_url, $this->base_url) === 0) { $new_url = $markdown_url; // if its absolute with / @@ -139,7 +162,7 @@ trait MarkdownGravLinkTrait $relative_path = rtrim($this->base_url, '/') . $this->page->route(); // If this is a 'real' filepath clean it up - if (file_exists($this->page->path().'/'.parse_url($markdown_url, PHP_URL_PATH))) { + if (file_exists($this->page->path() . '/' . parse_url($markdown_url, PHP_URL_PATH))) { $pages_dir = self::$grav['locator']->findResource('page://'); $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), '/'))); From 195bdd71a2092e46b421c060b2f810c1cd033cd9 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 12 Jan 2015 17:29:44 -0700 Subject: [PATCH 20/55] Updated Parsedown + ParsedownExtra to latest stable version --- composer.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/composer.json b/composer.json index b808308fc..3be2aae84 100644 --- a/composer.json +++ b/composer.json @@ -8,8 +8,7 @@ "require": { "php": ">=5.4.0", "twig/twig": "~1.16", - "erusev/parsedown": "1.1.*", - "erusev/parsedown-extra": "0.2.6", + "erusev/parsedown-extra": "0.5.0", "symfony/yaml": "~2.6", "symfony/console": "~2.6", "symfony/event-dispatcher": "~2.6", From 229d3acc9904f12bfb94cc8f9bdcf405190c4040 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 16 Jan 2015 11:13:47 -0700 Subject: [PATCH 21/55] moved rewrite base before exploits in .htaccess --- .htaccess | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.htaccess b/.htaccess index 4fd10f335..ce48b2674 100644 --- a/.htaccess +++ b/.htaccess @@ -2,6 +2,17 @@ RewriteEngine On +## Begin RewriteBase +# If you are getting 404 errors on subpages, you may have to uncomment the RewriteBase entry +# You should change the '/' to your appropriate subfolder. For example if you have +# your Grav install at the root of your site '/' should work, else it might be something +# along the lines of: RewriteBase / +## + +# RewriteBase / + +## End - RewriteBase + ## Begin - Exploits # If you experience problems on your site block out the operations listed below # This attempts to block the most common type of exploit `attempts` to Grav @@ -19,17 +30,6 @@ RewriteRule .* index.php [F] # ## End - Exploits -## Begin RewriteBase -# If you are getting 404 errors on subpages, you may have to uncomment the RewriteBase entry -# You should change the '/' to your appropriate subfolder. For example if you have -# your Grav install at the root of your site '/' should work, else it might be something -# along the lines of: RewriteBase / -## - -# RewriteBase / - -## End - RewriteBase - ## Begin - Index # If the requested path and file is not /index.php and the request # has not already been internally rewritten to the index.php script From 031df8de2cbe49011cb2a93f3e8f855c414c47ba Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 16 Jan 2015 11:14:18 -0700 Subject: [PATCH 22/55] Added optional all param to pages.find() --- system/src/Grav/Common/Page/Page.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 7a7da6aad..f493a3540 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -1387,11 +1387,11 @@ class Page * @return Page page you were looking for if it exists * @deprecated */ - public function find($url) + public function find($url, $all=false) { /** @var Pages $pages */ $pages = self::$grav['pages']; - return $pages->dispatch($url); + return $pages->dispatch($url, $all); } /** From 2b504149f847a40444214385de793b10afa4a0a1 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 16 Jan 2015 11:14:34 -0700 Subject: [PATCH 23/55] updates for changelog --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19452528e..91bc9fa70 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# v0.9.14 +## XX/XX/2015 + +1. [](#new) + * Added multiple configurations via `setup.php` +2. [](#improved) + * Various updates and fixes for streams resulting in better multisite support + * Updated Twig, Parsedown, ParsedownExtra, DoctrineCache libraries + * Force modular pages to be non-visible in menus + * Moved RewriteBase before Exploits in `.htaccess` +3. [](#bugfix) + * Fix for `published` setting to have prcedent of `publish_date` and `unpublish_date` + # v0.9.13 ## 01/09/2015 From ff973a06349b4416004b34d37dc0a90ef108bb3c Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 16 Jan 2015 13:38:30 -0700 Subject: [PATCH 24/55] Added Gzip support and fix for php-fpm connections --- system/src/Grav/Common/Grav.php | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index f4bd7ba8e..aa5ef997c 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -170,6 +170,10 @@ class Grav extends Container { // Use output buffering to prevent headers from being sent too early. ob_start(); + if ($this['config']->get('system.cache.gzip')) { + ob_start('ob_gzhandler'); + } + /** @var Debugger $debugger */ $debugger = $this['debugger']; @@ -325,12 +329,21 @@ class Grav extends Container $this['session']->close(); } - header('Content-length: ' . ob_get_length()); + if ($this['config']->get('system.cache.gzip')) { + ob_end_flush(); // gzhandler buffer + } + + header('Content-Length: ' . ob_get_length()); header("Connection: close\r\n"); - ob_end_flush(); + ob_end_flush(); // regular buffer ob_flush(); flush(); + + if (function_exists('fastcgi_finish_request')) { + @fastcgi_finish_request(); + } + } $this->fireEvent('onShutdown'); From 8363da35c61214bcd98a85277eb09ac8e5beea2c Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 16 Jan 2015 13:38:43 -0700 Subject: [PATCH 25/55] updated parsedown-extra --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3be2aae84..eedb56703 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "require": { "php": ">=5.4.0", "twig/twig": "~1.16", - "erusev/parsedown-extra": "0.5.0", + "erusev/parsedown-extra": "0.5.1", "symfony/yaml": "~2.6", "symfony/console": "~2.6", "symfony/event-dispatcher": "~2.6", From 23a25b8df2afd42eafd58d2d6585bb4df0a549df Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 16 Jan 2015 13:38:56 -0700 Subject: [PATCH 26/55] Added a gzip param - default to off --- system/config/system.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/system/config/system.yaml b/system/config/system.yaml index 27dcc5c27..d3cf126c7 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -29,6 +29,7 @@ cache: driver: auto # One of: auto|file|apc|xcache|memcache|wincache prefix: 'g' # Cache prefix string (prevents cache conflicts) lifetime: 604800 # Lifetime of cached data in seconds (0 = infinite) + gzip: false # GZip compress the page output twig: cache: true # Set to true to enable twig caching From ce282c47cf5d84c41cdb9216e125e91991b5303b Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 16 Jan 2015 13:39:06 -0700 Subject: [PATCH 27/55] updated changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91bc9fa70..a95f86334 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## XX/XX/2015 1. [](#new) + * Added **GZip** support * Added multiple configurations via `setup.php` 2. [](#improved) * Various updates and fixes for streams resulting in better multisite support @@ -10,6 +11,7 @@ * Moved RewriteBase before Exploits in `.htaccess` 3. [](#bugfix) * Fix for `published` setting to have prcedent of `publish_date` and `unpublish_date` + * Fix for `onShutdown()` events not closing connections properly in **php-fpm** environments # v0.9.13 ## 01/09/2015 From bdf80fd9205a71a8f1decf0eb6f44a2ccc847929 Mon Sep 17 00:00:00 2001 From: Djamil Legato Date: Fri, 16 Jan 2015 14:44:25 -0800 Subject: [PATCH 28/55] Cherry-pick of #112 --- system/config/media.yaml | 25 +++++++++++++++++++++++++ system/src/Grav/Common/Page/Media.php | 15 +++++++++++++++ system/src/Grav/Common/Page/Page.php | 3 +++ 3 files changed, 43 insertions(+) diff --git a/system/config/media.yaml b/system/config/media.yaml index 40385268e..f5a4795da 100644 --- a/system/config/media.yaml +++ b/system/config/media.yaml @@ -40,6 +40,31 @@ swf: type: video thumb: media/thumb-swf.png mime: video/x-flv +flv: + type: video + thumb: media/thumb-flv.png + mime: video/x-flv + +mp3: + type: audio + thumb: media/thumb-mp3.png + mime: audio/mp3 +ogg: + type: audio + thumb: media/thumb-ogg.png + mine: audio/ogg +wma: + type: audio + thumb: media/thumb-wma.png + mine: audio/wma +m4a: + type: audio + thumb: media/thumb-m4a.png + mine: audio/m4a +wav: + type: audio + thumb: media/thumb-wav.png + mine: audio/wav txt: type: file diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index ca175c7b4..97ac69962 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -23,6 +23,7 @@ class Media extends Getters protected $instances = array(); protected $images = array(); protected $videos = array(); + protected $audios = array(); protected $files = array(); /** @@ -155,6 +156,17 @@ class Media extends Getters return $this->videos; } + /** + * Get a list of all audio media. + * + * @return array|Medium[] + */ + public function audios() + { + ksort($this->audios, SORT_NATURAL | SORT_FLAG_CASE); + return $this->audios; + } + /** * Get a list of all file media. * @@ -179,6 +191,9 @@ class Media extends Getters case 'video': $this->videos[$file->filename] = $file; break; + case 'audio': + $this->audios[$file->filename] = $file; + break; default: $this->files[$file->filename] = $file; } diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index f493a3540..f7e1cd212 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -450,6 +450,9 @@ class Page if ($name == 'media.image') { return $this->media()->images(); } + if ($name == 'media.audio') { + return $this->media()->audios(); + } $path = explode('.', $name); $scope = array_shift($path); From e013cf70dbc084b4a4112ae48746e1f82b5bc6ed Mon Sep 17 00:00:00 2001 From: Pereira Ricardo Date: Sun, 18 Jan 2015 03:14:09 +0100 Subject: [PATCH 29/55] Add inline assets priority Use md5 from content for discard multiple iterance. --- system/src/Grav/Common/Assets.php | 40 +++++++++++++++++++++++++------ 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index 2270016ce..7af5e9473 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -298,8 +298,12 @@ class Assets public function addInlineCss($asset, $priority = 10) { - if (is_string($asset) && !in_array($asset, $this->inline_css)) { - $this->inline_css[] = $asset; + if (is_string($asset) && !array_key_exists(md5($asset), $this->inline_css)) { + $this->inline_css[md5($asset)] = [ + 'priority' => $priority, + 'order' => count($this->inline_css), + 'asset' => $asset + ]; } return $this; @@ -312,14 +316,19 @@ class Assets * For adding chunks of string-based inline JS * * @param mixed $asset + * @param int $priority the priority, bigger comes first * * @return $this */ - public function addInlineJs($asset) + public function addInlineJs($asset, $priority = 10) { - if (is_string($asset) && !in_array($asset, $this->inline_js)) { - $this->inline_js[] = $asset; + if (is_string($asset) && !array_key_exists(md5($asset), $this->inline_js)) { + $this->inline_js[md5($asset)] = [ + 'priority' => $priority, + 'count' => count($this->inline_js), + 'asset' => $asset + ]; } return $this; @@ -346,8 +355,16 @@ class Assets } return $a['priority'] - $b['priority']; }); + + usort($this->inline_css, function ($a, $b) { + if ($a['priority'] == $b['priority']) { + return $b['order'] - $a['order']; + } + return $a['priority'] - $b['priority']; + }); } $this->css = array_reverse($this->css); + $this->inline_css = array_reverse($this->inline_css); $attributes = $this->attributes(array_merge(['type' => 'text/css', 'rel' => 'stylesheet'], $attributes)); @@ -368,7 +385,7 @@ class Assets if (count($this->inline_css) > 0) { $output .= "\n"; } @@ -397,7 +414,16 @@ class Assets } return $a['priority'] - $b['priority']; }); + + usort($this->inline_js, function ($a, $b) { + if ($a['priority'] == $b['priority']) { + return $b['order'] - $a['order']; + } + return $a['priority'] - $b['priority']; + }); + $this->js = array_reverse($this->js); + $this->inline_js = array_reverse($this->inline_js); $attributes = $this->attributes(array_merge(['type' => 'text/javascript'], $attributes)); @@ -417,7 +443,7 @@ class Assets if (count($this->inline_js) > 0) { $output .= "\n"; } From e518e3ca92cab4d389ebb793daebbe4a481af216 Mon Sep 17 00:00:00 2001 From: Pereira Ricardo Date: Sun, 18 Jan 2015 03:22:51 +0100 Subject: [PATCH 30/55] Fix small spellchecker --- system/src/Grav/Common/Filesystem/Folder.php | 3 ++- system/src/Grav/Common/Page/Collection.php | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/system/src/Grav/Common/Filesystem/Folder.php b/system/src/Grav/Common/Filesystem/Folder.php index 3e04117ce..79eb5ada8 100644 --- a/system/src/Grav/Common/Filesystem/Folder.php +++ b/system/src/Grav/Common/Filesystem/Folder.php @@ -232,8 +232,9 @@ abstract class Folder /** * Recursively delete directory from filesystem. * - * @param string $target + * @param string $target * @throws \RuntimeException + * @return bool */ public static function delete($target) { diff --git a/system/src/Grav/Common/Page/Collection.php b/system/src/Grav/Common/Page/Collection.php index 5dd03ceb0..59302b781 100644 --- a/system/src/Grav/Common/Page/Collection.php +++ b/system/src/Grav/Common/Page/Collection.php @@ -226,15 +226,15 @@ class Collection extends Iterator $start = strtotime($startDate); $end = $endDate ? strtotime($endDate) : strtotime("now +1000 years"); - $daterange = []; + $date_range = []; foreach ($this->items as $path => $slug) { $page = $this->pages->get($path); if ($page->date() > $start && $page->date() < $end) { - $daterange[$path] = $slug; + $date_range[$path] = $slug; } } - $this->items = $daterange; + $this->items = $date_range; return $this; } From 42b2f99c6d62fe6d3c15e97e1899b50ce8f54f25 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 19 Jan 2015 14:35:52 -0700 Subject: [PATCH 31/55] RE PR: #119 - Refactored a bit to be better optimized and also take into account $pages->base() --- system/src/Grav/Common/Markdown/Markdown.php | 3 +- .../Grav/Common/Markdown/MarkdownExtra.php | 3 +- .../Common/Markdown/MarkdownGravLinkTrait.php | 34 +++++++++++-------- system/src/Grav/Common/Page/Pages.php | 1 + 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/system/src/Grav/Common/Markdown/Markdown.php b/system/src/Grav/Common/Markdown/Markdown.php index 31b8bd815..07db1c435 100644 --- a/system/src/Grav/Common/Markdown/Markdown.php +++ b/system/src/Grav/Common/Markdown/Markdown.php @@ -7,8 +7,7 @@ class Markdown extends \Parsedown public function __construct($page) { - $this->page = $page; - $this->BlockTypes['{'] [] = "TwigTag"; + $this->init($page); } } diff --git a/system/src/Grav/Common/Markdown/MarkdownExtra.php b/system/src/Grav/Common/Markdown/MarkdownExtra.php index 5bdef3b94..dd55602e9 100644 --- a/system/src/Grav/Common/Markdown/MarkdownExtra.php +++ b/system/src/Grav/Common/Markdown/MarkdownExtra.php @@ -8,7 +8,6 @@ class MarkdownExtra extends \ParsedownExtra public function __construct($page) { parent::__construct(); - $this->page = $page; - $this->BlockTypes['{'] [] = "TwigTag"; + $this->init($page); } } diff --git a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php index d061f6224..94e407f9c 100644 --- a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php +++ b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php @@ -13,8 +13,22 @@ use Grav\Common\Uri; trait MarkdownGravLinkTrait { use GravTrait; - + protected $page; protected $base_url; + protected $pages_dir; + + /** + * Initialiazation function to setup key variables needed by the MarkdownGravLinkTrait + * + * @param $page + */ + protected function init($page) + { + $this->page = $page; + $this->BlockTypes['{'] [] = "TwigTag"; + $this->base_url = rtrim(self::$grav['base_url'] . self::$grav['pages']->base(), '/'); + $this->pages_dir = self::$grav['locator']->findResource('page://'); + } /** * Ensure Twig tags are treated as block level items with no

tags @@ -31,13 +45,9 @@ trait MarkdownGravLinkTrait protected function inlineImage($excerpt) { - /** @var Config $config */ - $config = self::$grav['config']; - // Run the parent method to get the actual results $excerpt = parent::inlineImage($excerpt); $actions = array(); - $this->base_url = self::$grav['base_url']; // if this is an image if (isset($excerpt['element']['attributes']['src'])) { @@ -121,13 +131,8 @@ trait MarkdownGravLinkTrait protected function inlineLink($excerpt) { - /** @var Config $config */ - $config = self::$grav['config']; - // Run the parent method to get the actual results $excerpt = parent::inlineLink($excerpt); - $actions = array(); - $this->base_url = self::$grav['base_url']; // if this is a link if (isset($excerpt['element']['attributes']['href'])) { @@ -155,16 +160,15 @@ trait MarkdownGravLinkTrait // if absolute and starts with a base_url move on if ($this->base_url != '' && strpos($markdown_url, $this->base_url) === 0) { $new_url = $markdown_url; - // if its absolute with / + // if its absolute and starts with / } elseif (strpos($markdown_url, '/') === 0) { - $new_url = rtrim($this->base_url, '/') . $markdown_url; + $new_url = $this->base_url . $markdown_url; } else { - $relative_path = rtrim($this->base_url, '/') . $this->page->route(); + $relative_path = $this->base_url . $this->page->route(); // If this is a 'real' filepath clean it up if (file_exists($this->page->path() . '/' . parse_url($markdown_url, PHP_URL_PATH))) { - $pages_dir = self::$grav['locator']->findResource('page://'); - $relative_path = rtrim($this->base_url, '/') . preg_replace('/\/([\d]+.)/', '/', str_replace($pages_dir, '/', $this->page->path())); + $relative_path = $this->base_url . preg_replace('/\/([\d]+.)/', '/', str_replace($this->pages_dir, '/', $this->page->path())); $markdown_url = preg_replace('/^([\d]+.)/', '', preg_replace('/\/([\d]+.)/', '/', trim(preg_replace('/[^\/]+(\.md$)/', '', $markdown_url), '/'))); } diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php index 0479dbe59..8d8966d62 100644 --- a/system/src/Grav/Common/Page/Pages.php +++ b/system/src/Grav/Common/Page/Pages.php @@ -73,6 +73,7 @@ class Pages public function __construct(Grav $c) { $this->grav = $c; + $this->base = ''; } /** From 632c48e1e6eee3ce70963760ef8431b1710a3fb8 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 19 Jan 2015 14:36:05 -0700 Subject: [PATCH 32/55] Updated parsedown extra lib --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index eedb56703..21534ebea 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "require": { "php": ">=5.4.0", "twig/twig": "~1.16", - "erusev/parsedown-extra": "0.5.1", + "erusev/parsedown-extra": "0.6.0", "symfony/yaml": "~2.6", "symfony/console": "~2.6", "symfony/event-dispatcher": "~2.6", From bc8f74256524d6ea4758f6c73f4b6be3a5f401fa Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 19 Jan 2015 15:02:33 -0700 Subject: [PATCH 33/55] broke out resource into a variable --- system/src/Grav/Common/TwigExtension.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/TwigExtension.php b/system/src/Grav/Common/TwigExtension.php index 2d1a2a636..d47231238 100644 --- a/system/src/Grav/Common/TwigExtension.php +++ b/system/src/Grav/Common/TwigExtension.php @@ -342,8 +342,9 @@ class TwigExtension extends \Twig_Extension /** @var Uri $uri */ $uri = $this->grav['uri']; + $resource = $locator->findResource($input, false); - return $uri->rootUrl($domain) .'/'. $locator->findResource($input, false); + return $uri->rootUrl($domain) .'/'. $resource; } /** From 6aabb83204800a1745bd89d5e8942361ef8d19e7 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 19 Jan 2015 15:16:36 -0700 Subject: [PATCH 34/55] minor perf optimizations --- system/src/Grav/Common/Assets.php | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index 7af5e9473..03e57c9a4 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -234,8 +234,9 @@ class Assets $asset = $this->buildLocalLink($asset); } - if ($asset && !array_key_exists($asset, $this->css)) { - $this->css[$asset] = [ + $key = md5($asset); + if ($asset && !array_key_exists($key, $this->css)) { + $this->css[$key] = [ 'asset' => $asset, 'priority' => $priority, 'order' => count($this->css), @@ -272,8 +273,9 @@ class Assets $asset = $this->buildLocalLink($asset); } - if ($asset && !array_key_exists($asset, $this->js)) { - $this->js[$asset] = [ + $key = md5($asset); + if ($asset && !array_key_exists($key, $this->js)) { + $this->js[$key] = [ 'asset' => $asset, 'priority' => $priority, 'order' => count($this->js), @@ -297,9 +299,9 @@ class Assets */ public function addInlineCss($asset, $priority = 10) { - - if (is_string($asset) && !array_key_exists(md5($asset), $this->inline_css)) { - $this->inline_css[md5($asset)] = [ + $key = md5($asset); + if (is_string($asset) && !array_key_exists($key, $this->inline_css)) { + $this->inline_css[$key] = [ 'priority' => $priority, 'order' => count($this->inline_css), 'asset' => $asset @@ -322,9 +324,9 @@ class Assets */ public function addInlineJs($asset, $priority = 10) { - - if (is_string($asset) && !array_key_exists(md5($asset), $this->inline_js)) { - $this->inline_js[md5($asset)] = [ + $key = md5($asset); + if (is_string($asset) && !array_key_exists($key, $this->inline_js)) { + $this->inline_js[$key] = [ 'priority' => $priority, 'count' => count($this->inline_js), 'asset' => $asset From 0c90b5c7b2bf5fc1f353d29722cfeb5fce8aa48e Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 19 Jan 2015 15:32:45 -0700 Subject: [PATCH 35/55] assets typo --- system/src/Grav/Common/Assets.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index 03e57c9a4..81856f504 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -328,7 +328,7 @@ class Assets if (is_string($asset) && !array_key_exists($key, $this->inline_js)) { $this->inline_js[$key] = [ 'priority' => $priority, - 'count' => count($this->inline_js), + 'order' => count($this->inline_js), 'asset' => $asset ]; } From c9385632a9f5b491adb25f97421d5ee2641d4a43 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 19 Jan 2015 15:32:57 -0700 Subject: [PATCH 36/55] cleanup --- system/src/Grav/Common/Page/Page.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index f7e1cd212..84c463f68 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -1387,10 +1387,12 @@ class Page * Helper method to return a page. * * @param string $url the url of the page - * @return Page page you were looking for if it exists + * @param bool $all + * + * @return \Grav\Common\Page\Page page you were looking for if it exists * @deprecated */ - public function find($url, $all=false) + public function find($url, $all = false) { /** @var Pages $pages */ $pages = self::$grav['pages']; From 4cd4bb4202e7dd23d7752f2688ee77d8a818f3db Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 20 Jan 2015 09:35:30 -0700 Subject: [PATCH 37/55] fix for non-url valid twig code in Markdown Link/Image --- .../Common/Markdown/MarkdownGravLinkTrait.php | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php index 94e407f9c..e2c8e3631 100644 --- a/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php +++ b/system/src/Grav/Common/Markdown/MarkdownGravLinkTrait.php @@ -17,6 +17,8 @@ trait MarkdownGravLinkTrait protected $base_url; protected $pages_dir; + protected $twig_link_regex = '/\!*\[(?:.*)\]\(([{{|{%|{#].*[#}|%}|}}])\)/'; + /** * Initialiazation function to setup key variables needed by the MarkdownGravLinkTrait * @@ -45,8 +47,16 @@ trait MarkdownGravLinkTrait protected function inlineImage($excerpt) { - // Run the parent method to get the actual results - $excerpt = parent::inlineImage($excerpt); + if (preg_match($this->twig_link_regex, $excerpt['text'], $matches)) { + $excerpt['text'] = str_replace($matches[1], '/', $excerpt['text']); + $excerpt = parent::inlineImage($excerpt); + $excerpt['element']['attributes']['src'] = $matches[1]; + $excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1; + return $excerpt; + } else { + $excerpt = parent::inlineImage($excerpt); + } + $actions = array(); // if this is an image @@ -131,8 +141,16 @@ trait MarkdownGravLinkTrait protected function inlineLink($excerpt) { - // Run the parent method to get the actual results - $excerpt = parent::inlineLink($excerpt); + // do some trickery to get around Parsedown requirement for valid URL if its Twig in there + if (preg_match($this->twig_link_regex, $excerpt['text'], $matches)) { + $excerpt['text'] = str_replace($matches[1], '/', $excerpt['text']); + $excerpt = parent::inlineLink($excerpt); + $excerpt['element']['attributes']['href'] = $matches[1]; + $excerpt['extent'] = $excerpt['extent'] + strlen($matches[1]) - 1; + return $excerpt; + } else { + $excerpt = parent::inlineLink($excerpt); + } // if this is a link if (isset($excerpt['element']['attributes']['href'])) { From 259d8356b027fc7af1d48df20db4872ed7b1ad31 Mon Sep 17 00:00:00 2001 From: Matias Griese Date: Tue, 20 Jan 2015 19:23:05 +0200 Subject: [PATCH 38/55] Update url() method in twig --- system/src/Grav/Common/TwigExtension.php | 26 +++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/system/src/Grav/Common/TwigExtension.php b/system/src/Grav/Common/TwigExtension.php index d47231238..65a546900 100644 --- a/system/src/Grav/Common/TwigExtension.php +++ b/system/src/Grav/Common/TwigExtension.php @@ -331,20 +331,32 @@ class TwigExtension extends \Twig_Extension /** * Return URL to the resource. * - * @param string $input - * @param bool $domain - * @return string + * @example {{ url('theme://images/logo.png')|default('http://www.placehold.it/150x100/f4f4f4') }} + * + * @param string $input Resource to be located. + * @param bool $domain True to include domain name. + * @return string|null Returns url to the resource or null if resource was not found. */ public function urlFunc($input, $domain = false) { - /** @var UniformResourceLocator $locator */ - $locator = $this->grav['locator']; + if (!trim((string) $input)) { + return false; + } + + if (strpos((string) $input, '://')) { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + // Get relative path to the resource (or false if not found). + $resource = $locator->findResource((string) $input, false); + } else { + $resource = (string) $input; + } /** @var Uri $uri */ $uri = $this->grav['uri']; - $resource = $locator->findResource($input, false); - return $uri->rootUrl($domain) .'/'. $resource; + return $resource ? rtrim($uri->rootUrl($domain), '/') . '/' . $resource : null; } /** From af978767940d8b4c6ab733f5341bd023fca19190 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 20 Jan 2015 10:42:13 -0700 Subject: [PATCH 39/55] some initial refactoring --- system/src/Grav/Common/Page/Page.php | 29 +--------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 84c463f68..04d5c4298 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -348,8 +348,7 @@ class Page $update_cache = false; if ($this->content === false) { - // Process Markdown - $this->content = $this->processMarkdown(); + $this->content = $this->shouldProcess('markdown') ? $this->parseMarkdownContent($this->raw_content) : $this->raw_content; $update_cache = true; } @@ -1592,32 +1591,6 @@ class Page return $file && $file->exists(); } - /** - * Process the Markdown if processing is enabled for it. If not, process as 'raw' which simply strips the - * header YAML from the raw, and sends back the content portion. i.e. the bit below the header. - * - * @return string the content for the page - */ - protected function processMarkdown() - { - // Process Markdown if required - $process_method = $this->shouldProcess('markdown') ? 'parseMarkdownContent' : 'rawContent'; - $content = $this->$process_method($this->raw_content); - - return $content; - } - - /** - * Process the raw content. Basically just strips the headers out and returns the rest. - * - * @param string $content Input raw content - * @return string Output content after headers have been stripped - */ - protected function rawContent($content) - { - return $content; - } - /** * Process the Markdown content. This strips the headers, the process the resulting content as Markdown. * From 9f782a4aed23014a54927a70d544a1d48d91a739 Mon Sep 17 00:00:00 2001 From: Pereira Ricardo Date: Tue, 20 Jan 2015 21:11:13 +0100 Subject: [PATCH 40/55] Update User.php --- system/src/Grav/Common/User/User.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/User/User.php b/system/src/Grav/Common/User/User.php index e9626eda4..8da0896fe 100644 --- a/system/src/Grav/Common/User/User.php +++ b/system/src/Grav/Common/User/User.php @@ -4,6 +4,7 @@ namespace Grav\Common\User; use Grav\Common\Data\Blueprints; use Grav\Common\Data\Data; use Grav\Common\File\CompiledYamlFile; +use Grav\Common\GravTrait; /** * User object @@ -13,6 +14,8 @@ use Grav\Common\File\CompiledYamlFile; */ class User extends Data { + use GravTrait; + /** * Load user account. * @@ -23,10 +26,13 @@ class User extends Data */ public static function load($username) { + $locator = self::$grav['locator']; + // FIXME: validate directory name $blueprints = new Blueprints('blueprints://user'); $blueprint = $blueprints->get('account'); - $file = CompiledYamlFile::instance(ACCOUNTS_DIR . $username . YAML_EXT); + $file_path = $locator->findResource('account://' . $username . YAML_EXT); + $file = CompiledYamlFile::instance($file_path); $content = $file->content(); if (!isset($content['username'])) { $content['username'] = $username; From 0ddd2941e95a5d799013931f1e4a5bfb795f96cf Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 20 Jan 2015 18:08:14 -0700 Subject: [PATCH 41/55] Add event when caching markdown content too --- system/src/Grav/Common/Page/Page.php | 1 + 1 file changed, 1 insertion(+) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 04d5c4298..422c0e8cc 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -360,6 +360,7 @@ class Page // Do we want to cache markdown, but process twig in each page? if ($update_cache && $process_twig) { + self::$grav->fireEvent('onPageContentProcessed', new Event(['page' => $this])); $cache->save($cache_id, $this->content); $update_cache = false; } From c2c5afbb05d0202c406681a7132aed887796cc8b Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 21 Jan 2015 11:14:52 -0700 Subject: [PATCH 42/55] Added new onPageContentRaw() event that processes before markdown --- system/src/Grav/Common/Page/Page.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 422c0e8cc..d56449231 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -348,7 +348,9 @@ class Page $update_cache = false; if ($this->content === false) { - $this->content = $this->shouldProcess('markdown') ? $this->parseMarkdownContent($this->raw_content) : $this->raw_content; + $this->content = $this->raw_content; + self::$grav->fireEvent('onPageContentRaw', new Event(['page' => $this])); + $this->content = $this->shouldProcess('markdown') ? $this->parseMarkdownContent($this->content) : $this->content; $update_cache = true; } From c2f2f7b009dcddac506e659c7864c50909c1bd47 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 21 Jan 2015 12:22:29 -0700 Subject: [PATCH 43/55] fix for quotes in metadata --- system/src/Grav/Common/Page/Page.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index d56449231..aea72a72b 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -881,14 +881,14 @@ class Page if (is_array($value)) { foreach ($value as $property => $prop_value) { $prop_key = $key.":".$property; - $this->metadata[$prop_key] = array('property'=>$prop_key, 'content'=>$prop_value); + $this->metadata[$prop_key] = array('property'=>$prop_key, 'content'=>htmlspecialchars($prop_value, ENT_HTML5)); } // If it this is a standard meta data type } else { if (in_array($key, $header_tag_http_equivs)) { - $this->metadata[$key] = array('http_equiv'=>$key, 'content'=>$value); + $this->metadata[$key] = array('http_equiv'=>$key, 'content'=>htmlspecialchars($value, ENT_HTML5)); } else { - $this->metadata[$key] = array('name'=>$key, 'content'=>$value); + $this->metadata[$key] = array('name'=>$key, 'content'=>htmlspecialchars($value, ENT_HTML5)); } } } From c1ef8b639913792abccae07ed341fb39168a0273 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 21 Jan 2015 13:23:15 -0700 Subject: [PATCH 44/55] ENT_QUOTES works better than ENT_HTML5, so changing --- system/src/Grav/Common/Page/Page.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index aea72a72b..e3c656f10 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -881,14 +881,14 @@ class Page if (is_array($value)) { foreach ($value as $property => $prop_value) { $prop_key = $key.":".$property; - $this->metadata[$prop_key] = array('property'=>$prop_key, 'content'=>htmlspecialchars($prop_value, ENT_HTML5)); + $this->metadata[$prop_key] = array('property'=>$prop_key, 'content'=>htmlspecialchars($prop_value, ENT_QUOTES)); } // If it this is a standard meta data type } else { if (in_array($key, $header_tag_http_equivs)) { - $this->metadata[$key] = array('http_equiv'=>$key, 'content'=>htmlspecialchars($value, ENT_HTML5)); + $this->metadata[$key] = array('http_equiv'=>$key, 'content'=>htmlspecialchars($value, ENT_QUOTES)); } else { - $this->metadata[$key] = array('name'=>$key, 'content'=>htmlspecialchars($value, ENT_HTML5)); + $this->metadata[$key] = array('name'=>$key, 'content'=>htmlspecialchars($value, ENT_QUOTES)); } } } From 2dedd9d1a0db7eb3e8243ff9c54113f1ade46daa Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 21 Jan 2015 13:23:53 -0700 Subject: [PATCH 45/55] Refactored Parsedown override class names --- .../Grav/Common/Markdown/{Markdown.php => Parsedown.php} | 4 ++-- .../Markdown/{MarkdownExtra.php => ParsedownExtra.php} | 4 ++-- .../{MarkdownGravLinkTrait.php => ParsedownGravTrait.php} | 2 +- system/src/Grav/Common/Page/Page.php | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) rename system/src/Grav/Common/Markdown/{Markdown.php => Parsedown.php} (65%) rename system/src/Grav/Common/Markdown/{MarkdownExtra.php => ParsedownExtra.php} (67%) rename system/src/Grav/Common/Markdown/{MarkdownGravLinkTrait.php => ParsedownGravTrait.php} (99%) diff --git a/system/src/Grav/Common/Markdown/Markdown.php b/system/src/Grav/Common/Markdown/Parsedown.php similarity index 65% rename from system/src/Grav/Common/Markdown/Markdown.php rename to system/src/Grav/Common/Markdown/Parsedown.php index 07db1c435..1db2d1707 100644 --- a/system/src/Grav/Common/Markdown/Markdown.php +++ b/system/src/Grav/Common/Markdown/Parsedown.php @@ -1,9 +1,9 @@ markdown_extra) ? $this->markdown_extra : $config->get('system.pages.markdown_extra')) { - $parsedown = new MarkdownExtra($this); + $parsedown = new ParsedownExtra($this); } else { - $parsedown = new Markdown($this); + $parsedown = new Parsedown($this); } $content = $parsedown->text($content); return $content; From ac26c3ab4ef604d2209429f282ac473a9786c95f Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 21 Jan 2015 15:36:05 -0700 Subject: [PATCH 46/55] added ability to set metadata --- system/src/Grav/Common/Page/Page.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index f23f9adc1..d7d3052ea 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -850,9 +850,16 @@ class Page /** * Function to merge page metadata tags and build an array of Metadata objects * that can then be rendered in the page. + * + * @param array $var an Array of metadata values to set + * @return array an Array of metadata values for the page */ - public function metadata() + public function metadata($var = null) { + if ($var !== null) { + $this->metadata = (array) $var; + } + // if not metadata yet, process it. if (null === $this->metadata) { From 3c63993db84738b1465eeb2fbecd93f43c859082 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 21 Jan 2015 18:21:39 -0700 Subject: [PATCH 47/55] Some pretty serious page refactoring to clean up a rather unreadable chunk of code in content() method --- system/src/Grav/Common/Page/Page.php | 130 ++++++++++++++++----------- 1 file changed, 79 insertions(+), 51 deletions(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index d7d3052ea..458de5777 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -346,40 +346,50 @@ class Page $cache_id = md5('page'.$this->id()); $this->content = $cache->fetch($cache_id); - $update_cache = false; - if ($this->content === false) { + $process_markdown = $this->shouldProcess('markdown'); + $process_twig = $this->shouldProcess('twig'); + $cache_twig = isset($this->header->cache_enable) ? $this->header->cache_enable : true; + $twig_first = isset($this->header->twig_first) ? $this->header->twig_first : false; + $twig_already_processed = false; + + // if no cached-content run everything + if ($this->content == false) { + $this->content = $this->raw_content; self::$grav->fireEvent('onPageContentRaw', new Event(['page' => $this])); - $this->content = $this->shouldProcess('markdown') ? $this->parseMarkdownContent($this->content) : $this->content; - $update_cache = true; + + if ($twig_first) { + if ($process_twig) { + $this->processTwig(); + $twig_already_processed = true; + } + if ($process_markdown) { + $this->processMarkdown(); + } + if ($cache_twig) { + $this->cachePageContent(); + } + } else { + if ($process_markdown) { + $this->processMarkdown(); + } + if (!$cache_twig) { + $this->cachePageContent(); + } + if ($process_twig) { + $this->processTwig(); + $twig_already_processed = true; + } + if ($cache_twig) { + $this->cachePageContent(); + } + } + // content cached, but twig cache off } - // Process Twig if enabled - if ($this->shouldProcess('twig')) { - - // Always process twig if caching in the page is disabled - $process_twig = (isset($this->header->cache_enable) && !$this->header->cache_enable); - - // Do we want to cache markdown, but process twig in each page? - if ($update_cache && $process_twig) { - self::$grav->fireEvent('onPageContentProcessed', new Event(['page' => $this])); - $cache->save($cache_id, $this->content); - $update_cache = false; - } - - // Do we need to process twig this time? - if ($update_cache || $process_twig) { - /** @var Twig $twig */ - $twig = self::$grav['twig']; - $this->content = $twig->processPage($this, $this->content); - } - } - - // Cache the whole page, including processed content - if ($update_cache) { - // Process any post-processing but pre-caching functionality - self::$grav->fireEvent('onPageContentProcessed', new Event(['page' => $this])); - $cache->save($cache_id, $this->content); + // only markdown content cached, process twig if required and not already processed + if ($process_twig && !$cache_twig && !$twig_already_processed) { + $this->processTwig(); } // Handle summary divider @@ -394,6 +404,45 @@ class Page return $this->content; } + /** + * Process the Markdown content. Uses Parsedown or Parsedown Extra depending on configuration + */ + protected function processMarkdown() + { + /** @var Config $config */ + $config = self::$grav['config']; + + // get the appropriate setting for markdown extra + if (isset($this->markdown_extra) ? $this->markdown_extra : $config->get('system.pages.markdown_extra')) { + $parsedown = new ParsedownExtra($this); + } else { + $parsedown = new Parsedown($this); + } + $this->content = $parsedown->text($this->content); + } + + + /** + * Process the Twig page content. + */ + private function processTwig() + { + $twig = self::$grav['twig']; + $this->content = $twig->processPage($this, $this->content); + } + + /** + * Fires the onPageContentProcessed event, and caches the page content using a unique ID for the page + */ + private function cachePageContent() + { + $cache = self::$grav['cache']; + $cache_id = md5('page'.$this->id()); + + self::$grav->fireEvent('onPageContentProcessed', new Event(['page' => $this])); + $cache->save($cache_id, $this->content); + } + /** * Needed by the onPageContentProcessed event to get the raw page content * @@ -1601,27 +1650,6 @@ class Page return $file && $file->exists(); } - /** - * Process the Markdown content. This strips the headers, the process the resulting content as Markdown. - * - * @param string $content Input raw content - * @return string Output content that has been processed as Markdown - */ - protected function parseMarkdownContent($content) - { - /** @var Config $config */ - $config = self::$grav['config']; - - // get the appropriate setting for markdown extra - if (isset($this->markdown_extra) ? $this->markdown_extra : $config->get('system.pages.markdown_extra')) { - $parsedown = new ParsedownExtra($this); - } else { - $parsedown = new Parsedown($this); - } - $content = $parsedown->text($content); - return $content; - } - /** * Cleans the path. * From c881624801ac63892e4065e226abecd7fd5b1125 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 21 Jan 2015 21:57:55 -0700 Subject: [PATCH 48/55] Added ability to configure the special characters that are automatically converted in Parsedown --- .../Common/Markdown/ParsedownGravTrait.php | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php index 642be7562..9436ef78f 100644 --- a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php +++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php @@ -16,6 +16,7 @@ trait ParsedownGravTrait protected $page; protected $base_url; protected $pages_dir; + protected $special_chars; protected $twig_link_regex = '/\!*\[(?:.*)\]\(([{{|{%|{#].*[#}|%}|}}])\)/'; @@ -30,6 +31,21 @@ trait ParsedownGravTrait $this->BlockTypes['{'] [] = "TwigTag"; $this->base_url = rtrim(self::$grav['base_url'] . self::$grav['pages']->base(), '/'); $this->pages_dir = self::$grav['locator']->findResource('page://'); + $this->special_chars = array('>' => 'gt', '<' => 'lt', '"' => 'quot'); + } + + /** + * Setter for special chars + * + * @param $special_chars + * + * @return $this + */ + function setSpecialChars($special_chars) + { + $this->special_chars = $special_chars; + + return $this; } /** @@ -45,6 +61,23 @@ trait ParsedownGravTrait } } + protected function inlineSpecialCharacter($Excerpt) + { + if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text'])) { + return array( + 'markup' => '&', + 'extent' => 1, + ); + } + + if (isset($this->special_chars[$Excerpt['text'][0]])) { + return array( + 'markup' => '&'.$this->special_chars[$Excerpt['text'][0]].';', + 'extent' => 1, + ); + } + } + protected function inlineImage($excerpt) { if (preg_match($this->twig_link_regex, $excerpt['text'], $matches)) { From 7bc924b6d62a8a2b7d50a39bbdbb0d57f07b93f1 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 21 Jan 2015 21:58:51 -0700 Subject: [PATCH 49/55] Added ability to configure markdown options in configuration and in page --- system/config/system.yaml | 9 ++++++++- system/src/Grav/Common/Page/Page.php | 20 ++++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/system/config/system.yaml b/system/config/system.yaml index d3cf126c7..ead9bf100 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -5,7 +5,6 @@ home: pages: theme: antimatter # Default theme (defaults to "antimatter" theme) - markdown_extra: false # Enable support for Markdown Extra support (GFM by default) order: by: defaults # Order pages by "default", "alpha" or "date" dir: asc # Default ordering direction, "asc" or "desc" @@ -21,6 +20,14 @@ pages: events: page: true # Enable page level events twig: true # Enable twig level events + markdown: + extra: false # Enable support for Markdown Extra support (GFM by default) + auto_line_breaks: true # Enable automatic line breaks + auto_url_links: false # Enable automatic HTML links + escape_markup: false # Escape markup tags into entities + special_chars: # List of special characters to automatically convert to entities + '>': 'gt' + '<': 'lt' cache: enabled: true # Set to true to enable caching diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 458de5777..0c5bc4a89 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -412,12 +412,28 @@ class Page /** @var Config $config */ $config = self::$grav['config']; - // get the appropriate setting for markdown extra - if (isset($this->markdown_extra) ? $this->markdown_extra : $config->get('system.pages.markdown_extra')) { + $defaults = (array) $config->get('system.pages.markdown'); + if (isset($this->header()->markdown)) { + $defaults = array_merge($defaults, $this->header()->markdown); + } + + // pages.markdown_extra is deprecated, but still check it... + if (isset($this->markdown_extra) || $config->get('system.pages.markdown_extra') !== null) { + $defaults['extra'] = $this->markdown_extra; + } + + // Initialize the preferred variant of Parsedown + if ($defaults['extra']) { $parsedown = new ParsedownExtra($this); } else { $parsedown = new Parsedown($this); } + + $parsedown->setBreaksEnabled($defaults['auto_line_breaks']); + $parsedown->setSpecialChars($defaults['special_chars']); + $parsedown->setUrlsLinked($defaults['auto_url_links']); + $parsedown->setMarkupEscaped($defaults['escape_markup']); + $this->content = $parsedown->text($this->content); } From fed9862e44eaf39765b2df8813bd043578dc1f55 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 21 Jan 2015 22:07:37 -0700 Subject: [PATCH 50/55] set auto_link_breaks to false by default --- system/config/system.yaml | 2 +- system/src/Grav/Common/Page/Page.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/config/system.yaml b/system/config/system.yaml index ead9bf100..a7c1ada23 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -22,7 +22,7 @@ pages: twig: true # Enable twig level events markdown: extra: false # Enable support for Markdown Extra support (GFM by default) - auto_line_breaks: true # Enable automatic line breaks + auto_line_breaks: false # Enable automatic line breaks auto_url_links: false # Enable automatic HTML links escape_markup: false # Escape markup tags into entities special_chars: # List of special characters to automatically convert to entities diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 0c5bc4a89..feeb449a8 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -430,9 +430,9 @@ class Page } $parsedown->setBreaksEnabled($defaults['auto_line_breaks']); - $parsedown->setSpecialChars($defaults['special_chars']); $parsedown->setUrlsLinked($defaults['auto_url_links']); $parsedown->setMarkupEscaped($defaults['escape_markup']); + $parsedown->setSpecialChars($defaults['special_chars']); $this->content = $parsedown->text($this->content); } From adf80c3f872e4edf01986439ef29290afb8df3d1 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 22 Jan 2015 16:50:35 -0700 Subject: [PATCH 51/55] fix for change in slash trimming in Resource Locator --- system/src/Grav/Common/Markdown/ParsedownGravTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php index 9436ef78f..2cd116cbb 100644 --- a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php +++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php @@ -219,7 +219,7 @@ trait ParsedownGravTrait // If this is a 'real' filepath clean it up if (file_exists($this->page->path() . '/' . parse_url($markdown_url, PHP_URL_PATH))) { - $relative_path = $this->base_url . preg_replace('/\/([\d]+.)/', '/', str_replace($this->pages_dir, '/', $this->page->path())); + $relative_path = $this->base_url . preg_replace('/\/([\d]+.)/', '/', str_replace($this->pages_dir, '', $this->page->path())); $markdown_url = preg_replace('/^([\d]+.)/', '', preg_replace('/\/([\d]+.)/', '/', trim(preg_replace('/[^\/]+(\.md$)/', '', $markdown_url), '/'))); } From e571f3bcfd2d4dd3c11fd68790bcce0ac8bb00dd Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 22 Jan 2015 17:44:32 -0700 Subject: [PATCH 52/55] Added some missing clean statements --- system/src/Grav/Console/Cli/CleanCommand.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/system/src/Grav/Console/Cli/CleanCommand.php b/system/src/Grav/Console/Cli/CleanCommand.php index 13df85c28..94a644450 100644 --- a/system/src/Grav/Console/Cli/CleanCommand.php +++ b/system/src/Grav/Console/Cli/CleanCommand.php @@ -73,6 +73,7 @@ class CleanCommand extends Command 'vendor/gregwar/image/Gregwar/Image/phpunit.xml', 'vendor/gregwar/image/Gregwar/Image/.gitignore', 'vendor/gregwar/image/Gregwar/Image/.git', + 'vendor/gregwar/image/Gregwar/Image/doc', 'vendor/gregwar/image/Gregwar/Image/demo', 'vendor/gregwar/image/Gregwar/Image/tests', 'vendor/gregwar/cache/Gregwar/Cache/composer.json', @@ -90,6 +91,10 @@ class CleanCommand extends Command 'vendor/maximebf/debugbar/composer.json', 'vendor/maximebf/debugbar/.bowerrc', 'vendor/maximebf/debugbar/src/Debugbar/Resources/vendor', + 'vendor/maximebf/debugbar/demo', + 'vendor/maximebf/debugbar/docs', + 'vendor/maximebf/debugbar/tests', + 'vendor/maximebf/debugbar/phpunit.xml.dist', 'vendor/monolog/monolog/composer.json', 'vendor/monolog/monolog/doc', 'vendor/monolog/monolog/phpunit.xml.dist', From 689c65c5e452ab4a08d01934591fac39669e889b Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 22 Jan 2015 17:47:05 -0700 Subject: [PATCH 53/55] bumped parsedown extra lib version --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 21534ebea..5e8978351 100644 --- a/composer.json +++ b/composer.json @@ -8,7 +8,7 @@ "require": { "php": ">=5.4.0", "twig/twig": "~1.16", - "erusev/parsedown-extra": "0.6.0", + "erusev/parsedown-extra": "~0.6", "symfony/yaml": "~2.6", "symfony/console": "~2.6", "symfony/event-dispatcher": "~2.6", From 7ddf35d3fa356baa42e126438d5f61f8e9b32f11 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 23 Jan 2015 12:34:18 -0700 Subject: [PATCH 54/55] updated changelog --- CHANGELOG.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a95f86334..f9a111000 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,25 @@ 1. [](#new) * Added **GZip** support * Added multiple configurations via `setup.php` + * Added base structure for unit tests + * New `onPageContentRaw()` plugin event that processes before any page processing + * Added ability to dynamically set Metadata on page + * Added ability to dynamically configure Markdown processing via Parsedown options 2. [](#improved) - * Various updates and fixes for streams resulting in better multisite support + * Refactored `page.content()` method to be more flexible and reliable + * Various updates and fixes for streams resulting in better multi-site support * Updated Twig, Parsedown, ParsedownExtra, DoctrineCache libraries + * Refactored Parsedown trait * Force modular pages to be non-visible in menus * Moved RewriteBase before Exploits in `.htaccess` + * Added standard video formats to Media support + * Added priority for inline assets + * Check for uniqueness when adding multiple inline assets + * Improved support for Twig-based URLs inside Markdown links and images + * Improved Twig `url()` function 3. [](#bugfix) - * Fix for `published` setting to have prcedent of `publish_date` and `unpublish_date` + * Fix for HTML entities quotes in Metadata values + * Fix for `published` setting to have precedent of `publish_date` and `unpublish_date` * Fix for `onShutdown()` events not closing connections properly in **php-fpm** environments # v0.9.13 @@ -30,7 +42,7 @@ * House-cleaning of some unused methods in Pages object 3. [](#bugfix) * Fix `uninstall` GPM command that was broken in last release - * Fix for intermitten `undefined index` error when working with Collections + * Fix for intermittent `undefined index` error when working with Collections * Fix for date of some pages being set to incorrect future timestamps # v0.9.12 @@ -42,8 +54,8 @@ * Added support for **in-page** Twig processing in **modular** pages * Added configurable support for `undefined` Twig functions and filters 2. [](#improved) - * Fallback to default `.html` template if error occurs on non-html pages - * Added ability to have PSR-1 friendly plugin names (camelcase, no-dashes) + * Fall back to default `.html` template if error occurs on non-html pages + * Added ability to have PSR-1 friendly plugin names (CamelCase, no-dashes) * Fix to `composer.json` to deter API rate-limit errors * Added **non-exception-throwing** handler for undefined methods on `Medium` objects 3. [](#bugfix) From ccc65aa420f2e3e06d93ae7c47c299a9d0979289 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 23 Jan 2015 13:08:35 -0700 Subject: [PATCH 55/55] version update --- CHANGELOG.md | 2 +- system/defines.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f9a111000..d35a69eef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ # v0.9.14 -## XX/XX/2015 +## 01/23/2015 1. [](#new) * Added **GZip** support diff --git a/system/defines.php b/system/defines.php index f3818d69b..81e161036 100644 --- a/system/defines.php +++ b/system/defines.php @@ -2,7 +2,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '0.9.13'); +define('GRAV_VERSION', '0.9.14'); define('DS', '/'); // Directories and Paths