From 7947ba24422e74a4831151828e5f768267fda130 Mon Sep 17 00:00:00 2001 From: Gert Date: Thu, 16 Apr 2015 17:42:29 +0200 Subject: [PATCH 01/64] fix config reload to actually reload from files --- system/src/Grav/Common/Config/Config.php | 100 ++++++++---------- .../Common/Service/ConfigServiceProvider.php | 12 +-- 2 files changed, 48 insertions(+), 64 deletions(-) diff --git a/system/src/Grav/Common/Config/Config.php b/system/src/Grav/Common/Config/Config.php index 1fe373a40..ef08830a0 100644 --- a/system/src/Grav/Common/Config/Config.php +++ b/system/src/Grav/Common/Config/Config.php @@ -75,6 +75,8 @@ class Config extends Data ] ]; + protected $setup = []; + protected $blueprintFiles = []; protected $configFiles = []; protected $checksum; @@ -88,33 +90,25 @@ class Config extends Data protected $environment; protected $messages = []; - public function __construct(array $items = array(), Grav $grav = null, $environment = null) + public function __construct(array $setup = array(), Grav $grav = null, $environment = null) { $this->grav = $grav ?: Grav::instance(); $this->finder = new ConfigFinder; $this->environment = $environment ?: 'localhost'; $this->messages[] = 'Environment Name: ' . $this->environment; - if (isset($items['@class'])) { - if ($items['@class'] != get_class($this)) { - throw new \InvalidArgumentException('Unrecognized config cache file!'); - } - // Loading pre-compiled configuration. - $this->timestamp = (int) $items['timestamp']; - $this->checksum = $items['checksum']; - $this->items = (array) $items['data']; - } else { - // Make sure that - if (!isset($items['streams']['schemes'])) { - $items['streams']['schemes'] = []; - } - $items['streams']['schemes'] += $this->streams; - - $items = $this->autoDetectEnvironmentConfig($items); - $this->messages[] = $items['streams']['schemes']['config']['prefixes']['']; - - parent::__construct($items); + // Make sure that + if (!isset($setup['streams']['schemes'])) { + $setup['streams']['schemes'] = []; } + $setup['streams']['schemes'] += $this->streams; + + $setup = $this->autoDetectEnvironmentConfig($setup); + $this->messages[] = $setup['streams']['schemes']['config']['prefixes']['']; + + $this->setup = $setup; + parent::__construct($setup); + $this->check(); } @@ -125,8 +119,10 @@ class Config extends Data public function reload() { + $this->items = $this->setup; $this->check(); $this->init(); + $this->debug(); return $this; } @@ -150,6 +146,7 @@ class Config extends Data foreach ($this->messages as $message) { $this->grav['debugger']->addMessage($message); } + $this->messages = []; } public function init() @@ -161,15 +158,6 @@ class Config extends Data $this->blueprintLookup = $locator->findResources('blueprints://config'); $this->pluginLookup = $locator->findResources('plugins://'); - if (!isset($this->checksum)) { - $this->messages[] = 'No cached configuration, compiling new configuration..'; - } elseif ($this->checksum() != $this->checksum) { - $this->messages[] = 'Configuration checksum mismatch, reloading configuration..'; - } else { - $this->messages[] = 'Configuration checksum matches, using cached version.'; - return; - } - $this->loadCompiledBlueprints($this->blueprintLookup, $this->pluginLookup, 'master'); $this->loadCompiledConfig($this->configLookup, $this->pluginLookup, 'master'); @@ -255,7 +243,6 @@ class Config extends Data 'files' => $blueprintFiles, 'data' => $this->blueprints->toArray() ]; - // If compiled file wasn't already locked by another process, save it. if ($file->locked() !== false) { $this->messages[] = 'Saving compiled blueprints.'; @@ -269,44 +256,51 @@ class Config extends Data protected function loadCompiledConfig($configs, $plugins, $filename = null) { - $checksum = md5(json_encode($configs)); $filename = $filename ? CACHE_DIR . 'compiled/config/' . $filename . '-' . $this->environment . '.php' : CACHE_DIR . 'compiled/config/' . $checksum . '-' . $this->environment . '.php'; $file = PhpFile::instance($filename); $cache = $file->exists() ? $file->content() : null; - $configFiles = $this->finder->locateConfigFiles($configs, $plugins); - $checksum .= ':'.md5(json_encode($configFiles)); $class = get_class($this); + $checksum = $this->checksum(); - // Load real file if cache isn't up to date (or is invalid). if ( !is_array($cache) || !isset($cache['checksum']) || !isset($cache['@class']) - || $cache['checksum'] != $checksum || $cache['@class'] != $class ) { - // Attempt to lock the file for writing. - $file->lock(false); + $this->messages[] = 'No cached configuration, compiling new configuration..'; + } else if ($cache['checksum'] !== $checksum) { + $this->messages[] = 'Configuration checksum mismatch, reloading configuration..'; + } else { + $this->messages[] = 'Configuration checksum matches, using cached version.'; - // Load configuration. - foreach ($configFiles as $files) { - $this->loadConfigFiles($files); - } - $cache = [ - '@class' => $class, - 'timestamp' => time(), - 'checksum' => $this->checksum(), - 'data' => $this->toArray() - ]; + $this->items = $cache['data']; + return; + } - // If compiled file wasn't already locked by another process, save it. - if ($file->locked() !== false) { - $this->messages[] = 'Saving compiled configuration.'; - $file->save($cache); - $file->unlock(); - } + $configFiles = $this->finder->locateConfigFiles($configs, $plugins); + + // Attempt to lock the file for writing. + $file->lock(false); + + // Load configuration. + foreach ($configFiles as $files) { + $this->loadConfigFiles($files); + } + $cache = [ + '@class' => $class, + 'timestamp' => time(), + 'checksum' => $checksum, + 'data' => $this->toArray() + ]; + + // If compiled file wasn't already locked by another process, save it. + if ($file->locked() !== false) { + $this->messages[] = 'Saving compiled configuration.'; + $file->save($cache); + $file->unlock(); } $this->items = $cache['data']; diff --git a/system/src/Grav/Common/Service/ConfigServiceProvider.php b/system/src/Grav/Common/Service/ConfigServiceProvider.php index c66732b08..28a6ac4d9 100644 --- a/system/src/Grav/Common/Service/ConfigServiceProvider.php +++ b/system/src/Grav/Common/Service/ConfigServiceProvider.php @@ -38,18 +38,8 @@ class ConfigServiceProvider implements ServiceProviderInterface public function loadMasterConfig(Container $container) { $environment = $this->getEnvironment($container); - $file = CACHE_DIR . 'compiled/config/master-'.$environment.'.php'; - $data = is_file($file) ? (array) include $file : []; - if ($data) { - try { - $config = new Config($data, $container, $environment); - } catch (\Exception $e) { - } - } - if (!isset($config)) { - $config = new Config($this->setup, $container, $environment); - } + $config = new Config($this->setup, $container, $environment); return $config; } From f3b4efb66155e8df3a2ca8b5b36b240436e7c094 Mon Sep 17 00:00:00 2001 From: Gert Date: Thu, 16 Apr 2015 17:43:03 +0200 Subject: [PATCH 02/64] Make plugins and themes load the merged config from all files --- system/src/Grav/Common/Plugins.php | 4 ++-- system/src/Grav/Common/Themes.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index d0c30c3e3..9d8167df9 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -123,10 +123,10 @@ class Plugins extends Iterator $obj = new Data($file->content(), $blueprint); // Override with user configuration. - $file = CompiledYamlFile::instance("user://config/plugins/{$name}.yaml"); - $obj->merge($file->content()); + $obj->merge($this->grav['config']->get('plugins.' . $name) ?: []); // Save configuration always to user/config. + $file = CompiledYamlFile::instance("config://plugins/{$name}.yaml"); $obj->file($file); return $obj; diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index 4ec394ee9..ab4696a88 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -106,10 +106,10 @@ class Themes extends Iterator $obj = new Data($file->content(), $blueprint); // Override with user configuration. - $file = CompiledYamlFile::instance("user://config/themes/{$name}" . YAML_EXT); - $obj->merge($file->content()); + $obj->merge($this->grav['config']->get('themes.' . $name) ?: []); // Save configuration always to user/config. + $file = CompiledYamlFile::instance("config://themes/{$name}" . YAML_EXT); $obj->file($file); return $obj; From 7e94e464595c53684ebc406a61d823273f81dd7e Mon Sep 17 00:00:00 2001 From: Gert Date: Thu, 16 Apr 2015 17:54:48 +0200 Subject: [PATCH 03/64] use gravtrait in plugins --- system/src/Grav/Common/Grav.php | 2 +- system/src/Grav/Common/Plugins.php | 21 +++++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index df584fe4b..2068f3454 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -78,7 +78,7 @@ class Grav extends Container return new Cache($c); }; $container['plugins'] = function ($c) { - return new Plugins($c); + return new Plugins(); }; $container['themes'] = function ($c) { return new Themes($c); diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index 9d8167df9..b6264e9d9 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -4,6 +4,7 @@ namespace Grav\Common; use Grav\Common\Config\Config; use Grav\Common\Data\Blueprints; use Grav\Common\Data\Data; +use Grav\Common\GravTrait; use Grav\Common\File\CompiledYamlFile; use RocketTheme\Toolbox\Event\EventDispatcher; use RocketTheme\Toolbox\Event\EventSubscriberInterface; @@ -17,12 +18,7 @@ use RocketTheme\Toolbox\Event\EventSubscriberInterface; */ class Plugins extends Iterator { - protected $grav; - - public function __construct(Grav $grav) - { - $this->grav = $grav; - } + use GravTrait; /** * Recurses through the plugins directory creating Plugin objects for each plugin it finds. @@ -33,11 +29,11 @@ class Plugins extends Iterator public function init() { /** @var Config $config */ - $config = $this->grav['config']; + $config = self::getGrav()['config']; $plugins = (array) $config->get('plugins'); /** @var EventDispatcher $events */ - $events = $this->grav['events']; + $events = self::getGrav()['events']; foreach ($plugins as $plugin => $data) { if (empty($data['enabled'])) { @@ -45,9 +41,10 @@ class Plugins extends Iterator continue; } - $filePath = $this->grav['locator']('plugins://' . $plugin . DS . $plugin . PLUGIN_EXT); + $locator = self::getGrav()['locator']; + $filePath = $locator('plugins://' . $plugin . DS . $plugin . PLUGIN_EXT); if (!is_file($filePath)) { - $this->grav['log']->addWarning(sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $plugin)); + self::getGrav()['log']->addWarning(sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $plugin)); continue; } @@ -70,7 +67,7 @@ class Plugins extends Iterator throw new \RuntimeException(sprintf("Plugin '%s' class not found! Try reinstalling this plugin.", $plugin)); } - $instance = new $pluginClassName($plugin, $this->grav, $config); + $instance = new $pluginClassName($plugin, self::getGrav(), $config); if ($instance instanceof EventSubscriberInterface) { $events->addSubscriber($instance); } @@ -123,7 +120,7 @@ class Plugins extends Iterator $obj = new Data($file->content(), $blueprint); // Override with user configuration. - $obj->merge($this->grav['config']->get('plugins.' . $name) ?: []); + $obj->merge(self::getGrav()['config']->get('plugins.' . $name) ?: []); // Save configuration always to user/config. $file = CompiledYamlFile::instance("config://plugins/{$name}.yaml"); From 4883a408c764014e5dc5d73017235730e1d8d4ac Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 25 Apr 2015 18:41:45 -0600 Subject: [PATCH 04/64] updated composer.phar --- bin/composer.phar | Bin 1075141 -> 1098591 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/composer.phar b/bin/composer.phar index 31b9d3915f604997a7c343b86e86137b118b4769..f3d065ad9b311e025c02b25fde40e2ded287b53d 100755 GIT binary patch delta 33041 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

n5@>BK2jLdv0yFi}p%-JY69WE-A22LzI>%QyU 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

$d}yLG{i0FDq=LALDH@5z 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 From 8887f8862d9e6afca4bc4623dee26d674ac9c6d1 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 26 Apr 2015 15:30:10 -0600 Subject: [PATCH 05/64] Improved and cleaned up a couple of folder methods --- system/src/Grav/Common/Filesystem/Folder.php | 63 +++++++++++++++-- system/src/Grav/Common/Utils.php | 69 ------------------- .../src/Grav/Console/Cli/SandboxCommand.php | 4 +- .../src/Grav/Console/Gpm/InstallCommand.php | 2 +- 4 files changed, 60 insertions(+), 78 deletions(-) diff --git a/system/src/Grav/Common/Filesystem/Folder.php b/system/src/Grav/Common/Filesystem/Folder.php index 9355038b8..8309bebff 100644 --- a/system/src/Grav/Common/Filesystem/Folder.php +++ b/system/src/Grav/Common/Filesystem/Folder.php @@ -278,6 +278,46 @@ abstract class Folder } } + /** + * Recursive copy of one directory to another + * + * @param $src + * @param $dest + * + * @return bool + */ + public static function rcopy($src, $dest) + { + + // If the src is not a directory do a simple file copy + if (!is_dir($src)) { + copy($src, $dest); + return true; + } + + // If the destination directory does not exist create it + if (!is_dir($dest)) { + if (!mkdir($dest)) { + // If the destination directory could not be created stop processing + return false; + } + } + + // Open the source directory to read in files + $i = new \DirectoryIterator($src); + /** @var \DirectoryIterator $f */ + foreach ($i as $f) { + if ($f->isFile()) { + copy($f->getRealPath(), "$dest/" . $f->getFilename()); + } else { + if (!$f->isDot() && $f->isDir()) { + static::rcopy($f->getRealPath(), "$dest/$f"); + } + } + } + return true; + } + /** * @param string $folder * @return bool @@ -290,13 +330,24 @@ abstract class Folder return @unlink($folder); } - // Go through all items in filesystem and recursively remove everything. - $files = array_diff(scandir($folder), array('.', '..')); - foreach ($files as $file) { - $path = "{$folder}/{$file}"; - (is_dir($path)) ? self::doDelete($path) : @unlink($path); + $files = new \RecursiveIteratorIterator( + new \RecursiveDirectoryIterator($folder, \RecursiveDirectoryIterator::SKIP_DOTS), + \RecursiveIteratorIterator::CHILD_FIRST + ); + + /** @var \DirectoryIterator $fileinfo */ + foreach ($files as $fileinfo) { + if ($fileinfo->isDir()) { + if (false === rmdir($fileinfo->getRealPath())) { + return false; + } + } else { + if (false === unlink($fileinfo->getRealPath())) { + return false; + } + } } - return @rmdir($folder); + return rmdir($folder); } } diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index eee0ee4f9..830cb6a6b 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -54,75 +54,6 @@ abstract class Utils return (object) array_merge((array) $obj1, (array) $obj2); } - /** - * Recursive remove a directory - DANGEROUS! USE WITH CARE!!!! - * - * @param $dir - * @return bool - */ - public static function rrmdir($dir) - { - $files = new \RecursiveIteratorIterator( - new \RecursiveDirectoryIterator($dir, \RecursiveDirectoryIterator::SKIP_DOTS), - \RecursiveIteratorIterator::CHILD_FIRST - ); - - /** @var \DirectoryIterator $fileinfo */ - foreach ($files as $fileinfo) { - if ($fileinfo->isDir()) { - if (false === rmdir($fileinfo->getRealPath())) { - return false; - } - } else { - if (false === unlink($fileinfo->getRealPath())) { - return false; - } - } - } - - return rmdir($dir); - } - - /** - * Recursive copy of one directory to another - * - * @param $src - * @param $dest - * - * @return bool - */ - public static function rcopy($src, $dest) - { - - // If the src is not a directory do a simple file copy - if (!is_dir($src)) { - copy($src, $dest); - return true; - } - - // If the destination directory does not exist create it - if (!is_dir($dest)) { - if (!mkdir($dest)) { - // If the destination directory could not be created stop processing - return false; - } - } - - // Open the source directory to read in files - $i = new \DirectoryIterator($src); - /** @var \DirectoryIterator $f */ - foreach ($i as $f) { - if ($f->isFile()) { - copy($f->getRealPath(), "$dest/" . $f->getFilename()); - } else { - if (!$f->isDot() && $f->isDir()) { - static::rcopy($f->getRealPath(), "$dest/$f"); - } - } - } - return true; - } - /** * Truncate HTML by text length. * diff --git a/system/src/Grav/Console/Cli/SandboxCommand.php b/system/src/Grav/Console/Cli/SandboxCommand.php index 4d984d219..c1e79ecdc 100644 --- a/system/src/Grav/Console/Cli/SandboxCommand.php +++ b/system/src/Grav/Console/Cli/SandboxCommand.php @@ -189,7 +189,7 @@ class SandboxCommand extends Command $to = $this->destination . $target; $this->output->writeln(' ' . $source . ' -> ' . $to); - Utils::rcopy($from, $to); + Folder::rcopy($from, $to); } } @@ -269,7 +269,7 @@ class SandboxCommand extends Command if (count($pages_files) == 0) { $destination = $this->source . '/user/pages'; - Utils::rcopy($destination, $pages_dir); + Folder::rcopy($destination, $pages_dir); $this->output->writeln(' ' . $destination . ' -> Created'); } diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index c39087db4..60e01196f 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -255,7 +255,7 @@ class InstallCommand extends Command // Confirmation received, copy over the data $this->output->writeln(" |- Installing demo content... ok "); - Utils::rcopy($demo_dir, $dest_dir); + Folder::rcopy($demo_dir, $dest_dir); $this->output->writeln(" '- Success! "); $this->output->writeln(''); } From 8a2817a305df084937813214278bf3ddf63f0067 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 26 Apr 2015 16:39:58 -0600 Subject: [PATCH 06/64] Added check for curl in GPM --- bin/gpm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/gpm b/bin/gpm index 803722981..26305d3fa 100755 --- a/bin/gpm +++ b/bin/gpm @@ -26,6 +26,10 @@ if (!file_exists(ROOT_DIR . 'index.php')) { exit('FATAL: Must be run from ROOT directory of Grav!'); } +if (!function_exists('curl_version')) { + exit('FATAL: GPM requires PHP Curl module to be installed'); +} + $grav = Grav::instance(array('loader' => $autoload)); $grav['config']->init(); $grav['streams']; From 4bda629a6a2bfc47771e6556b3bf1238859a52e6 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 26 Apr 2015 16:58:45 -0600 Subject: [PATCH 07/64] handle condition of errors resulting in blank page. --- system/src/Grav/Common/Service/ErrorServiceProvider.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Service/ErrorServiceProvider.php b/system/src/Grav/Common/Service/ErrorServiceProvider.php index 66453e34d..ac676ad98 100644 --- a/system/src/Grav/Common/Service/ErrorServiceProvider.php +++ b/system/src/Grav/Common/Service/ErrorServiceProvider.php @@ -30,7 +30,11 @@ class ErrorServiceProvider implements ServiceProviderInterface $logger = $container['log']; $errors->pushHandler(function (\Exception $exception, $inspector, $run) use ($logger) { - $logger->addCritical($exception->getMessage(). ' - Trace: '. $exception->getTraceAsString()); + try { + $logger->addCritical($exception->getMessage() . ' - Trace: ' . $exception->getTraceAsString()); + } catch (\Exception $e) { + echo $e; + } }, 'log'); $errors->register(); From d461fac0890cb10df72c15b31037858cb7c2e8aa Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 26 Apr 2015 17:20:52 -0600 Subject: [PATCH 08/64] optimize install of vendor libs --- system/src/Grav/Console/Cli/InstallCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Console/Cli/InstallCommand.php b/system/src/Grav/Console/Cli/InstallCommand.php index f0510a51f..a8c98f370 100644 --- a/system/src/Grav/Console/Cli/InstallCommand.php +++ b/system/src/Grav/Console/Cli/InstallCommand.php @@ -98,7 +98,7 @@ class InstallCommand extends Command if (!$input->getOption('symlink')) { // Updates composer first $output->writeln("\nInstalling vendor dependencies"); - $output->writeln(system('php bin/composer.phar --working-dir="'.$this->destination.'" --no-interaction update')); + $output->writeln(system('php bin/composer.phar --working-dir="'.$this->destination.'" --no-interaction --no-dev -o install')); $this->gitclone($output); } else { From d25699397fb9f3883e65fe3e566c79078d226e1f Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 26 Apr 2015 17:21:12 -0600 Subject: [PATCH 09/64] add composer update to gpm selfupgrade --- system/src/Grav/Console/Gpm/SelfupgradeCommand.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php index 4d2895312..2b80b2793 100644 --- a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php +++ b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php @@ -153,6 +153,9 @@ class SelfupgradeCommand extends Command $this->output->writeln(''); } + $this->output->writeln("\nInstalling vendor dependencies"); + $this->output->writeln(system('php bin/composer.phar --working-dir="'.$this->destination.'" --no-interaction --no-dev -o install')); + // clear cache after successful upgrade $this->clearCache('all'); } From ae453dbc71ef9d27de2dbaeda5a97728eae2ebbf Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 26 Apr 2015 17:21:38 -0600 Subject: [PATCH 10/64] restore deprecated for whoops - causing composer issue --- system/src/Grav/Console/Cli/CleanCommand.php | 1 - 1 file changed, 1 deletion(-) diff --git a/system/src/Grav/Console/Cli/CleanCommand.php b/system/src/Grav/Console/Cli/CleanCommand.php index 749b7c5e8..5ceaed611 100644 --- a/system/src/Grav/Console/Cli/CleanCommand.php +++ b/system/src/Grav/Console/Cli/CleanCommand.php @@ -66,7 +66,6 @@ class CleanCommand extends Command 'vendor/filp/whoops/.scrutinizer.yml', 'vendor/filp/whoops/.travis.yml', 'vendor/filp/whoops/phpunit.xml.dist', - 'vendor/filp/whoops/src/deprecated', 'vendor/gregwar/image/Gregwar/Image/composer.json', 'vendor/gregwar/image/Gregwar/Image/phpunit.xml', 'vendor/gregwar/image/Gregwar/Image/.gitignore', From 2936d26f8d450308c2e9a8ea898800ae2ba755f8 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 26 Apr 2015 17:37:34 -0600 Subject: [PATCH 11/64] added --prefer-dist to these commands --- system/src/Grav/Console/Cli/InstallCommand.php | 2 +- system/src/Grav/Console/Gpm/SelfupgradeCommand.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Console/Cli/InstallCommand.php b/system/src/Grav/Console/Cli/InstallCommand.php index a8c98f370..b316e5701 100644 --- a/system/src/Grav/Console/Cli/InstallCommand.php +++ b/system/src/Grav/Console/Cli/InstallCommand.php @@ -98,7 +98,7 @@ class InstallCommand extends Command if (!$input->getOption('symlink')) { // Updates composer first $output->writeln("\nInstalling vendor dependencies"); - $output->writeln(system('php bin/composer.phar --working-dir="'.$this->destination.'" --no-interaction --no-dev -o install')); + $output->writeln(system('php bin/composer.phar --working-dir="'.$this->destination.'" --no-interaction --no-dev --prefer-dist -o install')); $this->gitclone($output); } else { diff --git a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php index 2b80b2793..29eb77d58 100644 --- a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php +++ b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php @@ -154,7 +154,7 @@ class SelfupgradeCommand extends Command } $this->output->writeln("\nInstalling vendor dependencies"); - $this->output->writeln(system('php bin/composer.phar --working-dir="'.$this->destination.'" --no-interaction --no-dev -o install')); + $this->output->writeln(system('php bin/composer.phar --working-dir="'.GRAV_ROOT.'" --no-interaction --no-dev --prefer-dist -o install')); // clear cache after successful upgrade $this->clearCache('all'); From 21cc9f86f3182db113e7b8a2b9f15bf6fa3b14ac Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 26 Apr 2015 18:00:34 -0600 Subject: [PATCH 12/64] added new composer update command --- bin/grav | 3 +- .../src/Grav/Console/Cli/ComposerCommand.php | 80 +++++++++++++++++++ .../src/Grav/Console/Cli/InstallCommand.php | 5 +- system/src/Grav/Console/ConsoleTrait.php | 5 ++ .../Grav/Console/Gpm/SelfupgradeCommand.php | 2 +- 5 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 system/src/Grav/Console/Cli/ComposerCommand.php diff --git a/bin/grav b/bin/grav index 2b754f153..2d412dd36 100755 --- a/bin/grav +++ b/bin/grav @@ -9,7 +9,7 @@ if (version_compare($ver = PHP_VERSION, $req = '5.4.0', '<')) { if (!file_exists(__DIR__ . '/../vendor')){ // Before we can even start, we need to run composer first echo "Preparing to install vendor dependencies...\n\n"; - echo system('php bin/composer.phar --working-dir="'.__DIR__.'/../" --no-interaction install'); + echo system('php bin/composer.phar --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist install'); echo "\n\n"; } @@ -28,6 +28,7 @@ if (!file_exists(ROOT_DIR . 'index.php')) { $app = new Application('Grav CLI Application', '0.1.0'); $app->addCommands(array( new Grav\Console\Cli\InstallCommand(), + new Grav\Console\Cli\ComposerCommand(), new Grav\Console\Cli\SandboxCommand(), new Grav\Console\Cli\CleanCommand(), new Grav\Console\Cli\ClearCacheCommand(), diff --git a/system/src/Grav/Console/Cli/ComposerCommand.php b/system/src/Grav/Console/Cli/ComposerCommand.php new file mode 100644 index 000000000..3a28718ac --- /dev/null +++ b/system/src/Grav/Console/Cli/ComposerCommand.php @@ -0,0 +1,80 @@ +setName("composer") + ->addOption( + 'install', + 'i', + InputOption::VALUE_NONE, + 'install the dependencies' + ) + ->addOption( + 'update', + 'u', + InputOption::VALUE_NONE, + 'update the dependencies' + ) + ->setDescription("Updates the composer vendordependencies needed by Grav.") + ->setHelp('The composer command updates the composer vendordependencies needed by Grav'); + } + + /** + * @param InputInterface $input + * @param OutputInterface $output + * + * @return int|null|void + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $action = 'update'; + + if ($input->getOption('install')) { + $action = 'install'; + } + + // Updates composer first + $output->writeln("\nInstalling vendor dependencies"); + $output->writeln($this->composerUpdate(GRAV_ROOT, $action)); + } + +} diff --git a/system/src/Grav/Console/Cli/InstallCommand.php b/system/src/Grav/Console/Cli/InstallCommand.php index b316e5701..8aead008f 100644 --- a/system/src/Grav/Console/Cli/InstallCommand.php +++ b/system/src/Grav/Console/Cli/InstallCommand.php @@ -1,6 +1,7 @@ getOption('symlink')) { // Updates composer first $output->writeln("\nInstalling vendor dependencies"); - $output->writeln(system('php bin/composer.phar --working-dir="'.$this->destination.'" --no-interaction --no-dev --prefer-dist -o install')); + $output->writeln($this->composerUpdate(GRAV_ROOT, 'install')); $this->gitclone($output); } else { diff --git a/system/src/Grav/Console/ConsoleTrait.php b/system/src/Grav/Console/ConsoleTrait.php index 42c65d495..a2e80b6e8 100644 --- a/system/src/Grav/Console/ConsoleTrait.php +++ b/system/src/Grav/Console/ConsoleTrait.php @@ -83,6 +83,11 @@ trait ConsoleTrait } } + public function composerUpdate($path, $action = 'install') + { + return system('php bin/composer.phar --working-dir="'.$path.'" --no-interaction --no-dev --prefer-dist -o '. $action); + } + /** * @param array $all * diff --git a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php index 29eb77d58..5ed68ced2 100644 --- a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php +++ b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php @@ -154,7 +154,7 @@ class SelfupgradeCommand extends Command } $this->output->writeln("\nInstalling vendor dependencies"); - $this->output->writeln(system('php bin/composer.phar --working-dir="'.GRAV_ROOT.'" --no-interaction --no-dev --prefer-dist -o install')); + $this->output->writeln($this->composerUpdate(GRAV_ROOT, 'update')); // clear cache after successful upgrade $this->clearCache('all'); From 1546783371c6060851c012c17d5c5a30b9197aa2 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 26 Apr 2015 18:10:56 -0600 Subject: [PATCH 13/64] upgrade already has vendor libs --- system/src/Grav/Console/Gpm/SelfupgradeCommand.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php index 5ed68ced2..4d2895312 100644 --- a/system/src/Grav/Console/Gpm/SelfupgradeCommand.php +++ b/system/src/Grav/Console/Gpm/SelfupgradeCommand.php @@ -153,9 +153,6 @@ class SelfupgradeCommand extends Command $this->output->writeln(''); } - $this->output->writeln("\nInstalling vendor dependencies"); - $this->output->writeln($this->composerUpdate(GRAV_ROOT, 'update')); - // clear cache after successful upgrade $this->clearCache('all'); } From 67c3d64275ba4e83dcdb0915f68af9c28f009489 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 26 Apr 2015 18:13:53 -0600 Subject: [PATCH 14/64] optimize composer --- bin/gpm | 2 +- bin/grav | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/gpm b/bin/gpm index 26305d3fa..a19fea5d1 100755 --- a/bin/gpm +++ b/bin/gpm @@ -9,7 +9,7 @@ if (version_compare($ver = PHP_VERSION, $req = '5.4.0', '<')) { if (!file_exists(__DIR__ . '/../vendor')){ // Before we can even start, we need to run composer first echo "Preparing to install vendor dependencies...\n\n"; - echo system('php bin/composer.phar --working-dir="'.__DIR__.'/../" --no-interaction install'); + echo system('php bin/composer.phar --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install'); echo "\n\n"; } diff --git a/bin/grav b/bin/grav index 2d412dd36..1d31dd687 100755 --- a/bin/grav +++ b/bin/grav @@ -9,7 +9,7 @@ if (version_compare($ver = PHP_VERSION, $req = '5.4.0', '<')) { if (!file_exists(__DIR__ . '/../vendor')){ // Before we can even start, we need to run composer first echo "Preparing to install vendor dependencies...\n\n"; - echo system('php bin/composer.phar --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist install'); + echo system('php bin/composer.phar --working-dir="'.__DIR__.'/../" --no-interaction --no-dev --prefer-dist -o install'); echo "\n\n"; } From d849f8a03ecab8d4dea441dddd84ef650a8d5006 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 26 Apr 2015 18:45:47 -0600 Subject: [PATCH 15/64] Added page level summary header overrides --- system/src/Grav/Common/Page/Page.php | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index e0c7ca963..1d8a80241 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -303,21 +303,25 @@ class Page public function summary($size = null) { /** @var Config $config */ - $config = self::getGrav()['config']; + $config = self::getGrav()['config']->get('site.summary'); $content = $this->content(); + if (isset($this->header->summary)) { + $config = array_merge($config, $this->header->summary); + } + // Return summary based on settings in site config file - if (!$config->get('site.summary.enabled', true)) { + if (!$config['enabled']) { return $content; } // Get summary size from site config's file if (is_null($size)) { - $size = $config->get('site.summary.size', null); + $size = $config['size']; } // Return calculated summary based on summary divider's position - $format = $config->get('site.summary.format', 'short'); + $format = $config['format']; // Return entire page content on wrong/ unknown format if (!in_array($format, array('short', 'long'))) { return $content; From e1d655a3ac3e36b7a0bc6ef68ec2d1261f69588b Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 27 Apr 2015 12:40:30 +0200 Subject: [PATCH 16/64] move backup code into Grav\Common --- system/src/Grav/Common/Backup/ZipBackup.php | 103 ++++++++++++++++++ system/src/Grav/Console/Cli/BackupCommand.php | 51 ++++----- 2 files changed, 122 insertions(+), 32 deletions(-) create mode 100644 system/src/Grav/Common/Backup/ZipBackup.php diff --git a/system/src/Grav/Common/Backup/ZipBackup.php b/system/src/Grav/Common/Backup/ZipBackup.php new file mode 100644 index 000000000..1836c56df --- /dev/null +++ b/system/src/Grav/Common/Backup/ZipBackup.php @@ -0,0 +1,103 @@ +findResource('cache://', true); + $destination = $destination . DS . 'tmp/Grav-' . uniqid(); + Folder::mkdir($destination); + } + + $name = basename(GRAV_ROOT); + + if (is_dir($destination)) { + $date = date('YmdHis', time()); + $filename = $name . '-' . $date . '.zip'; + $destination = rtrim($destination, DS) . DS . $filename; + } + + $messager && $messager([ + 'type' => 'message', + 'level' => 'info', + 'message' => 'Creating new Backup "' . $destination . '"' + ]); + $messager && $messager([ + 'type' => 'message', + 'level' => 'info', + 'message' => '' + ]); + + $zip = new \ZipArchive(); + $zip->open($destination, \ZipArchive::CREATE); + $zip->addEmptyDir($name); + + static::folderToZip(GRAV_ROOT, $zip, strlen(rtrim(GRAV_ROOT, DS) . DS), $messager); + + $messager && $messager([ + 'type' => 'progress', + 'percentage' => false, + 'complete' => true + ]); + + $messager && $messager([ + 'type' => 'message', + 'level' => 'info', + 'message' => '' + ]); + $messager && $messager([ + 'type' => 'message', + 'level' => 'info', + 'message' => 'Saving and compressing archive...' + ]); + + $zip->close(); + + return $destination; + } + + /** + * @param $folder + * @param $zipFile + * @param $exclusiveLength + * @param $messager + */ + private static function folderToZip($folder, \ZipArchive &$zipFile, $exclusiveLength, callable $messager = null) + { + $handle = opendir($folder); + while (false !== $f = readdir($handle)) { + if ($f != '.' && $f != '..') { + $filePath = "$folder/$f"; + // Remove prefix from file path before add to zip. + $localPath = substr($filePath, $exclusiveLength); + if (is_file($filePath)) { + $zipFile->addFile($filePath, $localPath); + + $messager && $messager([ + 'type' => 'progress', + 'percentage' => false, + 'complete' => false + ]); + } elseif (is_dir($filePath)) { + // Add sub-directory. + $zipFile->addEmptyDir($localPath); + static::folderToZip($filePath, $zipFile, $exclusiveLength, $messager); + } + } + } + closedir($handle); + } +} diff --git a/system/src/Grav/Console/Cli/BackupCommand.php b/system/src/Grav/Console/Cli/BackupCommand.php index 050301762..46590bf39 100644 --- a/system/src/Grav/Console/Cli/BackupCommand.php +++ b/system/src/Grav/Console/Cli/BackupCommand.php @@ -7,6 +7,7 @@ use Symfony\Component\Console\Helper\ProgressBar; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; +use Grav\Common\Backup\ZipBackup; /** * Class BackupCommand @@ -23,6 +24,10 @@ class BackupCommand extends Command * @var */ protected $progress; + /** + * @var + */ + protected $output; /** * @@ -52,6 +57,8 @@ class BackupCommand extends Command */ protected function execute(InputInterface $input, OutputInterface $output) { + $this->output = $output; + $output->getFormatter()->setStyle('red', new OutputFormatterStyle('red')); $output->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan')); $output->getFormatter()->setStyle('green', new OutputFormatterStyle('green')); @@ -60,25 +67,10 @@ class BackupCommand extends Command $this->progress = new ProgressBar($output); $this->progress->setFormat('Archiving %current% files [%bar%] %elapsed:6s% %memory:6s%'); - $name = basename($this->source); - $dir = dirname($this->source); - $date = date('YmdHis', time()); - $filename = $name . '-' . $date . '.zip'; - $destination = ($input->getArgument('destination')) ? $input->getArgument('destination') : ROOT_DIR; - $destination = rtrim($destination, DS) . DS . $filename; - $output->writeln(''); - $output->writeln('Creating new Backup "' . $destination . '"'); - $this->progress->start(); + ZipBackup::backup($destination, [$this, 'output']); - $zip = new \ZipArchive(); - $zip->open($destination, \ZipArchive::CREATE); - $zip->addEmptyDir($name); - - $this->folderToZip($this->source, $zip, strlen($dir . DS), $this->progress); - $zip->close(); - $this->progress->finish(); $output->writeln(''); $output->writeln(''); @@ -90,25 +82,20 @@ class BackupCommand extends Command * @param $exclusiveLength * @param $progress */ - private static function folderToZip($folder, \ZipArchive &$zipFile, $exclusiveLength, ProgressBar $progress) + public function output($args) { - $handle = opendir($folder); - while (false !== $f = readdir($handle)) { - if ($f != '.' && $f != '..') { - $filePath = "$folder/$f"; - // Remove prefix from file path before add to zip. - $localPath = substr($filePath, $exclusiveLength); - if (is_file($filePath)) { - $zipFile->addFile($filePath, $localPath); - $progress->advance(); - } elseif (is_dir($filePath)) { - // Add sub-directory. - $zipFile->addEmptyDir($localPath); - self::folderToZip($filePath, $zipFile, $exclusiveLength, $progress); + switch ($args['type']) { + case 'message': + $this->output->writeln($args['message']); + break; + case 'progress': + if ($args['complete']) { + $this->progress->finish(); + } else { + $this->progress->advance(); } - } + break; } - closedir($handle); } } From bbdb0189f1594900fafb0cb33fba3e2c7e15ec16 Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 27 Apr 2015 16:13:48 +0200 Subject: [PATCH 17/64] use site name for backup archive name --- system/src/Grav/Common/Backup/ZipBackup.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Backup/ZipBackup.php b/system/src/Grav/Common/Backup/ZipBackup.php index 1836c56df..48991b7b5 100644 --- a/system/src/Grav/Common/Backup/ZipBackup.php +++ b/system/src/Grav/Common/Backup/ZipBackup.php @@ -22,7 +22,7 @@ class ZipBackup Folder::mkdir($destination); } - $name = basename(GRAV_ROOT); + $name = self::getGrav()['config']->get('site.title', basename(GRAV_ROOT)); if (is_dir($destination)) { $date = date('YmdHis', time()); From c481acbb7185c3a0408ade4cc8e7a8d83e07b8cb Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 27 Apr 2015 16:24:17 +0200 Subject: [PATCH 18/64] implement ignore for backups --- system/src/Grav/Common/Backup/ZipBackup.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Backup/ZipBackup.php b/system/src/Grav/Common/Backup/ZipBackup.php index 48991b7b5..cdef16efc 100644 --- a/system/src/Grav/Common/Backup/ZipBackup.php +++ b/system/src/Grav/Common/Backup/ZipBackup.php @@ -14,6 +14,13 @@ class ZipBackup { use GravTrait; + protected static $ignore = [ + '.git', + 'cache', + 'images', + 'logs' + ]; + public static function backup($destination = null, callable $messager = null) { if (!$destination) { @@ -43,7 +50,6 @@ class ZipBackup $zip = new \ZipArchive(); $zip->open($destination, \ZipArchive::CREATE); - $zip->addEmptyDir($name); static::folderToZip(GRAV_ROOT, $zip, strlen(rtrim(GRAV_ROOT, DS) . DS), $messager); @@ -83,6 +89,11 @@ class ZipBackup $filePath = "$folder/$f"; // Remove prefix from file path before add to zip. $localPath = substr($filePath, $exclusiveLength); + + if (in_array($localPath, static::$ignore)) { + continue; + } + if (is_file($filePath)) { $zipFile->addFile($filePath, $localPath); From 93f4ad6e5ace9beba5afa7de1f1b26f823b508c4 Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 27 Apr 2015 19:29:32 +0200 Subject: [PATCH 19/64] upload limit setting --- system/config/system.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/system/config/system.yaml b/system/config/system.yaml index 38550d690..d6d84a7ff 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -78,6 +78,7 @@ images: media: enable_media_timestamp: false # Enable media timetsamps + upload_limit: 0 # Set maximum upload size in bytes (0 is unlimited) security: default_hash: $2y$10$kwsyMVwM8/7j0K/6LHT.g.Fs49xOCTp2b8hh/S5.dPJuJcJB6T.UK From 5ccefee2889daa2a7e4664d1d7397451d457a8c0 Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 27 Apr 2015 21:45:42 +0200 Subject: [PATCH 20/64] backup to backup folder --- .gitignore | 2 ++ backup/.gitkeep | 0 system/src/Grav/Common/Backup/ZipBackup.php | 8 ++++++-- system/src/Grav/Common/Config/Config.php | 6 ++++++ system/src/Grav/Console/Cli/SandboxCommand.php | 1 + 5 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 backup/.gitkeep diff --git a/.gitignore b/.gitignore index d436576ff..da248e548 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ vendor/ .sass-cache # Grav Specific +backup/* +!backup/.* cache/* !cache/.* assets/* diff --git a/backup/.gitkeep b/backup/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/system/src/Grav/Common/Backup/ZipBackup.php b/system/src/Grav/Common/Backup/ZipBackup.php index cdef16efc..2951cf9bf 100644 --- a/system/src/Grav/Common/Backup/ZipBackup.php +++ b/system/src/Grav/Common/Backup/ZipBackup.php @@ -16,6 +16,7 @@ class ZipBackup protected static $ignore = [ '.git', + 'backup', 'cache', 'images', 'logs' @@ -24,8 +25,11 @@ class ZipBackup public static function backup($destination = null, callable $messager = null) { if (!$destination) { - $destination = self::getGrav()['locator']->findResource('cache://', true); - $destination = $destination . DS . 'tmp/Grav-' . uniqid(); + $destination = self::getGrav()['locator']->findResource('backup://', true); + + if (!$destination) + throw new \RuntimeException('The backup folder is missing.'); + Folder::mkdir($destination); } diff --git a/system/src/Grav/Common/Config/Config.php b/system/src/Grav/Common/Config/Config.php index 1fe373a40..60f443108 100644 --- a/system/src/Grav/Common/Config/Config.php +++ b/system/src/Grav/Common/Config/Config.php @@ -72,6 +72,12 @@ class Config extends Data 'prefixes' => [ '' => ['logs'] ] + ], + 'backup' => [ + 'type' => 'Stream', + 'prefixes' => [ + '' => ['backup'] + ] ] ]; diff --git a/system/src/Grav/Console/Cli/SandboxCommand.php b/system/src/Grav/Console/Cli/SandboxCommand.php index 4d984d219..ef85e42bb 100644 --- a/system/src/Grav/Console/Cli/SandboxCommand.php +++ b/system/src/Grav/Console/Cli/SandboxCommand.php @@ -20,6 +20,7 @@ class SandboxCommand extends Command * @var array */ protected $directories = array( + '/backup', '/cache', '/logs', '/images', From e364616730b98888d1f969382af548a7debd019c Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 27 Apr 2015 21:53:08 +0200 Subject: [PATCH 21/64] add server directives to block access to backup folder --- .htaccess | 2 +- nginx.conf | 6 ++- web.config | 106 +++++++++++++++++++++++++++-------------------------- 3 files changed, 61 insertions(+), 53 deletions(-) diff --git a/.htaccess b/.htaccess index ce48b2674..ecf1097c0 100644 --- a/.htaccess +++ b/.htaccess @@ -44,7 +44,7 @@ RewriteRule .* index.php [L] ## Begin - Security # Block all direct access for these folders -RewriteRule ^(cache|bin|logs)/(.*) error [L] +RewriteRule ^(cache|bin|logs|backup)/(.*) error [L] # Block access to specific file types for these folders RewriteRule ^(system|user|vendor)/(.*)\.(txt|md|html|yaml|php|twig|sh|bat)$ error [L] ## End - Security diff --git a/nginx.conf b/nginx.conf index 12a48054a..afa450c23 100644 --- a/nginx.conf +++ b/nginx.conf @@ -25,7 +25,7 @@ http { index index.php; if (!-e $request_filename){ rewrite ^(.*)$ /index.php last; } } - + location /images/ { # Serve images as static } @@ -44,6 +44,10 @@ http { rewrite ^/bin/(.*)$ /error redirect; } + location /backup { + rewrite ^/backup/(.*) /error redirect; + } + location /system { rewrite ^/system/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect; } diff --git a/web.config b/web.config index 85d2c1b1b..c3dd31424 100644 --- a/web.config +++ b/web.config @@ -1,51 +1,55 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 5d38e0fa14bf3c087c90694b2e54c44ac616fc67 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 27 Apr 2015 21:41:52 -0600 Subject: [PATCH 22/64] add a menu sample in site.yaml --- system/config/site.yaml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/system/config/site.yaml b/system/config/site.yaml index 23c0f1f1b..72bc8027a 100644 --- a/system/config/site.yaml +++ b/system/config/site.yaml @@ -1,18 +1,31 @@ title: Grav # Name of the site + author: name: John Appleseed # Default author name email: 'john@email.com' # Default author email + taxonomies: [category,tag] # Arbitrary list of taxonomy types + blog: - route: '/blog' # Route to blog + route: '/blog' # Route to blog (deprecated) + metadata: description: 'My Grav Site' # Site description + summary: enabled: true # enable or disable summary of page format: short # long = summary delimiter will be ignored; short = use the first occurence of delimter or size size: 300 # Maximum length of summary (characters) delimiter: === # The summary delimiter + routes: /something/else: '/blog/sample-3' # Alias for /blog/sample-3 /another/one/here: '/blog/sample-3' # Another alias for /blog/sample-3 /new/*: '/blog/*' # Wildcard any /new/my-page URL to /blog/my-page Route + +#menu: # Sample Menu Example +# - text: Source +# icon: github +# url: https://github.com/getgrav/grav +# - icon: twitter +# url: http://twitter.com/getgrav From 7acdf231a45b8ce330f01ba805606bf3093e007a Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 28 Apr 2015 11:21:47 -0600 Subject: [PATCH 23/64] removed php config overrides --- system/src/Grav/Common/Utils.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index 830cb6a6b..acb228789 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -185,8 +185,6 @@ abstract class Utils set_time_limit(0); ignore_user_abort(false); - ini_set('output_buffering', 0); - ini_set('zlib.output_compression', 0); if ($force_download) { header('Content-Description: File Transfer'); From f7ea2e95e41ce94f180400d3bfdc82dce242ab9b Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 28 Apr 2015 11:24:46 -0600 Subject: [PATCH 24/64] strict comparison --- 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 b3d204232..0f1358216 100644 --- a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php +++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php @@ -37,7 +37,7 @@ trait ParsedownGravTrait $this->pages_dir = self::getGrav()['locator']->findResource('page://'); $this->special_chars = array('>' => 'gt', '<' => 'lt', '"' => 'quot'); - if ($defaults == null) { + if ($defaults === null) { $defaults = self::getGrav()['config']->get('system.pages.markdown'); } From 084e59dc90976fa87c5176c3271ddb947872d7cc Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 28 Apr 2015 11:26:18 -0600 Subject: [PATCH 25/64] remove unused var --- system/src/Grav/Common/Page/Medium/ImageMedium.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Page/Medium/ImageMedium.php b/system/src/Grav/Common/Page/Medium/ImageMedium.php index 17a9663de..bea2b10d6 100644 --- a/system/src/Grav/Common/Page/Medium/ImageMedium.php +++ b/system/src/Grav/Common/Page/Medium/ImageMedium.php @@ -308,7 +308,7 @@ class ImageMedium extends Medium } try { - $result = call_user_func_array([$this->image, $method], $args); + call_user_func_array([$this->image, $method], $args); foreach ($this->alternatives as $ratio => $medium) { $args_copy = $args; From 64bb6ea2ad114ee63e67be1e484d72dfe8593690 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 28 Apr 2015 11:26:30 -0600 Subject: [PATCH 26/64] remove another unused var --- system/src/Grav/Common/Utils.php | 1 - 1 file changed, 1 deletion(-) diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index acb228789..97e4d6b52 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -181,7 +181,6 @@ abstract class Utils $file_parts = pathinfo($file); $filesize = filesize($file); - $range = false; set_time_limit(0); ignore_user_abort(false); From 491c6d6a1f530e93da61794ef6e0e7532a48164e Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 28 Apr 2015 11:28:08 -0600 Subject: [PATCH 27/64] fixed missing classes --- system/src/Grav/Common/Page/Medium/Link.php | 2 +- system/src/Grav/Common/Page/Medium/Medium.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Page/Medium/Link.php b/system/src/Grav/Common/Page/Medium/Link.php index 1262bddf9..a92ec228e 100644 --- a/system/src/Grav/Common/Page/Medium/Link.php +++ b/system/src/Grav/Common/Page/Medium/Link.php @@ -60,6 +60,6 @@ class Link implements RenderableInterface // Don't start nesting links, if user has multiple link calls in his // actions, we will drop the previous links. - return $this->source instanceof LinkMedium ? $this->source : $this; + return $this->source instanceof Link ? $this->source : $this; } } diff --git a/system/src/Grav/Common/Page/Medium/Medium.php b/system/src/Grav/Common/Page/Medium/Medium.php index 5c210e563..0eb0666ce 100644 --- a/system/src/Grav/Common/Page/Medium/Medium.php +++ b/system/src/Grav/Common/Page/Medium/Medium.php @@ -399,7 +399,7 @@ class Medium extends Data implements RenderableInterface $thumb = $this->get('thumbnails.' . $type, false); if ($thumb) { - $thumb = $thumb instanceof ThumbnailMedium ? $thumb : MediumFactory::fromFile($thumb, ['type' => 'thumbnail']); + $thumb = $thumb instanceof ThumbnailImageMedium ? $thumb : MediumFactory::fromFile($thumb, ['type' => 'thumbnail']); $thumb->parent = $this; } From 3a25f028dfb8e7807e4bdf407ef432745328d6fc Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 28 Apr 2015 11:30:03 -0600 Subject: [PATCH 28/64] Commented these out for now --- .../src/Grav/Console/Gpm/InstallCommand.php | 116 +++++++++--------- 1 file changed, 57 insertions(+), 59 deletions(-) diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index 60e01196f..f9b6b9a6f 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -352,65 +352,63 @@ class InstallCommand extends Command $this->output->writeln(" '- Installation failed or aborted."); } - /** - * @param $package - */ - private function processGit($package) - { - $matches = $this->getGitRegexMatches($package); - - $to = $this->destination . DS . $package->install_path; - - $this->output->writeln("Preparing to Git clone " . $package->name . " from " . $matches[0]); - - $this->output->write(" |- Checking destination... "); - $checks = $this->checkDestination($package); - - if (!$checks) { - $this->output->writeln(" '- Installation failed or aborted."); - $this->output->writeln(''); - } else { - $cmd = 'cd ' . $this->destination . ' && git clone ' . $matches[0] . ' ' . $package->install_path; - exec($cmd); - - // extra white spaces to clear out the buffer properly - $this->output->writeln(" |- Cloning package... ok "); - - $this->output->writeln(" '- Success! "); - $this->output->writeln(''); - } - } - - /** - * @param $package - */ - private function processGPM($package) - { - $version = isset($package->available) ? $package->available : $package->version; - - $this->output->writeln("Preparing to install " . $package->name . " [v" . $version . "]"); - - $this->output->write(" |- Downloading package... 0%"); - $this->file = $this->downloadPackage($package); - - $this->output->write(" |- Checking destination... "); - $checks = $this->checkDestination($package); - - if (!$checks) { - $this->output->writeln(" '- Installation failed or aborted."); - $this->output->writeln(''); - } else { - $this->output->write(" |- Installing package... "); - $installation = $this->installPackage($package); - if (!$installation) { - $this->output->writeln(" '- Installation failed or aborted."); - $this->output->writeln(''); - } else { - $this->output->writeln(" '- Success! "); - $this->output->writeln(''); - } - } - } +// /** +// * @param $package +// */ +// private function processGit($package) +// { +// $matches = $this->getGitRegexMatches($package); +// +// $this->output->writeln("Preparing to Git clone " . $package->name . " from " . $matches[0]); +// +// $this->output->write(" |- Checking destination... "); +// $checks = $this->checkDestination($package); +// +// if (!$checks) { +// $this->output->writeln(" '- Installation failed or aborted."); +// $this->output->writeln(''); +// } else { +// $cmd = 'cd ' . $this->destination . ' && git clone ' . $matches[0] . ' ' . $package->install_path; +// exec($cmd); +// +// // extra white spaces to clear out the buffer properly +// $this->output->writeln(" |- Cloning package... ok "); +// +// $this->output->writeln(" '- Success! "); +// $this->output->writeln(''); +// } +// } +// +// /** +// * @param $package +// */ +// private function processGPM($package) +// { +// $version = isset($package->available) ? $package->available : $package->version; +// +// $this->output->writeln("Preparing to install " . $package->name . " [v" . $version . "]"); +// +// $this->output->write(" |- Downloading package... 0%"); +// $this->file = $this->downloadPackage($package); +// +// $this->output->write(" |- Checking destination... "); +// $checks = $this->checkDestination($package); +// +// if (!$checks) { +// $this->output->writeln(" '- Installation failed or aborted."); +// $this->output->writeln(''); +// } else { +// $this->output->write(" |- Installing package... "); +// $installation = $this->installPackage($package); +// if (!$installation) { +// $this->output->writeln(" '- Installation failed or aborted."); +// $this->output->writeln(''); +// } else { +// $this->output->writeln(" '- Success! "); +// $this->output->writeln(''); +// } +// } +// } /** * @param $package From 9bce9ce026d994c09bd85b0a5c2c9668a91e5d0f Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 28 Apr 2015 11:31:28 -0600 Subject: [PATCH 29/64] removed unused 'use' statements --- system/src/Grav/Common/Grav.php | 1 - system/src/Grav/Console/Cli/SandboxCommand.php | 1 - 2 files changed, 2 deletions(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 42085cd29..3720170cf 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -1,7 +1,6 @@ Date: Tue, 28 Apr 2015 23:35:58 +0200 Subject: [PATCH 30/64] ignore all .git folders --- system/src/Grav/Common/Backup/ZipBackup.php | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/system/src/Grav/Common/Backup/ZipBackup.php b/system/src/Grav/Common/Backup/ZipBackup.php index 2951cf9bf..d275d21eb 100644 --- a/system/src/Grav/Common/Backup/ZipBackup.php +++ b/system/src/Grav/Common/Backup/ZipBackup.php @@ -14,14 +14,17 @@ class ZipBackup { use GravTrait; - protected static $ignore = [ - '.git', + protected static $ignorePaths = [ 'backup', 'cache', 'images', 'logs' ]; + protected static $ignoreFolders = [ + '.git' + ]; + public static function backup($destination = null, callable $messager = null) { if (!$destination) { @@ -94,7 +97,7 @@ class ZipBackup // Remove prefix from file path before add to zip. $localPath = substr($filePath, $exclusiveLength); - if (in_array($localPath, static::$ignore)) { + if (in_array($f, static::$ignoreFolders) || in_array($localPath, static::$ignorePaths)) { continue; } From 8404ba7a09ca1004b9c66613b1cd104b5894c55e Mon Sep 17 00:00:00 2001 From: Gert Date: Wed, 29 Apr 2015 01:07:24 +0200 Subject: [PATCH 31/64] gzip --- system/src/Grav/Common/Grav.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 33e5a2a28..7ba3ad4cf 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -167,12 +167,6 @@ class Grav extends Container public function process() { - // 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']; @@ -185,6 +179,12 @@ class Grav extends Container $this['config']->debug(); $debugger->stopTimer('_config'); + // Use output buffering to prevent headers from being sent too early. + ob_start(); + if ($this['config']->get('system.cache.gzip')) { + ob_start('ob_gzhandler'); + } + // Initialize the timezone if ($this['config']->get('system.timezone')) { date_default_timezone_set($this['config']->get('system.timezone')); From 91a963f58044c819e92e56f84347fe2c4dc56b5a Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 28 Apr 2015 17:21:30 -0600 Subject: [PATCH 32/64] tweaks --- system/src/Grav/Common/Grav.php | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 7ba3ad4cf..19d48f396 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -349,26 +349,29 @@ class Grav extends Container public function shutdown() { if ($this['config']->get('system.debugger.shutdown.close_connection')) { - + //stop user abort if (function_exists('ignore_user_abort')) { @ignore_user_abort(true); } + // close the session if (isset($this['session'])) { $this['session']->close(); } + // flush buffer if gzip buffer was started if ($this['config']->get('system.cache.gzip')) { ob_end_flush(); // gzhandler buffer } + // get lengh and close the connection header('Content-Length: ' . ob_get_length()); header("Connection: close\r\n"); - ob_end_flush(); // regular buffer - @ob_flush(); - flush(); + // flush the regular buffer + ob_end_flush(); + // fix for fastcgi close connection issue if (function_exists('fastcgi_finish_request')) { @fastcgi_finish_request(); } From b65280f3c92d65a52a3397248ed52fd3c51e9b0a Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 28 Apr 2015 17:34:59 -0600 Subject: [PATCH 33/64] added other close bits back for gzip close connection --- system/src/Grav/Common/Grav.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 19d48f396..09a207fb9 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -366,10 +366,12 @@ class Grav extends Container // get lengh and close the connection header('Content-Length: ' . ob_get_length()); - header("Connection: close\r\n"); + header("Connection: close"); // flush the regular buffer ob_end_flush(); + @ob_flush(); + flush(); // fix for fastcgi close connection issue if (function_exists('fastcgi_finish_request')) { From ecc12be5310485e3606633fdcd302ff94b08a80b Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 30 Apr 2015 16:54:23 -0600 Subject: [PATCH 34/64] restored gpm install functions --- .../src/Grav/Console/Gpm/InstallCommand.php | 114 +++++++++--------- 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index f9b6b9a6f..6e8e40bbe 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -352,63 +352,63 @@ class InstallCommand extends Command $this->output->writeln(" '- Installation failed or aborted."); } -// /** -// * @param $package -// */ -// private function processGit($package) -// { -// $matches = $this->getGitRegexMatches($package); -// -// $this->output->writeln("Preparing to Git clone " . $package->name . " from " . $matches[0]); -// -// $this->output->write(" |- Checking destination... "); -// $checks = $this->checkDestination($package); -// -// if (!$checks) { -// $this->output->writeln(" '- Installation failed or aborted."); -// $this->output->writeln(''); -// } else { -// $cmd = 'cd ' . $this->destination . ' && git clone ' . $matches[0] . ' ' . $package->install_path; -// exec($cmd); -// -// // extra white spaces to clear out the buffer properly -// $this->output->writeln(" |- Cloning package... ok "); -// -// $this->output->writeln(" '- Success! "); -// $this->output->writeln(''); -// } -// } -// -// /** -// * @param $package -// */ -// private function processGPM($package) -// { -// $version = isset($package->available) ? $package->available : $package->version; -// -// $this->output->writeln("Preparing to install " . $package->name . " [v" . $version . "]"); -// -// $this->output->write(" |- Downloading package... 0%"); -// $this->file = $this->downloadPackage($package); -// -// $this->output->write(" |- Checking destination... "); -// $checks = $this->checkDestination($package); -// -// if (!$checks) { -// $this->output->writeln(" '- Installation failed or aborted."); -// $this->output->writeln(''); -// } else { -// $this->output->write(" |- Installing package... "); -// $installation = $this->installPackage($package); -// if (!$installation) { -// $this->output->writeln(" '- Installation failed or aborted."); -// $this->output->writeln(''); -// } else { -// $this->output->writeln(" '- Success! "); -// $this->output->writeln(''); -// } -// } -// } + /** + * @param $package + */ + private function processGit($package) + { + $matches = $this->getGitRegexMatches($package); + + $this->output->writeln("Preparing to Git clone " . $package->name . " from " . $matches[0]); + + $this->output->write(" |- Checking destination... "); + $checks = $this->checkDestination($package); + + if (!$checks) { + $this->output->writeln(" '- Installation failed or aborted."); + $this->output->writeln(''); + } else { + $cmd = 'cd ' . $this->destination . ' && git clone ' . $matches[0] . ' ' . $package->install_path; + exec($cmd); + + // extra white spaces to clear out the buffer properly + $this->output->writeln(" |- Cloning package... ok "); + + $this->output->writeln(" '- Success! "); + $this->output->writeln(''); + } + } + + /** + * @param $package + */ + private function processGPM($package) + { + $version = isset($package->available) ? $package->available : $package->version; + + $this->output->writeln("Preparing to install " . $package->name . " [v" . $version . "]"); + + $this->output->write(" |- Downloading package... 0%"); + $this->file = $this->downloadPackage($package); + + $this->output->write(" |- Checking destination... "); + $checks = $this->checkDestination($package); + + if (!$checks) { + $this->output->writeln(" '- Installation failed or aborted."); + $this->output->writeln(''); + } else { + $this->output->write(" |- Installing package... "); + $installation = $this->installPackage($package); + if (!$installation) { + $this->output->writeln(" '- Installation failed or aborted."); + $this->output->writeln(''); + } else { + $this->output->writeln(" '- Success! "); + $this->output->writeln(''); + } + } + } /** * @param $package From 4305bbabd5f22501fb523bfa1f56e1fdaf53de44 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 30 Apr 2015 18:05:30 -0600 Subject: [PATCH 35/64] fix for theme name same as base_url and asset pipeline --- 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 3b232f457..a2a741239 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -825,7 +825,7 @@ class Assets } else { // Fix to remove relative dir if grav is in one if (($this->base_url != '/') && (strpos($this->base_url, $link) == 0)) { - $relative_path = str_replace($this->base_url, '/', $link); + $relative_path = ltrim(preg_replace($this->base_url, '/', $link, 1), '/'); } $relative_dir = dirname($relative_path); From 750dfb60dce26dac570efb3d7460f1905444dba4 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 30 Apr 2015 22:51:39 -0600 Subject: [PATCH 36/64] Fix to properly normalize the font rewrite path --- system/src/Grav/Common/Assets.php | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index a2a741239..2d44912a8 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -881,18 +881,7 @@ class Assets return $matches[0]; } - $newpath = array(); - $paths = explode('/', $old_url); - - foreach ($paths as $path) { - if ($path == '..') { - $relative_path = dirname($relative_path); - } else { - $newpath[] = $path; - } - } - - $new_url = rtrim($this->base_url, '/') . $relative_path . '/' . implode('/', $newpath); + $new_url = $this->base_url . ltrim(Utils::normalizePath($relative_path . '/' . $old_url), '/'); return str_replace($old_url, $new_url, $matches[0]); }, From 41c00d7fbeb20b9f5a2a9e52b44056722343ba67 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 1 May 2015 06:23:31 -0600 Subject: [PATCH 37/64] fix for absolute url's below this page --- system/src/Grav/Common/Markdown/ParsedownGravTrait.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php index 0f1358216..0d629be8a 100644 --- a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php +++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php @@ -232,13 +232,8 @@ trait ParsedownGravTrait $normalized_path = Utils::normalizePath($this->pages_dir . $markdown_url); $normalized_url = Utils::normalizePath($this->base_url . $markdown_url); } else { - // contains path, so need to normalize it - if (Utils::contains($markdown_url, '/')) { - $normalized_path = Utils::normalizePath($this->page->path() . '/' . $markdown_url); - } else { - $normalized_path = false; - } $normalized_url = $this->base_url . Utils::normalizePath($this->page->route() . '/' . $markdown_url); + $normalized_path = Utils::normalizePath($this->page->path() . '/' . $markdown_url); } // if this file exits, get the page and work with that From c68c39df27773173fc7ef884fee8094e7433df68 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 1 May 2015 06:23:49 -0600 Subject: [PATCH 38/64] fix for .. page references --- .../Common/Markdown/ParsedownGravTrait.php | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php index 0d629be8a..1d7b581dd 100644 --- a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php +++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php @@ -246,16 +246,23 @@ trait ParsedownGravTrait $page_path = $path_info['dirname']; $filename = ''; - // save the filename if a file is part of the path - $filename_regex = "/([\w\d-_]+\.([a-zA-Z]{2,4}))$/"; - if (preg_match($filename_regex, $full_path, $matches)) { - if ($matches[2] != 'md') { - $filename = '/' . $matches[1]; - } - } else { + + if ($markdown_url == '..') { $page_path = $full_path; + } else { + // save the filename if a file is part of the path + $filename_regex = "/([\w\d-_]+\.([a-zA-Z]{2,4}))$/"; + if (preg_match($filename_regex, $full_path, $matches)) { + if ($matches[2] != 'md') { + $filename = '/' . $matches[1]; + } + } else { + $page_path = $full_path; + } } + + // get page instances and try to find one that fits $instances = $this->pages->instances(); if (isset($instances[$page_path])) { From 0563b2b6e58e231f470ca874d88945b4f4258885 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 2 May 2015 11:31:10 -0600 Subject: [PATCH 39/64] fixed missing method name --- system/src/Grav/Common/Plugins.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index b6264e9d9..77a2afa2e 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -42,7 +42,7 @@ class Plugins extends Iterator } $locator = self::getGrav()['locator']; - $filePath = $locator('plugins://' . $plugin . DS . $plugin . PLUGIN_EXT); + $filePath = $locator->findResource('plugins://' . $plugin . DS . $plugin . PLUGIN_EXT); if (!is_file($filePath)) { self::getGrav()['log']->addWarning(sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $plugin)); continue; From f12ef84a984b2d688cd45bad93de63974ae98975 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 2 May 2015 14:21:13 -0600 Subject: [PATCH 40/64] Added a function to parseLinks - used by YouTube plugin as testbed --- system/src/Grav/Common/Plugin.php | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/system/src/Grav/Common/Plugin.php b/system/src/Grav/Common/Plugin.php index 4197dd192..8643a89c0 100644 --- a/system/src/Grav/Common/Plugin.php +++ b/system/src/Grav/Common/Plugin.php @@ -114,6 +114,25 @@ class Plugin implements EventSubscriberInterface } } + /** + * This function will search a string for markdown links in a specific format. The link value can be + * optionally compared against via the $internal_regex and operated on by the callback $function + * provided. + * + * format: [plugin:myplugin_name](function_data) + * + * @param $content The string to perform operations upon + * @param $function The anonymous callback function + * @param string $internal_regex Optional internal regex to extra data from + * + * @return string + */ + protected function parseLinks($content, $function, $internal_regex = '(.*)') + { + $regex = '/\[plugin:(?:'.$this->name.')\]\('.$internal_regex.'\)/i'; + return preg_replace_callback($regex, $function, $content); + } + /** * Merge global and page configurations. * From 2e680cd35a240ab02318a22e7709bb292d115669 Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 14:56:34 +0200 Subject: [PATCH 41/64] email validate --- system/blueprints/config/site.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/system/blueprints/config/site.yaml b/system/blueprints/config/site.yaml index 9ec49f43d..604be106d 100644 --- a/system/blueprints/config/site.yaml +++ b/system/blueprints/config/site.yaml @@ -24,6 +24,8 @@ form: type: text size: large label: Default Email + validate: + type: email taxonomies: type: text From 08c4fd02d28cba0b5a110f021e16c305b9490cda Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 15:13:29 +0200 Subject: [PATCH 42/64] fix markdown extra blueprint --- system/blueprints/config/system.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 2a3f0119f..3c49b562f 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -27,7 +27,7 @@ form: label: Default Theme help: "Set the theme (defaults to 'default')" - pages.markdown_extra: + pages.markdown.extra: type: toggle label: Markdown Extra highlight: 1 From ce8513d3ff4b948f9ecb1dcf2147ffdbd8bf01bd Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 15:18:31 +0200 Subject: [PATCH 43/64] timezon and param_sep blueprints --- system/blueprints/config/system.yaml | 23 +++++++++++++++++++++++ system/src/Grav/Common/Utils.php | 28 ++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 3c49b562f..7b7bd3d8c 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -362,3 +362,26 @@ form: 0: No validate: type: bool + system: + type: section + title: System + underline: true + + fields: + timezone: + type: select + label: Timezone + classes: fancy + @data-options: '\Grav\Common\Utils::timezones' + default: '' + options: + '': '- None -' + + param_sep: + type: select + label: Parameter separator + classes: fancy + default: '' + options: + ':': ': (default)' + ';': '; (use this for apache on Windows)' diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index 97e4d6b52..ac1a2dcec 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -348,4 +348,32 @@ abstract class Utils } return $root . implode('/', $ret); } + + public static function timezones() + { + $timezones = \DateTimeZone::listIdentifiers(\DateTimeZone::ALL); + $offsets = []; + $testDate = new \DateTime; + + foreach ($timezones as $zone) { + $tz = new \DateTimeZone($zone); + $offsets[$zone] = $tz->getOffset($testDate); + } + + asort($offsets); + + $timezone_list = array(); + foreach( $offsets as $timezone => $offset ) + { + $offset_prefix = $offset < 0 ? '-' : '+'; + $offset_formatted = gmdate( 'H:i', abs($offset) ); + + $pretty_offset = "UTC${offset_prefix}${offset_formatted}"; + + $timezone_list[$timezone] = "(${pretty_offset}) $timezone"; + } + + return $timezone_list; + + } } From 2c51dd5fe17f6de25f029e15166ac009b83ee16b Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 15:18:55 +0200 Subject: [PATCH 44/64] default ordering fix --- system/config/system.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/config/system.yaml b/system/config/system.yaml index d6d84a7ff..98e183b1a 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -8,7 +8,7 @@ home: pages: theme: antimatter # Default theme (defaults to "antimatter" theme) order: - by: defaults # Order pages by "default", "alpha" or "date" + by: default # Order pages by "default", "alpha" or "date" dir: asc # Default ordering direction, "asc" or "desc" list: count: 20 # Default item count per page From 58bb5a699324bbe45e417d130dd1e876f67c947b Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 15:23:08 +0200 Subject: [PATCH 45/64] publish_dates blueprint --- system/blueprints/config/system.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 7b7bd3d8c..fb6bb90db 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -101,6 +101,16 @@ form: validate: type: number min: 1 + pages.publish_dates: + type: toggle + label: Date-based publishing + help: Automatically (un)publish posts based on their date + highlight: 1 + options: + 1: Yes + 0: No + validate: + type: bool From 4e07c294c552743e141ddca1f74d39e483cb6ea6 Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 15:29:46 +0200 Subject: [PATCH 46/64] gzip compression blueprint --- system/blueprints/config/system.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index fb6bb90db..28d9a255d 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -185,6 +185,16 @@ form: label: Cache Prefix placeholder: "Derived from base URL (override by entering random string)" + cache.gzip: + type: toggle + label: GZIP compression + highlight: 1 + options: + 1: Yes + 0: No + validate: + type: bool + twig: type: section title: Twig Templating From e01a116173cd887b46bf482ce404da9218fe65fa Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 15:36:17 +0200 Subject: [PATCH 47/64] asset timestamps blueprint --- system/blueprints/config/system.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 28d9a255d..81805ed5e 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -307,6 +307,16 @@ form: validate: type: bool + assets.enable_asset_timestamp: + type: toggle + label: Enable timestamps + highlight: 1 + options: + 1: Yes + 0: No + validate: + type: bool + debugger: type: section title: Debugger From 565a76c31764afcf8f3ff8becfc786ab47bb133c Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 15:37:07 +0200 Subject: [PATCH 48/64] error handler blueprints --- system/blueprints/config/system.yaml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 81805ed5e..f02848221 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -317,6 +317,32 @@ form: validate: type: bool + errors: + type: section + title: Error handler + underline: true + + fields: + errors.display: + type: toggle + label: Display errors + highlight: 1 + options: + 1: Yes + 0: No + validate: + type: bool + + errors.log: + type: toggle + label: Log errors + highlight: 1 + options: + 1: Yes + 0: No + validate: + type: bool + debugger: type: section title: Debugger @@ -392,6 +418,7 @@ form: 0: No validate: type: bool + system: type: section title: System From 845da953e1150d82537462206e87052d3ffef90f Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 15:39:33 +0200 Subject: [PATCH 49/64] timestamp blueprints under caching header --- system/blueprints/config/system.yaml | 30 ++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index f02848221..890613cc5 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -195,6 +195,26 @@ form: validate: type: bool + assets.enable_asset_timestamp: + type: toggle + label: Enable timestamps on assets + highlight: 1 + options: + 1: Yes + 0: No + validate: + type: bool + + media.enable_media_timestamp: + type: toggle + label: Enable timestamps on media + highlight: 1 + options: + 1: Yes + 0: No + validate: + type: bool + twig: type: section title: Twig Templating @@ -307,16 +327,6 @@ form: validate: type: bool - assets.enable_asset_timestamp: - type: toggle - label: Enable timestamps - highlight: 1 - options: - 1: Yes - 0: No - validate: - type: bool - errors: type: section title: Error handler From 4b56a05f57a8dc79d7bac263b2277866a3cb5a29 Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 15:44:25 +0200 Subject: [PATCH 50/64] media blueprints --- system/blueprints/config/system.yaml | 32 ++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 890613cc5..56712a4c8 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -429,6 +429,38 @@ form: validate: type: bool + media: + type: section + title: Media + underline: true + + fields: + images.default_image_quality: + type: text + label: Default image quality + classes: x-small + validate: + tpye: number + min: 1 + max: 100 + + images.debug: + type: toggle + label: Image debug watermark + highlight: 1 + options: + 1: Yes + 0: No + validate: + type: bool + + media.upload_limit: + type: text + label: File upload limit + classes: small + validate: + tpye: number + system: type: section title: System From 3ec855e28fc0f5671e64ffffbc3bec9cf8252630 Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 15:58:39 +0200 Subject: [PATCH 51/64] fix typo in type --- system/blueprints/config/system.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml index 56712a4c8..071a5c1b2 100644 --- a/system/blueprints/config/system.yaml +++ b/system/blueprints/config/system.yaml @@ -440,7 +440,7 @@ form: label: Default image quality classes: x-small validate: - tpye: number + type: number min: 1 max: 100 @@ -459,7 +459,7 @@ form: label: File upload limit classes: small validate: - tpye: number + type: number system: type: section From e62133233c7dc81a07bfed994657b55ed6f724ed Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 15:59:06 +0200 Subject: [PATCH 52/64] remove permission management from user settings --- system/blueprints/user/account.yaml | 45 ----------------------------- 1 file changed, 45 deletions(-) diff --git a/system/blueprints/user/account.yaml b/system/blueprints/user/account.yaml index 821d5d7bc..7ed36145a 100644 --- a/system/blueprints/user/account.yaml +++ b/system/blueprints/user/account.yaml @@ -28,8 +28,6 @@ form: validate: required: true - - fullname: type: text size: large @@ -41,46 +39,3 @@ form: type: text size: large label: Title - - admin: - type: section - title: Admin Access - - fields: - access.admin.super: - type: toggle - label: Super user - default: 0 - highlight: 1 - options: - 1: Yes - 0: No - validate: - type: bool - - access.admin.login: - type: toggle - label: Admin login - default: 0 - highlight: 1 - options: - 1: Yes - 0: No - validate: - type: bool - - site: - type: section - title: Site Access - - fields: - access.site.login: - type: toggle - label: Site login - default: 1 - highlight: 1 - options: - 1: Yes - 0: No - validate: - type: bool From 13e9e6f5e1e3d76a2e4c6b76893a611789d9ab32 Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 17:12:24 +0200 Subject: [PATCH 53/64] modular page cannot be added to root --- system/blueprints/pages/modular_raw.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/blueprints/pages/modular_raw.yaml b/system/blueprints/pages/modular_raw.yaml index 8e008ac60..f7877772f 100644 --- a/system/blueprints/pages/modular_raw.yaml +++ b/system/blueprints/pages/modular_raw.yaml @@ -61,7 +61,7 @@ form: @data-options: '\Grav\Common\Page\Pages::parents' @data-default: '\Grav\Plugin\admin::route' options: - '/': '- Root -' + '': '- Select -' validate: required: true From 9792c9a84edf2c610dc78ddc895e2d1c38b24113 Mon Sep 17 00:00:00 2001 From: Gert Date: Mon, 4 May 2015 17:42:53 +0200 Subject: [PATCH 54/64] re-add size property to media --- system/src/Grav/Common/Page/Media.php | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index 93c8ddb04..c766b0992 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -58,27 +58,31 @@ class Media extends Getters if ($type === 'alternative') { $media["{$basename}.{$ext}"][$type] = isset($media["{$basename}.{$ext}"][$type]) ? $media["{$basename}.{$ext}"][$type] : []; - $media["{$basename}.{$ext}"][$type][$extra] = $path; + $media["{$basename}.{$ext}"][$type][$extra] = [ 'file' => $path, 'size' => $info->getSize() ]; } else { - $media["{$basename}.{$ext}"][$type] = $path; + $media["{$basename}.{$ext}"][$type] = [ 'file' => $path, 'size' => $info->getSize() ]; } } foreach ($media as $name => $types) { // First prepare the alternatives in case there is no base medium if (!empty($types['alternative'])) { - foreach ($types['alternative'] as $ratio => &$file) { - $file = MediumFactory::fromFile($file); + foreach ($types['alternative'] as $ratio => &$alt) { + $alt['file'] = MediumFactory::fromFile($alt['file']); + $alt['file']->set('size', $alt['size']); } } // Create the base medium if (!empty($types['base'])) { - $medium = MediumFactory::fromFile($types['base']); + $medium = MediumFactory::fromFile($types['base']['file']); + $medium->set('size', $types['base']['size']); } else if (!empty($types['alternative'])) { $altMedium = reset($types['alternative']); $ratio = key($types['alternative']); + $altMedium = $altMedium['file']; + $medium = MediumFactory::scaledFromMedium($altMedium, $ratio, 1); } @@ -87,13 +91,13 @@ class Media extends Getters } if (!empty($types['meta'])) { - $medium->addMetaFile($types['meta']); + $medium->addMetaFile($types['meta']['file']); } if (!empty($types['thumb'])) { // We will not turn it into medium yet because user might never request the thumbnail // not wasting any resources on that, maybe we should do this for medium in general? - $medium->set('thumbnails.page', $types['thumb']); + $medium->set('thumbnails.page', $types['thumb']['file']); } // Build missing alternatives From 7f8e8f67a5539ec17ed1a4339e3b3a030da8d971 Mon Sep 17 00:00:00 2001 From: Gert Date: Tue, 5 May 2015 19:49:14 +0200 Subject: [PATCH 55/64] check if medium was created before setting size --- system/src/Grav/Common/Page/Media.php | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index c766b0992..05705711e 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -69,14 +69,19 @@ class Media extends Getters if (!empty($types['alternative'])) { foreach ($types['alternative'] as $ratio => &$alt) { $alt['file'] = MediumFactory::fromFile($alt['file']); - $alt['file']->set('size', $alt['size']); + + if (!$alt['file']) { + unset($types['alternative'][$ratio]); + } else { + $alt['file']->set('size', $alt['size']); + } } } // Create the base medium if (!empty($types['base'])) { $medium = MediumFactory::fromFile($types['base']['file']); - $medium->set('size', $types['base']['size']); + $medium && $medium->set('size', $types['base']['size']); } else if (!empty($types['alternative'])) { $altMedium = reset($types['alternative']); $ratio = key($types['alternative']); From 16c3a3690b2a00d566390df96606d38f08f1b46a Mon Sep 17 00:00:00 2001 From: Gert Date: Tue, 5 May 2015 20:33:47 +0200 Subject: [PATCH 56/64] ignore .DS_Store in media lookup --- system/src/Grav/Common/Page/Media.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index 05705711e..d73064618 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -47,7 +47,7 @@ class Media extends Getters /** @var \DirectoryIterator $info */ foreach ($iterator as $path => $info) { // Ignore folders and Markdown files. - if (!$info->isFile() || $info->getExtension() == 'md') { + if (!$info->isFile() || $info->getExtension() == 'md' || $info->getBasename() === '.DS_Store') { continue; } From b2a78d587c81884de6bc300c489a228b664cf302 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 5 May 2015 12:48:15 -0600 Subject: [PATCH 57/64] added check to see if on same page --- system/src/Grav/Common/Markdown/ParsedownGravTrait.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php index 1d7b581dd..c265bf599 100644 --- a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php +++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php @@ -236,6 +236,12 @@ trait ParsedownGravTrait $normalized_path = Utils::normalizePath($this->page->path() . '/' . $markdown_url); } + // special check to see if path checking is required. + $just_path = str_replace($normalized_url, '', $normalized_path); + if ($just_path == $this->page->path()) { + return $normalized_url; + } + // if this file exits, get the page and work with that if ($normalized_path) { $url_bits = parse_url($normalized_path); From 14767a3e11622348d87ecbe09a81bd0bbe358cde Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 7 May 2015 14:13:05 -0600 Subject: [PATCH 58/64] added twig filters for starts_with and ends_with --- system/src/Grav/Common/TwigExtension.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/TwigExtension.php b/system/src/Grav/Common/TwigExtension.php index cfec33ba7..c9d5f2289 100644 --- a/system/src/Grav/Common/TwigExtension.php +++ b/system/src/Grav/Common/TwigExtension.php @@ -52,7 +52,9 @@ class TwigExtension extends \Twig_Extension new \Twig_SimpleFilter('contains', [$this, 'containsFilter']), new \Twig_SimpleFilter('nicetime', [$this, 'nicetimeFilter']), new \Twig_SimpleFilter('absolute_url', [$this, 'absoluteUrlFilter']), - new \Twig_SimpleFilter('markdown', [$this, 'markdownFilter']) + new \Twig_SimpleFilter('markdown', [$this, 'markdownFilter']), + new \Twig_SimpleFilter('starts_with', [$this, 'startsWithFilter']), + new \Twig_SimpleFilter('ends_with', [$this, 'endsWithFilter']) ]; } @@ -347,6 +349,16 @@ class TwigExtension extends \Twig_Extension return $string; } + public function startsWithFilter($needle, $haystack) + { + return Utils::startsWith($needle, $haystack); + } + + public function endsWithFilter($needle, $haystack) + { + return Utils::endsWith($needle, $haystack); + } + /** * Repeat given string x times. * From 57c588521681c4f33979947ff096626c8c75287d Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 7 May 2015 16:01:11 -0600 Subject: [PATCH 59/64] don't cache twig template when you pass params --- system/src/Grav/Common/Twig.php | 6 ++++++ system/src/Grav/Common/Uri.php | 9 ++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Twig.php b/system/src/Grav/Common/Twig.php index e5a7fafbd..6a92f86a0 100644 --- a/system/src/Grav/Common/Twig.php +++ b/system/src/Grav/Common/Twig.php @@ -292,6 +292,12 @@ class Twig $twig_vars['content'] = $page->content(); $ext = '.' . ($format ? $format : 'html') . TWIG_EXT; + // determine if params are set, if so disable twig cache + $params = $this->grav['uri']->params(null, true); + if (!empty($params)) { + $this->twig->setCache(false); + } + // Get Twig template layout $template = $this->template($page->template() . $ext); diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index bacd14b38..c4297bc20 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -193,20 +193,27 @@ class Uri * Return all or a single query parameter as a URI compatible string. * * @param string $id Optional parameter name. + * @param boolean $array return the array format or not * @return null|string */ - public function params($id = null) + public function params($id = null, $array = false) { $config = Grav::instance()['config']; $params = null; if ($id === null) { + if ($array) { + return $this->params; + } $output = array(); foreach ($this->params as $key => $value) { $output[] = $key . $config->get('system.param_sep') . $value; $params = '/'.implode('/', $output); } } elseif (isset($this->params[$id])) { + if ($array) { + return $this->params[$id]; + } $params = "/{$id}". $config->get('system.param_sep') . $this->params[$id]; } From 718d443d5219ad32eb9a4de32eb2b88348311571 Mon Sep 17 00:00:00 2001 From: Gert Date: Sat, 9 May 2015 15:07:15 +0200 Subject: [PATCH 60/64] trim trailing slashes from path during page lookup [fixes #190] --- 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 09a207fb9..d62290114 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -101,7 +101,7 @@ class Grav extends Container /** @var Uri $uri */ $uri = $c['uri']; - $path = $uri->path(); + $path = rtrim($uri->path(), '/'); $page = $pages->dispatch($path); From cabec818e286240e3cb87c93abf7682bec036205 Mon Sep 17 00:00:00 2001 From: Gert Date: Sat, 9 May 2015 16:08:33 +0200 Subject: [PATCH 61/64] make sure lookup path does not become empty (root sites) --- system/src/Grav/Common/Grav.php | 1 + 1 file changed, 1 insertion(+) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index d62290114..710984aca 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -102,6 +102,7 @@ class Grav extends Container $uri = $c['uri']; $path = rtrim($uri->path(), '/'); + $path = $path ?: '/'; $page = $pages->dispatch($path); From cea130700d6c0dfe8749cdc5b502e1411c4baeb0 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 9 May 2015 12:36:22 -0600 Subject: [PATCH 62/64] composer.par updated to latest --- bin/composer.phar | Bin 1098591 -> 1103856 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/composer.phar b/bin/composer.phar index f3d065ad9b311e025c02b25fde40e2ded287b53d..a08ea4eba3ab936bd19cef6df49d344601a2bce0 100755 GIT binary patch delta 21967 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 From e9ebe3b533fc101e00aa71a75e300e62acd84512 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 9 May 2015 12:53:29 -0600 Subject: [PATCH 63/64] updated changelog --- CHANGELOG.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ce9860c7..7e914ad1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,32 @@ +# v0.9.27 +## 05/09/2015 + +1. [](#new) + * Added new composer CLI command + * Added page-level summary header overrides + * Added `size` back for Media objects + * Refactored Backup command in preparation for admin plugin + * Added a new `parseLinks` method to Plugins class + * Added `starts_with` and `ends_with` Twig filters +2. [](#improved) + * Opitmized install of vendor libraries for speed improvement + * Improved configuration handling in preparation for admin plugin + * Cache optimization: Don't cache Twig templates when you pass dynamic params + * Moved `Utils::rcopy` to `Folder::rcopy` + * Improved `Folder::doDelete` + * Added check for required Curl in GPM + * Updated included composer.phar to latest version + * Various blueprint fixes for admin plugin + * Various PSR and code cleanup tasks +3. [](#bugfix) + * Fix issue with Gzip not working with `onShutDown()` event + * Fix for URLs with trailing slashes + * Handle condition where certain errors resulted in blank page + * Fix for issue with theme name equal to base_url and asset pipeline + * Fix to properly nomralize font rewrite path + * Fix for absolute URLs below the current page + * Fix for `..` page references + # v0.9.26 ## 04/24/2015 From e026ba32f49234d3e4d556372b7b32fd7accefbd Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 9 May 2015 13:14:23 -0600 Subject: [PATCH 64/64] version update --- system/defines.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/defines.php b/system/defines.php index 2055be734..71aa234fd 100644 --- a/system/defines.php +++ b/system/defines.php @@ -2,7 +2,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '0.9.26'); +define('GRAV_VERSION', '0.9.27'); define('DS', '/'); // Directories and Paths