Merge branch 'release/1.0.6'

This commit is contained in:
Andy Miller
2015-12-22 17:15:44 -07:00
23 changed files with 204 additions and 251 deletions

View File

@@ -44,7 +44,7 @@ RewriteRule .* index.php [L]
## Begin - Security
# Block all direct access for these folders
RewriteRule ^(.git|cache|bin|logs|backup)/(.*) error [F]
RewriteRule ^(.git|cache|bin|logs|backup|webserver-configs)/(.*) error [F]
# Block access to specific file types for these system folders
RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
# Block access to specific file types for these user folders
@@ -54,7 +54,7 @@ RewriteRule \.md$ error [F]
# Block all direct access to files and folders beginning with a dot
RewriteRule (^\.|/\.) - [F]
# Block access to specific files in the root folder
RewriteRule ^(LICENSE.txt|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess)$ error [F]
RewriteRule ^(LICENSE.txt|composer.lock|composer.json|\.htaccess)$ error [F]
## End - Security
</IfModule>

View File

@@ -43,7 +43,7 @@ before_install:
- export TZ=Pacific/Honolulu
- composer self-update
- go get github.com/aktau/github-release
- echo "Travis Date: `date`"
- echo "Travis Date - `date`"
- git clone --quiet --depth=50 --branch=master https://${BB_TOKEN}bitbucket.org/rockettheme/grav-devtools.git $RT_DEVTOOLS &>/dev/null;
- if [ ! -z "$TRAVIS_TAG" ]; then
cd "${RT_DEVTOOLS}";

View File

