Merge branch 'develop' of https://github.com/getgrav/grav into 2.0

# Conflicts:
#	composer.lock
This commit is contained in:
Matias Griese
2017-05-16 10:54:16 +03:00
11 changed files with 200 additions and 25 deletions

View File

@@ -12,6 +12,9 @@
## mm/dd/2017
1. [](#new)
* Added support for a single array field in the forms
* Added EXIF support with automatic generation of Page Media metafiles
* Added Twig function to get EXIF data on any image file
* Added `Pages::baseUrl()`, `Pages::homeUrl()` and `Pages::url()` functions
* Added `base32_encode`, `base32_decode`, `base64_encode`, `base64_decode` Twig filters
* Added `Debugger::getCaller()` to figure out where the method was called from
@@ -23,6 +26,7 @@
* Groups selection pre-filled in user form
* Improve error handling in `Folder::move()`
* Added extra parameter for `Twig::processSite()` to include custom context
* Updated RocketTheme Toolbox vendor library
1. [](#bugfix)
* Fix to force route/redirect matching from the start of the route by default [#1446](https://github.com/getgrav/grav/issues/1446)
* Edit check for valid slug [#1459](https://github.com/getgrav/grav/issues/1459)

View File

@@ -31,7 +31,8 @@
"ext-curl": "*",
"ext-zip": "*",
"league/climate": "^3.2",
"antoligy/dom-string-iterators": "^1.0"
"antoligy/dom-string-iterators": "^1.0",
"miljar/php-exif": "^0.6.3"
},
"require-dev": {
"codeception/codeception": "^2.1",

82
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"content-hash": "f9e602a9833bae4ef67c9545e72fcfbc",
"content-hash": "b418b22b918df3b62e5e372de49f13c4",
"packages": [
{
"name": "antoligy/dom-string-iterators",
@@ -697,6 +697,61 @@
],
"time": "2017-01-05T08:46:19+00:00"
},
{
"name": "miljar/php-exif",
"version": "v0.6.3",
"source": {
"type": "git",
"url": "https://github.com/PHPExif/php-exif.git",
"reference": "e43cc30608824d7f3466653b52bbbb71874b5b02"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/PHPExif/php-exif/zipball/e43cc30608824d7f3466653b52bbbb71874b5b02",
"reference": "e43cc30608824d7f3466653b52bbbb71874b5b02",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"require-dev": {
"phpmd/phpmd": "~2.2",
"phpunit/phpunit": "3.7.*",
"satooshi/php-coveralls": "~0.6",
"sebastian/phpcpd": "1.4.*@stable",
"squizlabs/php_codesniffer": "1.4.*@stable"
},
"suggest": {
"ext-exif": "Use exif PHP extension as adapter",
"lib-exiftool": "Use perl lib exiftool as adapter"
},
"type": "library",
"autoload": {
"psr-0": {
"PHPExif": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Tom Van Herreweghe",
"homepage": "http://theanalogguy.be",
"role": "Developer"
}
],
"description": "Object-Oriented EXIF parsing",
"keywords": [
"IPTC",
"exif",
"exiftool",
"jpeg",
"tiff"
],
"time": "2017-02-06T14:40:26+00:00"
},
{
"name": "monolog/monolog",
"version": "1.22.1",
@@ -918,16 +973,16 @@
},
{
"name": "rockettheme/toolbox",
"version": "1.3.3",
"version": "1.3.4",
"source": {
"type": "git",
"url": "https://github.com/rockettheme/toolbox.git",
"reference": "8eec637fdd60e546fb98db8b0409acc897baaccf"
"reference": "416b854c0c3743a1a69edfa685b7bf7514bc1f93"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/rockettheme/toolbox/zipball/8eec637fdd60e546fb98db8b0409acc897baaccf",
"reference": "8eec637fdd60e546fb98db8b0409acc897baaccf",
"url": "https://api.github.com/repos/rockettheme/toolbox/zipball/416b854c0c3743a1a69edfa685b7bf7514bc1f93",
"reference": "416b854c0c3743a1a69edfa685b7bf7514bc1f93",
"shasum": ""
},
"require": {
@@ -962,7 +1017,7 @@
"php",
"rockettheme"
],
"time": "2016-10-06T18:02:45+00:00"
"time": "2017-05-15T17:46:25+00:00"
},
{
"name": "seld/cli-prompt",
@@ -1550,16 +1605,16 @@
},
{
"name": "codeception/codeception",
"version": "2.2.10",
"version": "2.2.11",
"source": {
"type": "git",
"url": "https://github.com/Codeception/Codeception.git",
"reference": "c32a3f92834db08ceedb4666ea2265c3aa43396e"
"reference": "a8681b416921ae282ccca2c485d75a3ed6756080"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/c32a3f92834db08ceedb4666ea2265c3aa43396e",
"reference": "c32a3f92834db08ceedb4666ea2265c3aa43396e",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/a8681b416921ae282ccca2c485d75a3ed6756080",
"reference": "a8681b416921ae282ccca2c485d75a3ed6756080",
"shasum": ""
},
"require": {
@@ -1570,9 +1625,10 @@
"guzzlehttp/guzzle": ">=4.1.4 <7.0",
"guzzlehttp/psr7": "~1.0",
"php": ">=5.4.0 <8.0",
"phpunit/php-code-coverage": ">=2.2.4 <5.0",
"phpunit/php-code-coverage": ">=2.2.4 <6.0",
"phpunit/phpunit": ">4.8.20 <6.0",
"sebastian/comparator": "~1.1",
"phpunit/phpunit-mock-objects": ">2.3 <5.0",
"sebastian/comparator": ">1.1 <3.0",
"sebastian/diff": "^1.4",
"stecman/symfony-console-completion": "^0.7.0",
"symfony/browser-kit": ">=2.7 <4.0",
@@ -1639,7 +1695,7 @@
"functional testing",
"unit testing"
],
"time": "2017-03-25T03:19:52+00:00"
"time": "2017-05-11T21:07:05+00:00"
},
{
"name": "doctrine/instantiator",

View File

@@ -930,6 +930,17 @@ form:
validate:
type: bool
media.auto_metadata_exif:
type: toggle
label: PLUGIN_ADMIN.ENABLE_AUTO_METADATA
help: PLUGIN_ADMIN.ENABLE_AUTO_METADATA_HELP
highlight: 0
options:
1: PLUGIN_ADMIN.YES
0: PLUGIN_ADMIN.NO
validate:
type: bool
media.allowed_fallback_types:

View File

@@ -121,10 +121,11 @@ images:
auto_fix_orientation: false # Automatically fix the image orientation based on the Exif data
media:
enable_media_timestamp: false # Enable media timetsamps
enable_media_timestamp: false # Enable media timestamps
upload_limit: 0 # Set maximum upload size in bytes (0 is unlimited)
unsupported_inline_types: [] # Array of supported media types to try to display inline
allowed_fallback_types: [] # Array of allowed media types of files found if accessed via Page route
auto_metadata_exif: false # Automatically create metadata files from Exif data where possible
session:
enabled: true # Enable Session support

View File

@@ -45,6 +45,7 @@ class Grav extends Container
'Grav\Common\Service\PageServiceProvider',
'Grav\Common\Service\OutputServiceProvider',
'browser' => 'Grav\Common\Browser',
'exif' => 'Grav\Common\Helpers\Exif',
'Grav\Common\Service\StreamsServiceProvider',
'Grav\Common\Service\ConfigServiceProvider',
'inflector' => 'Grav\Common\Inflector',

View File

@@ -0,0 +1,27 @@
<?php
/**
* @package Grav.Common.Helpers
*
* @copyright Copyright (C) 2014 - 2017 RocketTheme, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Helpers;
use Grav\Common\Grav;
class Exif
{
public $reader;
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')) {
throw new \Exception('Please enable the Exif extension for PHP or disable Exif support in Grav system configuration');
}
}
}
}

View File

@@ -8,9 +8,12 @@
namespace Grav\Common\Page;
use Grav\Common\Grav;
use Grav\Common\Page\Medium\AbstractMedia;
use Grav\Common\Page\Medium\GlobalMedia;
use Grav\Common\Page\Medium\MediumFactory;
use RocketTheme\Toolbox\File\File;
use Symfony\Component\Yaml\Yaml;
class Media extends AbstractMedia
{
@@ -18,6 +21,8 @@ class Media extends AbstractMedia
protected $path;
protected $standard_exif = ['FileSize', 'MimeType', 'height', 'width'];
/**
* @param $path
*/
@@ -58,6 +63,8 @@ class Media extends AbstractMedia
*/
protected function init()
{
$config = Grav::instance()['config'];
$exif = Grav::instance()['exif'];
// Handle special cases where page doesn't exist in filesystem.
if (!is_dir($this->path)) {
@@ -71,7 +78,7 @@ class Media extends AbstractMedia
/** @var \DirectoryIterator $info */
foreach ($iterator as $path => $info) {
// Ignore folders and Markdown files.
if (!$info->isFile() || $info->getExtension() == 'md' || $info->getBasename()[0] === '.') {
if (!$info->isFile() || $info->getExtension() === 'md' || $info->getBasename()[0] === '.') {
continue;
}
@@ -116,6 +123,23 @@ class Media extends AbstractMedia
continue;
}
// 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')) {
$file_path = $types['base']['file'];
$meta = $exif->reader->read($file_path);
if ($meta) {
$meta_path = $file_path . '.meta.yaml';
$meta_data = $meta->getData();
$meta_trimmed = array_diff_key($meta_data, array_flip($this->standard_exif));
if ($meta_trimmed) {
$file = File::instance($meta_path);
$file->save(Yaml::dump($meta_trimmed));
$types['meta']['file'] = $meta_path;
}
}
}
if (!empty($types['meta'])) {
$medium->addMetaFile($types['meta']['file']);
}

View File

@@ -49,6 +49,11 @@ class Medium extends Data implements RenderableInterface
*/
protected $styleAttributes = [];
/**
* @var array
*/
protected $metadata = [];
/**
* Construct.
*
@@ -77,6 +82,16 @@ class Medium extends Data implements RenderableInterface
return new Data($this->items);
}
/**
* Returns an array containing just the metadata
*
* @return array
*/
public function metadata()
{
return $this->metadata;
}
/**
* Add meta file for the medium.
*
@@ -84,7 +99,8 @@ class Medium extends Data implements RenderableInterface
*/
public function addMetaFile($filepath)
{
$this->merge((array)CompiledYamlFile::instance($filepath)->content());
$this->metadata = (array)CompiledYamlFile::instance($filepath)->content();
$this->merge($this->metadata);
}
/**

View File

@@ -125,6 +125,7 @@ class TwigExtension extends \Twig_Extension
new \Twig_SimpleFunction('redirect_me', [$this, 'redirectFunc']),
new \Twig_SimpleFunction('range', [$this, 'rangeFunc']),
new \Twig_SimpleFunction('isajaxrequest', [$this, 'isAjaxFunc']),
new \Twig_SimpleFunction('exif', [$this, 'exifFunc']),
];
}
@@ -137,7 +138,7 @@ class TwigExtension extends \Twig_Extension
*/
public function fieldNameFilter($str)
{
$path = explode('.', $str);
$path = explode('.', rtrim($str, '.'));
return array_shift($path) . ($path ? '[' . implode('][', $path) . ']' : '');
}
@@ -956,4 +957,27 @@ class TwigExtension extends \Twig_Extension
!empty($_SERVER['HTTP_X_REQUESTED_WITH'])
&& strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest');
}
/**
* Get's the Exif data for a file
*
* @param $image
* @param bool $raw
* @return mixed
*/
public function exifFunc($image, $raw = false)
{
if (file_exists($image)) {
$exif_data = $this->grav['exif']->reader->read($image);
if ($exif_data) {
if ($raw) {
return $exif_data->getRawData();
} else {
return $exif_data->getData();
}
}
}
}
}

View File

@@ -41,13 +41,7 @@ class CleanCommand extends Command
'user/plugins/email/vendor/swiftmailer/swiftmailer/notes',
'user/plugins/email/vendor/swiftmailer/swiftmailer/doc',
'user/themes/antimatter/.sass-cache',
'vendor/donatj/phpuseragentparser/.git',
'vendor/donatj/phpuseragentparser/.gitignore',
'vendor/donatj/phpuseragentparser/.travis.yml',
'vendor/donatj/phpuseragentparser/composer.json',
'vendor/donatj/phpuseragentparser/phpunit.xml.dist',
'vendor/donatj/phpuseragentparser/Tests',
'vendor/donatj/phpuseragentparser/Tools',
'vendor/antoligy/dom-string-iterators/composer.json',
'vendor/doctrine/cache/.travis.yml',
'vendor/doctrine/cache/build.properties',
'vendor/doctrine/cache/build.xml',
@@ -57,6 +51,16 @@ class CleanCommand extends Command
'vendor/doctrine/cache/.gitignore',
'vendor/doctrine/cache/.git',
'vendor/doctrine/cache/tests',
'vendor/doctrine/collections/composer.json',
'vendor/doctrine/collections/phpunit.xml.dist',
'vendor/doctrine/collections/tests',
'vendor/donatj/phpuseragentparser/.git',
'vendor/donatj/phpuseragentparser/.gitignore',
'vendor/donatj/phpuseragentparser/.travis.yml',
'vendor/donatj/phpuseragentparser/composer.json',
'vendor/donatj/phpuseragentparser/phpunit.xml.dist',
'vendor/donatj/phpuseragentparser/Tests',
'vendor/donatj/phpuseragentparser/Tools',
'vendor/erusev/parsedown/composer.json',
'vendor/erusev/parsedown/phpunit.xml.dist',
'vendor/erusev/parsedown/.travis.yml',
@@ -132,6 +136,12 @@ class CleanCommand extends Command
'vendor/symfony/console/.git',
'vendor/symfony/console/Tester',
'vendor/symfony/console/Tests',
'vendor/symfony/debug/.gitignore',
'vendor/symfony/debug/.git',
'vendor/symfony/debug/phpunit.xml.dist',
'vendor/symfony/debug/composer.json',
'vendor/symfony/debug/Tests',
'vendor/symfony/debug/Resources',
'vendor/symfony/event-dispatcher/.git',
'vendor/symfony/event-dispatcher/.gitignore',
'vendor/symfony/event-dispatcher/composer.json',