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

# Conflicts:
#	CHANGELOG.md
This commit is contained in:
Andy Miller
2018-01-19 10:32:37 -07:00
8 changed files with 145 additions and 34 deletions

View File

@@ -7,13 +7,12 @@
* Made `modular` blueprint more flexible
* Objects: Add protected function `getElement()` to get serialized value for a single property
* `ObjectPropertyTrait`: Added protected functions `isPropertyLoaded()`, `offsetLoad()`, `offsetPrepare()` and `offsetSerialize()`
* `Grav\Framework\Cache`: Allow unlimited TTL
* Slight modification of Whoops error colors
* Updated vendor libs to latest
1. [](#bugfix)
* Date ordering should always be numeric [#1810](https://github.com/getgrav/grav/issues/1810)
# v1.4.0-beta.3
## 12/29/2017

View File

@@ -17,10 +17,12 @@ class ParsedownExtra extends \ParsedownExtra
*
* @param $page
* @param $defaults
* @throws \Exception
*/
public function __construct($page, $defaults)
{
parent::__construct();
$this->init($page, $defaults);
}
}

View File

@@ -10,6 +10,7 @@ namespace Grav\Framework\Cache\Adapter;
use Grav\Framework\Cache\AbstractCache;
use Grav\Framework\Cache\CacheInterface;
use Grav\Framework\Cache\Exception\InvalidArgumentException;
/**
* Cache class for PSR-16 compatible "Simple Cache" implementation using chained cache adapters.
@@ -32,19 +33,19 @@ class ChainCache extends AbstractCache
* Chain Cache constructor.
* @param array $caches
* @param null|int|\DateInterval $defaultLifetime
* @throws \InvalidArgumentException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function __construct(array $caches, $defaultLifetime = null)
{
parent::__construct('', $defaultLifetime);
if (!$caches) {
throw new \InvalidArgumentException('At least one cache must be specified');
throw new InvalidArgumentException('At least one cache must be specified');
}
foreach ($caches as $cache) {
if (!$cache instanceof CacheInterface) {
throw new \InvalidArgumentException(
throw new InvalidArgumentException(
sprintf(
"The class '%s' does not implement the '%s' interface",
get_class($cache),
@@ -58,6 +59,9 @@ class ChainCache extends AbstractCache
$this->count = count($caches);
}
/**
* @inheritdoc
*/
public function doGet($key, $miss)
{
foreach ($this->caches as $i => $cache) {
@@ -75,6 +79,9 @@ class ChainCache extends AbstractCache
return $miss;
}
/**
* @inheritdoc
*/
public function doSet($key, $value, $ttl)
{
$success = true;
@@ -87,6 +94,9 @@ class ChainCache extends AbstractCache
return $success;
}
/**
* @inheritdoc
*/
public function doDelete($key)
{
$success = true;
@@ -99,6 +109,9 @@ class ChainCache extends AbstractCache
return $success;
}
/**
* @inheritdoc
*/
public function doClear()
{
$success = true;
@@ -110,7 +123,9 @@ class ChainCache extends AbstractCache
return $success;
}
/**
* @inheritdoc
*/
public function doGetMultiple($keys, $miss)
{
$list = [];
@@ -136,6 +151,9 @@ class ChainCache extends AbstractCache
return $values;
}
/**
* @inheritdoc
*/
public function doSetMultiple($values, $ttl)
{
$success = true;
@@ -148,6 +166,9 @@ class ChainCache extends AbstractCache
return $success;
}
/**
* @inheritdoc
*/
public function doDeleteMultiple($keys)
{
$success = true;
@@ -160,6 +181,9 @@ class ChainCache extends AbstractCache
return $success;
}
/**
* @inheritdoc
*/
public function doHas($key)
{
foreach ($this->caches as $cache) {

View File

@@ -10,6 +10,7 @@ namespace Grav\Framework\Cache\Adapter;
use Doctrine\Common\Cache\CacheProvider;
use Grav\Framework\Cache\AbstractCache;
use Grav\Framework\Cache\Exception\InvalidArgumentException;
/**
* Cache class for PSR-16 compatible "Simple Cache" implementation using Doctrine Cache backend.
@@ -28,6 +29,7 @@ class DoctrineCache extends AbstractCache
* @param CacheProvider $doctrineCache
* @param string $namespace
* @param null|int|\DateInterval $defaultLifetime
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function __construct(CacheProvider $doctrineCache, $namespace = '', $defaultLifetime = null)
{
@@ -41,6 +43,9 @@ class DoctrineCache extends AbstractCache
$this->driver = $doctrineCache;
}
/**
* @inheritdoc
*/
public function doGet($key, $miss)
{
$value = $this->driver->fetch($key);
@@ -49,31 +54,50 @@ class DoctrineCache extends AbstractCache
return $value !== false || $this->driver->contains($key) ? $value : $miss;
}
/**
* @inheritdoc
*/
public function doSet($key, $value, $ttl)
{
return $this->driver->save($key, $value, (int) $ttl);
}
/**
* @inheritdoc
*/
public function doDelete($key)
{
return $this->driver->delete($key);
}
/**
* @inheritdoc
*/
public function doClear()
{
return $this->driver->deleteAll();
}
/**
* @inheritdoc
*/
public function doGetMultiple($keys, $miss)
{
return $this->driver->fetchMultiple($keys);
}
/**
* @inheritdoc
*/
public function doSetMultiple($values, $ttl)
{
return $this->driver->saveMultiple($values, (int) $ttl);
}
/**
* @inheritdoc
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function doDeleteMultiple($keys)
{
// TODO: Remove when Doctrine Cache has been updated to support the feature.
@@ -89,6 +113,9 @@ class DoctrineCache extends AbstractCache
return $this->driver->deleteMultiple($keys);
}
/**
* @inheritdoc
*/
public function doHas($key)
{
return $this->driver->contains($key);

View File

@@ -15,6 +15,8 @@ use Grav\Framework\Cache\Exception\InvalidArgumentException;
/**
* Cache class for PSR-16 compatible "Simple Cache" implementation using file backend.
*
* Defaults to 1 year TTL. Does not support unlimited TTL.
*
* @package Grav\Framework\Cache
*/
class FileCache extends AbstractCache
@@ -22,6 +24,17 @@ class FileCache extends AbstractCache
private $directory;
private $tmp;
/**
* @inheritdoc
*/
public function __construct($namespace = '', $defaultLifetime = null)
{
parent::__construct($namespace, $defaultLifetime ?: 31557600); // = 1 year
}
/**
* @inheritdoc
*/
public function doGet($key, $miss)
{
$now = time();
@@ -47,9 +60,13 @@ class FileCache extends AbstractCache
return $miss;
}
/**
* @inheritdoc
* @throws \Psr\SimpleCache\CacheException
*/
public function doSet($key, $value, $ttl)
{
$expiresAt = time() + ($ttl ?: 31557600); // = 1 year
$expiresAt = time() + (int)$ttl;
$result = $this->write(
$this->getFile($key, true),
@@ -64,6 +81,9 @@ class FileCache extends AbstractCache
return $result;
}
/**
* @inheritdoc
*/
public function doDelete($key)
{
$file = $this->getFile($key);
@@ -71,6 +91,9 @@ class FileCache extends AbstractCache
return (!file_exists($file) || @unlink($file) || !file_exists($file));
}
/**
* @inheritdoc
*/
public function doClear()
{
$result = true;
@@ -83,6 +106,9 @@ class FileCache extends AbstractCache
return $result;
}
/**
* @inheritdoc
*/
public function doHas($key)
{
$file = $this->getFile($key);
@@ -90,6 +116,11 @@ class FileCache extends AbstractCache
return file_exists($file) && (@filemtime($file) > time() || $this->doGet($key, null));
}
/**
* @param string $key
* @param bool $mkdir
* @return string
*/
protected function getFile($key, $mkdir = false)
{
$hash = str_replace('/', '-', base64_encode(hash('sha256', static::class . $key, true)));
@@ -102,6 +133,11 @@ class FileCache extends AbstractCache
return $dir . substr($hash, 2, 20);
}
/**
* @param string $namespace
* @param string $directory
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
private function init($namespace, $directory)
{
if (!isset($directory[0])) {
@@ -129,6 +165,12 @@ class FileCache extends AbstractCache
$this->directory = $directory;
}
/**
* @param string $file
* @param string $data
* @param int|null $expiresAt
* @return bool
*/
private function write($file, $data, $expiresAt = null)
{
set_error_handler(__CLASS__.'::throwError');
@@ -152,6 +194,7 @@ class FileCache extends AbstractCache
/**
* @internal
* @throws \ErrorException
*/
public static function throwError($type, $message, $file, $line)
{

View File

@@ -12,6 +12,7 @@ use Grav\Framework\Cache\AbstractCache;
/**
* Cache class for PSR-16 compatible "Simple Cache" implementation using in memory backend.
*
* Memory backend does not use namespace or default ttl as the cache is unique to each cache object and request.
*
* @package Grav\Framework\Cache
@@ -23,14 +24,6 @@ class MemoryCache extends AbstractCache
*/
protected $cache = [];
/**
* Memory Cache constructor.
*/
public function __construct()
{
parent::__construct('', 300);
}
public function doGet($key, $miss)
{
if (!array_key_exists($key, $this->cache)) {

View File

@@ -29,7 +29,13 @@ class SessionCache extends AbstractCache
public function doSet($key, $value, $ttl)
{
$_SESSION[$this->getNamespace()][$key] = [self::VALUE => $value, self::LIFETIME => time() + $ttl];
$stored = [self::VALUE => $value];
if (null !== $ttl) {
$stored[self::LIFETIME] = time() + $ttl;
}
$_SESSION[$this->getNamespace()][$key] = $stored;
return true;
}
@@ -43,7 +49,7 @@ class SessionCache extends AbstractCache
public function doClear()
{
$_SESSION[$this->getNamespace()] = [];
unset($_SESSION[$this->getNamespace()]);
return true;
}
@@ -62,7 +68,7 @@ class SessionCache extends AbstractCache
{
$stored = isset($_SESSION[$this->getNamespace()][$key]) ? $_SESSION[$this->getNamespace()][$key] : null;
if ($stored && $stored[self::LIFETIME] < time()) {
if (isset($stored[self::LIFETIME]) && $stored[self::LIFETIME] < time()) {
unset($_SESSION[$this->getNamespace()][$key]);
$stored = null;
}

View File

@@ -36,12 +36,12 @@ trait CacheTrait
*
* @param string $namespace
* @param null|int|\DateInterval $defaultLifetime
* @throws InvalidArgumentException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
protected function init($namespace = '', $defaultLifetime = null)
{
$this->namespace = (string) $namespace;
$this->defaultLifetime = $this->convertTtl($defaultLifetime, true);
$this->defaultLifetime = $this->convertTtl($defaultLifetime);
$this->miss = new \stdClass;
}
@@ -63,7 +63,7 @@ trait CacheTrait
/**
* @inheritdoc
* @throws InvalidArgumentException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function get($key, $default = null)
{
@@ -76,7 +76,7 @@ trait CacheTrait
/**
* @inheritdoc
* @throws InvalidArgumentException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function set($key, $value, $ttl = null)
{
@@ -85,12 +85,12 @@ trait CacheTrait
$ttl = $this->convertTtl($ttl);
// If a negative or zero TTL is provided, the item MUST be deleted from the cache.
return $ttl <= 0 ? $this->doDelete($key) : $this->doSet($key, $value, $ttl);
return null !== $ttl && $ttl <= 0 ? $this->doDelete($key) : $this->doSet($key, $value, $ttl);
}
/**
* @inheritdoc
* @throws InvalidArgumentException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function delete($key)
{
@@ -109,7 +109,7 @@ trait CacheTrait
/**
* @inheritdoc
* @throws InvalidArgumentException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function getMultiple($keys, $default = null)
{
@@ -149,7 +149,7 @@ trait CacheTrait
/**
* @inheritdoc
* @throws InvalidArgumentException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function setMultiple($values, $ttl = null)
{
@@ -175,12 +175,12 @@ trait CacheTrait
$ttl = $this->convertTtl($ttl);
// If a negative or zero TTL is provided, the item MUST be deleted from the cache.
return $ttl <= 0 ? $this->doDeleteMultiple($keys) : $this->doSetMultiple($values, $ttl);
return null !== $ttl && $ttl <= 0 ? $this->doDeleteMultiple($keys) : $this->doSetMultiple($values, $ttl);
}
/**
* @inheritdoc
* @throws InvalidArgumentException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function deleteMultiple($keys)
{
@@ -206,7 +206,7 @@ trait CacheTrait
/**
* @inheritdoc
* @throws InvalidArgumentException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
public function has($key)
{
@@ -220,6 +220,11 @@ trait CacheTrait
abstract public function doDelete($key);
abstract public function doClear();
/**
* @param array $keys
* @param mixed $miss
* @return array
*/
public function doGetMultiple($keys, $miss)
{
$results = [];
@@ -234,6 +239,11 @@ trait CacheTrait
return $results;
}
/**
* @param array $values
* @param int $ttl
* @return bool
*/
public function doSetMultiple($values, $ttl)
{
$success = true;
@@ -245,6 +255,10 @@ trait CacheTrait
return $success;
}
/**
* @param array $keys
* @return bool
*/
public function doDeleteMultiple($keys)
{
$success = true;
@@ -260,7 +274,7 @@ trait CacheTrait
/**
* @param string $key
* @throws InvalidArgumentException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
protected function validateKey($key)
{
@@ -287,6 +301,10 @@ trait CacheTrait
}
}
/**
* @param array $keys
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
protected function validateKeys($keys)
{
foreach ($keys as $key) {
@@ -296,13 +314,12 @@ trait CacheTrait
/**
* @param null|int|\DateInterval $ttl
* @param bool $ignoreDefault Used internally inside $this->init().
* @return int|null
* @throws InvalidArgumentException
* @throws \Psr\SimpleCache\InvalidArgumentException
*/
protected function convertTtl($ttl, $ignoreDefault = false)
protected function convertTtl($ttl)
{
if (!$ignoreDefault && $ttl === null) {
if ($ttl === null) {
return $this->getDefaultLifetime();
}