@@ -1,3 +1,20 @@
# v1.0.6
## 12/22/2015
1. [](#new)
* Set minimum requirements to [PHP 5.5.9](http://bit.ly/1Jt9OXO)
* Added `saveConfig` to Themes
1. [](#improved)
* Updated Whoops to new 2.0 version (PHP 7.0 compatbile)
* Moved sample web server configs into dedicated directory
* FastCGI will use Apache's `mod_deflate` if gzip turned off
1. [](#bugfix)
* Fix broken media image operators
* Only call extra method of blueprints if blueprints exist
* Fix lang prefix in url twig variables #523
* Fix case insensitive HTTPS check #535
* Field field validation handles case `multiple` missing
# v1.0.5
## 12/18/2015

View File

@@ -6,7 +6,7 @@
"homepage": "http://getgrav.org",
"license": "MIT",
"require": {
"php": ">=5.4.0",
"php": ">=5.5.9",
"twig/twig": "~1.23",
"erusev/parsedown": "dev-master as 1.6.0",
"erusev/parsedown-extra": "~0.7",
@@ -16,7 +16,7 @@
"symfony/var-dumper": "~2.8",
"symfony/polyfill-iconv": "~1.0",
"doctrine/cache": "~1.5",
"filp/whoops": "1.1.10",
"filp/whoops": "2.0.0-alpha2",
"monolog/monolog": "~1.0",
"gregwar/image": "~2.0",
"ircmaxell/password-compat": "1.0.*",

57
composer.lock generated
View File

@@ -4,21 +4,21 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
"hash": "82d333365d7424d73da22f99a2daa42c",
"content-hash": "6d876da7dbe11934a98374e67d15550c",
"hash": "94131c9b1e1bafa572e1022ca6093544",
"content-hash": "fd3f9839960586cb8d7c841eb3a51610",
"packages": [
{
"name": "doctrine/cache",
"version": "v1.5.2",
"version": "v1.5.4",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "47c7128262da274f590ae6f86eb137a7a64e82af"
"reference": "47cdc76ceb95cc591d9c79a36dc3794975b5d136"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/47c7128262da274f590ae6f86eb137a7a64e82af",
"reference": "47c7128262da274f590ae6f86eb137a7a64e82af",
"url": "https://api.github.com/repos/doctrine/cache/zipball/47cdc76ceb95cc591d9c79a36dc3794975b5d136",
"reference": "47cdc76ceb95cc591d9c79a36dc3794975b5d136",
"shasum": ""
},
"require": {
@@ -75,7 +75,7 @@
"cache",
"caching"
],
"time": "2015-12-03 10:50:37"
"time": "2015-12-19 05:03:47"
},
{
"name": "donatj/phpuseragentparser",
@@ -134,12 +134,12 @@
"source": {
"type": "git",
"url": "https://github.com/getgrav/parsedown.git",
"reference": "10a7ff776c3f16b1b3aa41c176c48150fc091065"
"reference": "e7443a2bd868e78946ae6a01a1b07d477ce6f4cc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/getgrav/parsedown/zipball/10a7ff776c3f16b1b3aa41c176c48150fc091065",
"reference": "10a7ff776c3f16b1b3aa41c176c48150fc091065",
"url": "https://api.github.com/repos/getgrav/parsedown/zipball/e7443a2bd868e78946ae6a01a1b07d477ce6f4cc",
"reference": "e7443a2bd868e78946ae6a01a1b07d477ce6f4cc",
"shasum": ""
},
"type": "library",
@@ -167,7 +167,7 @@
"support": {
"source": "https://github.com/getgrav/parsedown/tree/master"
},
"time": "2015-12-17 17:48:21"
"time": "2015-12-19 03:45:14"
},
{
"name": "erusev/parsedown-extra",
@@ -215,36 +215,41 @@
},
{
"name": "filp/whoops",
"version": "1.1.10",
"version": "2.0.0-alpha2",
"source": {
"type": "git",
"url": "https://github.com/filp/whoops.git",
"reference": "72538eeb70bbfb11964412a3d098d109efd012f7"
"reference": "eb1ce6439db161a9f00cd57f33a9cfa1355229ec"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/filp/whoops/zipball/72538eeb70bbfb11964412a3d098d109efd012f7",
"reference": "72538eeb70bbfb11964412a3d098d109efd012f7",
"url": "https://api.github.com/repos/filp/whoops/zipball/eb1ce6439db161a9f00cd57f33a9cfa1355229ec",
"reference": "eb1ce6439db161a9f00cd57f33a9cfa1355229ec",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
"php": ">=5.5.9"
},
"require-dev": {
"mockery/mockery": "0.9.*"
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "^4.8 || ^5.0"
},
"suggest": {
"symfony/var-dumper": "Pretty print complex values better with var-dumper available",
"whoops/soap": "Formats errors as SOAP responses"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.2-dev"
"dev-master": "2.0-dev"
}
},
"autoload": {
"psr-0": {
"Whoops": "src/"
"psr-4": {
"Whoops\\": "src/Whoops/"
},
"classmap": [
"src/deprecated"
"files": [
"src/Whoops/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -265,11 +270,10 @@
"exception",
"handling",
"library",
"silex-provider",
"whoops",
"zf2"
],
"time": "2015-06-29 05:42:04"
"time": "2015-12-15 12:27:17"
},
{
"name": "gregwar/cache",
@@ -1137,12 +1141,13 @@
],
"minimum-stability": "stable",
"stability-flags": {
"erusev/parsedown": 20
"erusev/parsedown": 20,
"filp/whoops": 15
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"php": ">=5.4.0"
"php": ">=5.5.9"
},
"platform-dev": []
}

View File

@@ -1,110 +1,19 @@
body {
background-color: #eee;
}
body header {
background: #349886;
border-left: 8px solid #29796B;
background: #8552A2;
}
body .clipboard {
width: 28px;
height: 28px;
background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAcAQMAAABIw03XAAAAA3NCSVQICAjb4U/gAAAABlBMVEX///////9VfPVsAAAAAnRSTlP/AOW3MEoAAAAJcEhZcwAACxIAAAsSAdLdfvwAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzbovLKMAAAAFnRFWHRDcmVhdGlvbiBUaW1lADEwLzE1LzE0xr/LJAAAADhJREFUCJlj+P///wcGBPGDQR5E8OMi2IEEczOIaAQRHSCioQBGHAAR/7AT/z+DiA8MMALVXhABAJf9Sr5aY+UFAAAAAElFTkSuQmCC);
body .left-panel {
background: inherit;
}
body .exc-title-primary {
color: #1C3631;
text-shadow: none;
color: #fff;
}
body .exc-title {
color: #2F5B52;
text-shadow: none;
}
body .data-table-container label {
color: #0082BA;
}
body .frame {
border: 0;
}
body .frames-container {
overflow-y: auto;
overflow-x: hidden;
}
body .active .frame-class {
color: #E3D8E9;
}
body .frame-class {
color: #9055AF;
}
body .frame.active {
border: 0;
box-shadow: none;
background-color: #9055AF;
color: #ddd;
}
body .frame:not(.active):hover {
background: #e9e9e9;
}
body .frame-file, body .data-table tbody {
font-family: "DejaVu Sans Mono", Menlo, Monaco, Consolas, Courier, monospace;
font-size: 13px;
}
body .frame-code {
background: #305669;
border-left: 8px solid #253A47;
padding: 1rem;
}
body .frame-code .frame-file {
background: #253A47;
color: #eee;
text-shadow: none;
box-shadow: none;
font-family: inherit;
}
body .frame-code .frame-file strong {
color: #fff;
font-weight: normal;
}
body .frame-comments {
background: #283E4D;
box-shadow: none;
}
body .frame-comments.empty:before {
color: #789AAB;
}
body .details-container {
border: 0;
}
body .details {
background-color: #eee;
border-left: 8px solid #ddd;
padding: 1rem;
}
body .code-block {
background: #2C4454;
box-shadow: none;
font-family: "DejaVu Sans Mono", Menlo, Monaco, Consolas, Courier, monospace;
font-size: 13px;
}
body .handler.active {
background: #666;
background: #e6e6e6;
}

View File

@@ -55,7 +55,7 @@ form:
help: PLUGIN_ADMIN.LANGUAGE_HELP
security:
title: Security
title: PLUGIN_ADMIN.ACCESS_LEVELS
type: section
security: admin.super
@@ -82,4 +82,4 @@ form:
label: PLUGIN_ADMIN.SITE_ACCESS
multiple: false
validate:
type: array
type: array

View File

@@ -2,7 +2,7 @@
// Some standard defines
define('GRAV', true);
define('GRAV_VERSION', '1.0.5');
define('GRAV_VERSION', '1.0.6');
define('DS', '/');
define('GRAV_PHP_MIN', '5.5.9');

View File

@@ -43,13 +43,13 @@ INFLECTOR_SINGULAR:
'/([ti])a$/i': '\1um'
'/(n)ews$/i': '\1ews'
'/s$/i': ''
INFLECTOR_UNCOUNTABLE: ['équipment', 'information', 'riz', 'argent', 'espèces', 'séries', 'poisson', 'mouton']
INFLECTOR_UNCOUNTABLE: ['équipement', 'information', 'riz', 'argent', 'espèces', 'séries', 'poisson', 'mouton']
INFLECTOR_IRREGULAR:
'person': 'personnes'
'man': 'Hommes'
'man': 'hommes'
'child': 'enfants'
'sex': 'sexes'
'move': 'déplacemements'
'move': 'déplacements'
INFLECTOR_ORDINALS:
'default': 'ème'
'first': 'er'

View File

@@ -211,7 +211,7 @@ class Data implements DataInterface, \ArrayAccess, \Countable, ExportInterface
*/
public function extra()
{
return $this->blueprints()->extra($this->items);
return $this->blueprints ? $this->blueprints->extra($this->items) : array();
}
/**

View File

@@ -283,7 +283,7 @@ class Validation
protected static function filterFile($value, array $params, array $field)
{
if ($field['multiple'] == true) {
if (isset($field['multiple']) && $field['multiple'] == true) {
return (array) $value;
}

View File

@@ -2,51 +2,54 @@
namespace Grav\Common\Errors;
use Grav\Common\Grav;
use Whoops\Handler\CallbackHandler;
use Whoops\Handler\HandlerInterface;
use Whoops\Run;
use Whoops;
/**
* Class Debugger
* @package Grav\Common
*/
class Errors extends Run
class Errors
{
public function pushHandler($handler, $key = null)
{
if (is_callable($handler)) {
$handler = new CallbackHandler($handler);
}
if (!$handler instanceof HandlerInterface) {
throw new \InvalidArgumentException(
"Argument to " . __METHOD__ . " must be a callable, or instance of"
. "Whoops\\Handler\\HandlerInterface"
);
}
// Store with key if provided
if ($key) {
$this->handlerStack[$key] = $handler;
} else {
$this->handlerStack[] = $handler;
}
return $this;
}
public function resetHandlers()
{
$grav = Grav::instance();
$config = $grav['config']->get('system.errors');
if (isset($config['display']) && !$config['display']) {
unset($this->handlerStack['pretty']);
$this->handlerStack = array('simple' => new SimplePageHandler()) + $this->handlerStack;
}
if (isset($config['log']) && !$config['log']) {
unset($this->handlerStack['log']);
}
}
// Setup Whoops-based error handler
$whoops = new \Whoops\Run;
if (isset($config['display'])) {
if ($config['display']) {
$error_page = new Whoops\Handler\PrettyPageHandler;
$error_page->setPageTitle('Crikey! There was an error...');
$error_page->addResourcePath(GRAV_ROOT . '/system/assets');
$error_page->addCustomCss('whoops.css');
$whoops->pushHandler($error_page);
} else {
$whoops->pushHandler(new SimplePageHandler);
}
}
if (function_exists('Whoops\isAjaxRequest')) { //Whoops 2
if (Whoops\isAjaxRequest()) {
$whoops->pushHandler(new Whoops\Handler\JsonResponseHandler);
}
} else { //Whoops 1
$json_page = new Whoops\Handler\JsonResponseHandler;
$json_page->onlyForAjaxRequests(true);
}
if (isset($config['log']) && $config['log']) {
$logger = $grav['log'];
$whoops->pushHandler(function($exception, $inspector, $run) use ($logger) {
try {
$logger->addCritical($exception->getMessage() . ' - Trace: ' . $exception->getTraceAsString());
} catch (\Exception $e) {
echo $e;
}
}, 'log');
}
$whoops->register();
}
}

View File

@@ -417,41 +417,49 @@ class Grav extends Container
*/
public function shutdown()
{
if ($this['config']->get('system.debugger.shutdown.close_connection')) {
// Prevent user abort.
if (function_exists('ignore_user_abort')) {
@ignore_user_abort(true);
}
// Close the session.
if (isset($this['session'])) {
$this['session']->close();
}
if ($this['config']->get('system.cache.gzip')) {
// Flush gzhandler buffer if gzip was enabled.
ob_end_flush();
} else {
// Otherwise prevent server from compressing the output.
header('Content-Encoding: none');
}
// Get length and close the connection.
header('Content-Length: ' . ob_get_length());
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')) {
@fastcgi_finish_request();
}
// Prevent user abort allowing onShutdown event to run without interruptions.
if (function_exists('ignore_user_abort')) {
@ignore_user_abort(true);
}
// Close the session allowing new requests to be handled.
if (isset($this['session'])) {
$this['session']->close();
}
if ($this['config']->get('system.debugger.shutdown.close_connection', true)) {
// Flush the response and close the connection to allow time consuming tasks to be performed without leaving
// the connection to the client open. This will make page loads to feel much faster.
// FastCGI allows us to flush all response data to the client and finish the request.
$success = function_exists('fastcgi_finish_request') ? @fastcgi_finish_request() : false;
if (!$success) {
// Unfortunately without FastCGI there is no way to close the connection. We need to ask browser to
// close the connection for us.
if ($this['config']->get('system.cache.gzip')) {
// Flush gzhandler buffer if gzip setting was enabled.
ob_end_flush();
} else {
// Without gzip we have no other choice than to prevent server from compressing the output.
// This action turns off mod_deflate which would prevent us from closing the connection.
header('Content-Encoding: none');
}
// Get length and close the connection.
header('Content-Length: ' . ob_get_length());
header("Connection: close");
// Finally flush the regular buffer.
ob_end_flush();
@ob_flush();
flush();
}
}
// Run any time consuming tasks.
$this->fireEvent('onShutdown');
}

View File

@@ -18,8 +18,8 @@ trait ParsedownGravTrait
protected $special_chars;
protected $twig_link_regex = '/\!*\[(?:.*)\]\((\{([\{%#])\s*(.*?)\s*(?:\2|\})\})\)/';
public $completeable_blocks = [];
public $continueable_blocks = [];
public $completable_blocks = [];
public $continuable_blocks = [];
/**
* Initialization function to setup key variables needed by the MarkdownGravLinkTrait
@@ -57,16 +57,16 @@ trait ParsedownGravTrait
* @param $type
* @param $tag
*/
public function addBlockType($type, $tag, $continueable = false, $completeable = false)
public function addBlockType($type, $tag, $continuable = false, $completable = false)
{
$this->BlockTypes[$type] []= $tag;
if ($continueable) {
$this->continueable_blocks[] = $tag;
if ($continuable) {
$this->continuable_blocks[] = $tag;
}
if ($completeable) {
$this->completeable_blocks[] = $tag;
if ($completable) {
$this->completable_blocks[] = $tag;
}
}
@@ -83,27 +83,27 @@ trait ParsedownGravTrait
}
/**
* Overrides the default behavior to allow for plugin-provided blocks to be continueable
* Overrides the default behavior to allow for plugin-provided blocks to be continuable
*
* @param $Type
* @return bool
*/
protected function isBlockContinueable($Type)
protected function isBlockContinuable($Type)
{
$continueable = in_array($Type, $this->continueable_blocks) || method_exists($this, 'block'.$Type.'Continue');
return $continueable;
$continuable = in_array($Type, $this->continuable_blocks) || method_exists($this, 'block'.$Type.'Continue');
return $continuable;
}
/**
* Overrides the default behavior to allow for plugin-provided blocks to be completeable
* Overrides the default behavior to allow for plugin-provided blocks to be completable
*
* @param $Type
* @return bool
*/
protected function isBlockCompleteable($Type)
protected function isBlockCompletable($Type)
{
$completeable = in_array($Type, $this->completeable_blocks) || method_exists($this, 'block'.$Type.'Complete');
return $completeable;
$completable = in_array($Type, $this->completable_blocks) || method_exists($this, 'block'.$Type.'Complete');
return $completable;
}
@@ -272,7 +272,7 @@ trait ParsedownGravTrait
if (isset($url['query'])) {
$actions = array_reduce(explode('&', $url['query']), function ($carry, $item) {
$parts = explode('=', $item, 2);
$value = isset($parts[1]) ? $parts[1] : null;
$value = isset($parts[1]) ? $parts[1] : true;
$carry[$parts[0]] = $value;
return $carry;

View File

@@ -12,33 +12,7 @@ class ErrorServiceProvider implements ServiceProviderInterface
{
public function register(Container $container)
{
// Setup Whoops-based error handler
$errors = new Errors;
$error_page = new PrettyPageHandler;
$error_page->setPageTitle('Crikey! There was an error...');
$error_page->setEditor('sublime');
$error_page->addResourcePath(GRAV_ROOT . '/system/assets');
$error_page->addCustomCss('whoops.css');
$json_page = new JsonResponseHandler;
$json_page->onlyForAjaxRequests(true);
$errors->pushHandler($error_page, 'pretty');
$errors->pushHandler(new PlainTextHandler, 'text');
$errors->pushHandler($json_page, 'json');
$logger = $container['log'];
$errors->pushHandler(function (\Exception $exception, $inspector, $run) use ($logger) {
try {
$logger->addCritical($exception->getMessage() . ' - Trace: ' . $exception->getTraceAsString());
} catch (\Exception $e) {
echo $e;
}
}, 'log');
$errors->register();
$container['errors'] = $errors;
}
}

View File

@@ -20,4 +20,26 @@ class Theme extends Plugin
parent::__construct($name, $grav, $config);
}
/**
* Persists to disk the theme parameters currently stored in the Grav Config object
*
* @param string $theme_name The name of the theme whose config it should store.
*
* @return true
*/
public static function saveConfig($theme_name) {
if (!$theme_name) {
return false;
}
$locator = Grav::instance()['locator'];
$filename = 'config://themes/' . $theme_name . '.yaml';
$file = YamlFile::instance($locator->findResource($filename, true, true));
$content = Grav::instance()['config']->get('themes.' . $theme_name);
$file->save($content);
$file->free();
return true;
}
}

View File

@@ -80,7 +80,10 @@ class Twig
$active_language = $language->getActive();
$language_append = $active_language ? '/'.$active_language : '';
$language_append = '';
if ($language->getDefault() != $active_language || $config->get('system.languages.include_default_lang') === true) {
$language_append = $active_language ? '/' . $active_language : '';
}
// handle language templates if available
if ($language->enabled()) {

View File

@@ -46,7 +46,7 @@ class Uri
// set the base
if (isset($_SERVER['HTTPS'])) {
$base = (@$_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://';
$base = (strtolower(@$_SERVER['HTTPS']) == 'on') ? 'https://' : 'http://';
} else {
$base = 'http://';
}

View File

@@ -0,0 +1,12 @@
:8080
gzip
fastcgi / 127.0.0.1:9000 {
ext .php
split .php
index index.php
}
rewrite {
regexp .*
ext /
to /index.php?_url={uri}
}

View File

@@ -44,7 +44,7 @@ RewriteRule .* index.php [L]
## Begin - Security
# Block all direct access for these folders
RewriteRule ^(.git|cache|bin|logs|backup)/(.*) error [F]
RewriteRule ^(.git|cache|bin|logs|backup|webserver-configs)/(.*) error [F]
# Block access to specific file types for these system folders
RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ error [F]
# Block access to specific file types for these user folders
@@ -54,7 +54,7 @@ RewriteRule \.md$ error [F]
# Block all direct access to files and folders beginning with a dot
RewriteRule (^\.|/\.) - [F]
# Block access to specific files in the root folder
RewriteRule ^(LICENSE.txt|composer.lock|composer.json|nginx.conf|web.config|htaccess.txt|\.htaccess)$ error [F]
RewriteRule ^(LICENSE.txt|composer.lock|composer.json|\.htaccess)$ error [F]
## End - Security
</IfModule>