mirror of
https://github.com/getgrav/grav.git
synced 2026-01-29 02:40:07 +01:00
Merge branch 'develop' of https://github.com/getgrav/grav into 2.0
# Conflicts: # composer.lock
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
82
composer.lock
generated
@@ -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",
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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',
|
||||
|
||||
27
system/src/Grav/Common/Helpers/Exif.php
Normal file
27
system/src/Grav/Common/Helpers/Exif.php
Normal 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');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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']);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
Reference in New Issue
Block a user