diff --git a/CHANGELOG.md b/CHANGELOG.md index c394555e63..6ef65c7a79 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ +# v1.3.0-rc.2 +## 05/17/2017 + +1. [](#new) + * Added new `media` and `vardump` Twig functions +1. [](#improved) + * Put in various checks to ensure Exif is available before trying to use it + * Add timestamp to configuration settings [#1445](https://github.com/getgrav/grav/pull/1445) +1. [](#bugfix) + * Fix an issue saving YAML textarea fields in expert mode [#1480](https://github.com/getgrav/grav/pull/1480) + * Moved `onOutputRendered()` back into Grav core + # v1.3.0-rc.1 -## 15/16/2017 +## 05/16/2017 1. [](#new) * Added support for a single array field in the forms diff --git a/system/defines.php b/system/defines.php index a65cfd0267..bca0335536 100644 --- a/system/defines.php +++ b/system/defines.php @@ -8,7 +8,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '1.3.0-rc.1'); +define('GRAV_VERSION', '1.3.0-rc.2'); define('GRAV_TESTING', true); define('DS', '/'); diff --git a/system/src/Grav/Common/Config/CompiledBase.php b/system/src/Grav/Common/Config/CompiledBase.php index f1e71f0442..b4e2abb29d 100644 --- a/system/src/Grav/Common/Config/CompiledBase.php +++ b/system/src/Grav/Common/Config/CompiledBase.php @@ -27,6 +27,11 @@ abstract class CompiledBase */ public $checksum; + /** + * @var string Timestamp of compiled configuration + */ + public $timestamp; + /** * @var string Cache folder to be used. */ @@ -59,9 +64,10 @@ public function __construct($cacheFolder, array $files, $path) throw new \BadMethodCallException('Cache folder not defined.'); } + $this->path = $path ? rtrim($path, '\\/') . '/' : ''; $this->cacheFolder = $cacheFolder; $this->files = $files; - $this->path = $path ? rtrim($path, '\\/') . '/' : ''; + $this->timestamp = 0; } /** @@ -84,6 +90,16 @@ public function name($name = null) */ public function modified() {} + /** + * Get timestamp of compiled configuration + * + * @return int Timestamp of compiled configuration + */ + public function timestamp() + { + return $this->timestamp ?: time(); + } + /** * Load the configuration. * @@ -196,6 +212,7 @@ protected function loadCompiledFile($filename) } $this->createObject($cache['data']); + $this->timestamp = isset($cache['timestamp']) ? $cache['timestamp'] : 0; $this->finalizeObject(); diff --git a/system/src/Grav/Common/Config/CompiledConfig.php b/system/src/Grav/Common/Config/CompiledConfig.php index 1e064d90c8..05d3ed9b1e 100644 --- a/system/src/Grav/Common/Config/CompiledConfig.php +++ b/system/src/Grav/Common/Config/CompiledConfig.php @@ -77,6 +77,7 @@ protected function createObject(array $data = []) protected function finalizeObject() { $this->object->checksum($this->checksum()); + $this->object->timestamp($this->timestamp()); } /** diff --git a/system/src/Grav/Common/Config/CompiledLanguages.php b/system/src/Grav/Common/Config/CompiledLanguages.php index b6fbe37b90..94d2e3a4ee 100644 --- a/system/src/Grav/Common/Config/CompiledLanguages.php +++ b/system/src/Grav/Common/Config/CompiledLanguages.php @@ -38,6 +38,7 @@ protected function createObject(array $data = []) protected function finalizeObject() { $this->object->checksum($this->checksum()); + $this->object->timestamp($this->timestamp()); } diff --git a/system/src/Grav/Common/Config/Config.php b/system/src/Grav/Common/Config/Config.php index faa596831a..c8cf5aec36 100644 --- a/system/src/Grav/Common/Config/Config.php +++ b/system/src/Grav/Common/Config/Config.php @@ -17,6 +17,7 @@ class Config extends Data { protected $checksum; protected $modified = false; + protected $timestamp = 0; public function key() { @@ -41,6 +42,15 @@ public function modified($modified = null) return $this->modified; } + public function timestamp($timestamp = null) + { + if ($timestamp !== null) { + $this->timestamp = $timestamp; + } + + return $this->timestamp; + } + public function reload() { $grav = Grav::instance(); diff --git a/system/src/Grav/Common/Config/Languages.php b/system/src/Grav/Common/Config/Languages.php index 50073df26e..997b842c8e 100644 --- a/system/src/Grav/Common/Config/Languages.php +++ b/system/src/Grav/Common/Config/Languages.php @@ -30,6 +30,15 @@ public function modified($modified = null) return $this->modified; } + public function timestamp($timestamp = null) + { + if ($timestamp !== null) { + $this->timestamp = $timestamp; + } + + return $this->timestamp; + } + public function reformat() { if (isset($this->items['plugins'])) { diff --git a/system/src/Grav/Common/Data/Validation.php b/system/src/Grav/Common/Data/Validation.php index b9ba8f90e9..6f1bbe1c77 100644 --- a/system/src/Grav/Common/Data/Validation.php +++ b/system/src/Grav/Common/Data/Validation.php @@ -38,6 +38,11 @@ public static function validate($value, array $field) $field['type'] = 'text'; } + // If this is a YAML field, stop validation + if (isset($field['yaml']) && $field['yaml'] === true) { + return $messages; + } + // Get language class. $language = Grav::instance()['language']; @@ -98,13 +103,7 @@ public static function filter($value, array $field) // If this is a YAML field, simply parse it and return the value. if (isset($field['yaml']) && $field['yaml'] === true) { - try { - $yaml = new Parser(); - - return $yaml->parse($value); - } catch (ParseException $e) { - throw new \RuntimeException($e->getMessage()); - } + return $value; } // Validate type with fallback type text. diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index a260ec95f7..eb152277e2 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -137,6 +137,8 @@ public function process() $debugger = $this['debugger']; $debugger->render(); + $this->fireEvent('onOutputRendered'); + register_shutdown_function([$this, 'shutdown']); } diff --git a/system/src/Grav/Common/Helpers/Exif.php b/system/src/Grav/Common/Helpers/Exif.php index 9e7a423ae5..e33cc7366a 100644 --- a/system/src/Grav/Common/Helpers/Exif.php +++ b/system/src/Grav/Common/Helpers/Exif.php @@ -16,12 +16,21 @@ class Exif public function __construct() { - if (function_exists('exif_read_data') && class_exists('\PHPExif\Reader\Reader')) { - $this->reader = \PHPExif\Reader\Reader::factory(\PHPExif\Reader\Reader::TYPE_NATIVE); - } else { - if (Grav::instance()['config']->get('system.media.auto_metadata_exif')) { + if (Grav::instance()['config']->get('system.media.auto_metadata_exif')) { + if (function_exists('exif_read_data') && class_exists('\PHPExif\Reader\Reader')) { + $this->reader = \PHPExif\Reader\Reader::factory(\PHPExif\Reader\Reader::TYPE_NATIVE); + } else { throw new \Exception('Please enable the Exif extension for PHP or disable Exif support in Grav system configuration'); } } } + + public function getReader() + { + if ($this->reader) { + return $this->reader; + } + + return false; + } } diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index 3c5256a49e..9d8a40cf68 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -64,7 +64,7 @@ public function offsetGet($offset) protected function init() { $config = Grav::instance()['config']; - $exif = Grav::instance()['exif']; + $exif_reader = isset(Grav::instance()['exif']) ? Grav::instance()['exif']->getReader() : false; // Handle special cases where page doesn't exist in filesystem. if (!is_dir($this->path)) { @@ -124,9 +124,9 @@ protected function init() } // Read/store Exif metadata as required - if (!empty($types['base']) && $medium->get('mime') === 'image/jpeg' && empty($types['meta']) && $config->get('system.media.auto_metadata_exif')) { + if (!empty($types['base']) && $medium->get('mime') === 'image/jpeg' && empty($types['meta']) && $config->get('system.media.auto_metadata_exif') && $exif_reader) { $file_path = $types['base']['file']; - $meta = $exif->reader->read($file_path); + $meta = $exif_reader->read($file_path); if ($meta) { $meta_path = $file_path . '.meta.yaml'; diff --git a/system/src/Grav/Common/Processors/RenderProcessor.php b/system/src/Grav/Common/Processors/RenderProcessor.php index 623be38e68..a55b42847a 100644 --- a/system/src/Grav/Common/Processors/RenderProcessor.php +++ b/system/src/Grav/Common/Processors/RenderProcessor.php @@ -29,8 +29,9 @@ public function process() $container->header(); echo $output; - } - $container->fireEvent('onOutputRendered'); + // remove any output + $container->output = ''; + } } } diff --git a/system/src/Grav/Common/Twig/TwigExtension.php b/system/src/Grav/Common/Twig/TwigExtension.php index 71407c8b18..fc60bbdeba 100644 --- a/system/src/Grav/Common/Twig/TwigExtension.php +++ b/system/src/Grav/Common/Twig/TwigExtension.php @@ -9,6 +9,7 @@ namespace Grav\Common\Twig; use Grav\Common\Grav; +use Grav\Common\Page\Media; use Grav\Common\Utils; use Grav\Common\Markdown\Parsedown; use Grav\Common\Markdown\ParsedownExtra; @@ -109,6 +110,7 @@ public function getFunctions() new \Twig_simpleFunction('authorize', [$this, 'authorize']), new \Twig_SimpleFunction('debug', [$this, 'dump'], ['needs_context' => true, 'needs_environment' => true]), new \Twig_SimpleFunction('dump', [$this, 'dump'], ['needs_context' => true, 'needs_environment' => true]), + new \Twig_SimpleFunction('vardump', [$this, 'vardumpFunc']), new \Twig_SimpleFunction('evaluate', [$this, 'evaluateStringFunc'], ['needs_context' => true, 'needs_environment' => true]), new \Twig_SimpleFunction('evaluate_twig', [$this, 'evaluateTwigFunc'], ['needs_context' => true, 'needs_environment' => true]), new \Twig_SimpleFunction('gist', [$this, 'gistFunc']), @@ -126,6 +128,8 @@ public function getFunctions() new \Twig_SimpleFunction('range', [$this, 'rangeFunc']), new \Twig_SimpleFunction('isajaxrequest', [$this, 'isAjaxFunc']), new \Twig_SimpleFunction('exif', [$this, 'exifFunc']), + new \Twig_SimpleFunction('media', [$this, 'mediaFunc']), + ]; } @@ -967,17 +971,60 @@ public function isAjaxFunc() */ public function exifFunc($image, $raw = false) { - if (file_exists($image)) { + if (isset($this->grav['exif'])) { - $exif_data = $this->grav['exif']->reader->read($image); + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; - if ($exif_data) { - if ($raw) { - return $exif_data->getRawData(); - } else { - return $exif_data->getData(); + if ($locator->isStream($image)) { + $image = $locator->findResource($image); + } + + $exif_reader = $this->grav['exif']->getReader(); + + if (file_exists($image) && $this->config->get('system.media.auto_metadata_exif') && $exif_reader) { + + $exif_data = $exif_reader->read($image); + + if ($exif_data) { + if ($raw) { + return $exif_data->getRawData(); + } else { + return $exif_data->getData(); + } } } } } + + /** + * Process a folder as Media and return a media object + * + * @param $media_dir + * @return Media + */ + public function mediaFunc($media_dir) + { + /** @var UniformResourceLocator $locator */ + $locator = $this->grav['locator']; + + if ($locator->isStream($media_dir)) { + $media_dir = $locator->findResource($media_dir); + } + + if (file_exists($media_dir)) { + return new Media($media_dir); + } + + } + + /** + * Dump a variable to the browser + * + * @param $var + */ + public function vardumpFunc($var) + { + var_dump($var); + } }