maj+ header
This commit is contained in:
@@ -262,18 +262,22 @@ class Setup extends Data
|
||||
);
|
||||
}
|
||||
|
||||
if (!$locator->findResource('environment://config', true)) {
|
||||
// If environment does not have its own directory, remove it from the lookup.
|
||||
$this->set('streams.schemes.environment.prefixes', ['config' => []]);
|
||||
$this->initializeLocator($locator);
|
||||
}
|
||||
try {
|
||||
if (!$locator->findResource('environment://config', true)) {
|
||||
// If environment does not have its own directory, remove it from the lookup.
|
||||
$this->set('streams.schemes.environment.prefixes', ['config' => []]);
|
||||
$this->initializeLocator($locator);
|
||||
}
|
||||
|
||||
// Create security.yaml if it doesn't exist.
|
||||
$filename = $locator->findResource('config://security.yaml', true, true);
|
||||
$file = YamlFile::instance($filename);
|
||||
if (!$file->exists()) {
|
||||
$file->save(['salt' => Utils::generateRandomString(14)]);
|
||||
$file->free();
|
||||
// Create security.yaml if it doesn't exist.
|
||||
$filename = $locator->findResource('config://security.yaml', true, true);
|
||||
$file = YamlFile::instance($filename);
|
||||
if (!$file->exists()) {
|
||||
$file->save(['salt' => Utils::generateRandomString(14)]);
|
||||
$file->free();
|
||||
}
|
||||
} catch (\RuntimeException $e) {
|
||||
throw new \RuntimeException(sprintf('Grav failed to initialize: %s', $e->getMessage()), 500, $e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@ namespace Grav\Common\Data;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Utils;
|
||||
use Symfony\Component\Yaml\Exception\ParseException;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use RocketTheme\Toolbox\Compat\Yaml\Yaml as FallbackYaml;
|
||||
|
||||
class Validation
|
||||
{
|
||||
@@ -107,7 +107,7 @@ class Validation
|
||||
$method = 'filter' . ucfirst(strtr($type, '-', '_'));
|
||||
|
||||
// If this is a YAML field validate/filter as such
|
||||
if ($type != 'yaml' && isset($field['yaml']) && $field['yaml'] === true) {
|
||||
if ($type !== 'yaml' && isset($field['yaml']) && $field['yaml'] === true) {
|
||||
$method = 'filterYaml';
|
||||
}
|
||||
|
||||
@@ -128,10 +128,12 @@ class Validation
|
||||
*/
|
||||
public static function typeText($value, array $params, array $field)
|
||||
{
|
||||
if (!is_string($value)) {
|
||||
if (!is_string($value) && !is_numeric($value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$value = (string)$value;
|
||||
|
||||
if (isset($params['min']) && strlen($value) < $params['min']) {
|
||||
return false;
|
||||
}
|
||||
@@ -643,13 +645,21 @@ class Validation
|
||||
|
||||
public static function filterYaml($value, $params)
|
||||
{
|
||||
if (!is_string($value)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
try {
|
||||
if (is_string($value)) {
|
||||
return (array) Yaml::parse($value);
|
||||
} else {
|
||||
return $value;
|
||||
}
|
||||
return (array) Yaml::parse($value);
|
||||
} catch (ParseException $e) {
|
||||
// If YAML compatibility mode is set on, fall back to older YAML parser.
|
||||
if (Grav::instance()['config']->get('system.strict_mode.yaml_compat', true)) {
|
||||
try {
|
||||
return (array) FallbackYaml::parse($value);
|
||||
} catch (ParseException $e2) {
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,8 +58,14 @@ class Debugger
|
||||
$this->enabled = $this->config->get('system.debugger.enabled');
|
||||
|
||||
if ($this->enabled()) {
|
||||
|
||||
$plugins_config = (array)$this->config->get('plugins');
|
||||
|
||||
ksort($plugins_config);
|
||||
|
||||
|
||||
$this->debugbar->addCollector(new ConfigCollector((array)$this->config->get('system'), 'Config'));
|
||||
$this->debugbar->addCollector(new ConfigCollector((array)$this->config->get('plugins'), 'Plugins'));
|
||||
$this->debugbar->addCollector(new ConfigCollector($plugins_config, 'Plugins'));
|
||||
$this->addMessage('Grav v' . GRAV_VERSION);
|
||||
}
|
||||
|
||||
|
||||
@@ -20,9 +20,6 @@ trait CompiledFile
|
||||
*/
|
||||
public function content($var = null)
|
||||
{
|
||||
// Set some options
|
||||
$this->settings(['native' => true, 'compat' => true]);
|
||||
|
||||
try {
|
||||
// If nothing has been loaded, attempt to get pre-compiled version of the file first.
|
||||
if ($var === null && $this->raw === null && $this->content === null) {
|
||||
|
||||
@@ -13,7 +13,7 @@ use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\Inflector;
|
||||
use Grav\Common\Iterator;
|
||||
use Grav\Common\Utils;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
use RocketTheme\Toolbox\File\YamlFile;
|
||||
|
||||
class GPM extends Iterator
|
||||
{
|
||||
@@ -624,7 +624,10 @@ class GPM extends Iterator
|
||||
return false;
|
||||
}
|
||||
|
||||
$blueprint = (array)Yaml::parse(file_get_contents($blueprint_file));
|
||||
$file = YamlFile::instance($blueprint_file);
|
||||
$blueprint = (array)$file->content();
|
||||
$file->free();
|
||||
|
||||
return $blueprint;
|
||||
}
|
||||
|
||||
@@ -873,7 +876,9 @@ class GPM extends Iterator
|
||||
// get currently installed version
|
||||
$locator = Grav::instance()['locator'];
|
||||
$blueprints_path = $locator->findResource('plugins://' . $dependency_slug . DS . 'blueprints.yaml');
|
||||
$package_yaml = Yaml::parse(file_get_contents($blueprints_path));
|
||||
$file = YamlFile::instance($blueprints_path);
|
||||
$package_yaml = $file->content();
|
||||
$file->free();
|
||||
$currentlyInstalledVersion = $package_yaml['version'];
|
||||
|
||||
// if requirement is next significant release, check is compatible with currently installed version, might not be
|
||||
|
||||
@@ -114,7 +114,7 @@ class Licenses
|
||||
|
||||
{
|
||||
if (!isset(self::$file)) {
|
||||
$path = Grav::instance()['locator']->findResource('user://data') . '/licenses.yaml';;
|
||||
$path = Grav::instance()['locator']->findResource('user://data') . '/licenses.yaml';
|
||||
if (!file_exists($path)) {
|
||||
touch($path);
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
namespace Grav\Common;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Page\Medium\ImageMedium;
|
||||
use Grav\Common\Page\Medium\Medium;
|
||||
use Grav\Common\Page\Page;
|
||||
@@ -205,11 +204,8 @@ class Grav extends Container
|
||||
*/
|
||||
public function redirectLangSafe($route, $code = null)
|
||||
{
|
||||
/** @var Language $language */
|
||||
$language = $this['language'];
|
||||
|
||||
if (!$this['uri']->isExternal($route) && $language->enabled() && $language->isIncludeDefaultLanguage()) {
|
||||
$this->redirect($language->getLanguage() . $route, $code);
|
||||
if (!$this['uri']->isExternal($route)) {
|
||||
$this->redirect($this['pages']->route($route), $code);
|
||||
} else {
|
||||
$this->redirect($route, $code);
|
||||
}
|
||||
@@ -443,7 +439,7 @@ class Grav extends Container
|
||||
/** @var Config $config */
|
||||
$config = $this['config'];
|
||||
|
||||
$uri_extension = $uri->extension();
|
||||
$uri_extension = strtolower($uri->extension());
|
||||
$fallback_types = $config->get('system.media.allowed_fallback_types', null);
|
||||
$supported_types = $config->get('media.types');
|
||||
|
||||
|
||||
@@ -190,10 +190,11 @@ class Inflector
|
||||
public function hyphenize($word)
|
||||
{
|
||||
$regex1 = preg_replace('/([A-Z]+)([A-Z][a-z])/', '\1-\2', $word);
|
||||
$regex2 = preg_replace('/([a-zd])([A-Z])/', '\1-\2', $regex1);
|
||||
$regex3 = preg_replace('/[^A-Z^a-z^0-9]+/', '-', $regex2);
|
||||
$regex2 = preg_replace('/([a-z])([A-Z])/', '\1-\2', $regex1);
|
||||
$regex3 = preg_replace('/([0-9])([A-Z])/', '\1-\2', $regex2);
|
||||
$regex4 = preg_replace('/[^A-Z^a-z^0-9]+/', '-', $regex3);
|
||||
|
||||
return strtolower($regex3);
|
||||
return strtolower($regex4);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Grav\Common\Media\Interfaces;
|
||||
|
||||
/**
|
||||
* Class implements media collection interface.
|
||||
*/
|
||||
interface MediaCollectionInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace Grav\Common\Media\Interfaces;
|
||||
|
||||
/**
|
||||
* Class implements media interface.
|
||||
*/
|
||||
interface MediaInterface
|
||||
{
|
||||
/**
|
||||
* Gets the associated media collection.
|
||||
*
|
||||
* @return MediaCollectionInterface Collection of associated media.
|
||||
*/
|
||||
public function getMedia();
|
||||
|
||||
/**
|
||||
* Get filesystem path to the associated media.
|
||||
*
|
||||
* @return string|null Media path or null if the object doesn't have media folder.
|
||||
*/
|
||||
public function getMediaFolder();
|
||||
|
||||
/**
|
||||
* Get display order for the associated media.
|
||||
*
|
||||
* @return array Empty array means default ordering.
|
||||
*/
|
||||
public function getMediaOrder();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Grav\Common\Media\Interfaces;
|
||||
|
||||
/**
|
||||
* Class implements media object interface.
|
||||
*/
|
||||
interface MediaObjectInterface
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
namespace Grav\Common\Media\Traits;
|
||||
|
||||
use Grav\Common\Cache;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Media\Interfaces\MediaCollectionInterface;
|
||||
use Grav\Common\Page\Media;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
trait MediaTrait
|
||||
{
|
||||
protected $media;
|
||||
|
||||
/**
|
||||
* Get filesystem path to the associated media.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
abstract public function getMediaFolder();
|
||||
|
||||
/**
|
||||
* Get display order for the associated media.
|
||||
*
|
||||
* @return array Empty array means default ordering.
|
||||
*/
|
||||
abstract public function getMediaOrder();
|
||||
|
||||
/**
|
||||
* Get URI ot the associated media. Method will return null if path isn't URI.
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
public function getMediaUri()
|
||||
{
|
||||
$folder = $this->getMediaFolder();
|
||||
|
||||
if (strpos($folder, '://')) {
|
||||
return $folder;
|
||||
}
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
$user = $locator->findResource('user://');
|
||||
if (strpos($folder, $user) === 0) {
|
||||
return 'user://' . substr($folder, strlen($user)+1);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the associated media collection.
|
||||
*
|
||||
* @return MediaCollectionInterface Representation of associated media.
|
||||
*/
|
||||
public function getMedia()
|
||||
{
|
||||
$cache = $this->getMediaCache();
|
||||
|
||||
if ($this->media === null) {
|
||||
// Use cached media if possible.
|
||||
$cacheKey = md5('media' . $this->getCacheKey());
|
||||
if (!$media = $cache->fetch($cacheKey)) {
|
||||
$media = new Media($this->getMediaFolder(), $this->getMediaOrder());
|
||||
$cache->save($cacheKey, $media);
|
||||
}
|
||||
$this->media = $media;
|
||||
}
|
||||
|
||||
return $this->media;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the associated media collection.
|
||||
*
|
||||
* @param MediaCollectionInterface $media Representation of associated media.
|
||||
* @return $this
|
||||
*/
|
||||
protected function setMedia(MediaCollectionInterface $media)
|
||||
{
|
||||
$cache = $this->getMediaCache();
|
||||
$cacheKey = md5('media' . $this->getCacheKey());
|
||||
$cache->save($cacheKey, $media);
|
||||
|
||||
$this->media = $media;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear media cache.
|
||||
*/
|
||||
protected function clearMediaCache()
|
||||
{
|
||||
$cache = $this->getMediaCache();
|
||||
$cacheKey = md5('media' . $this->getCacheKey());
|
||||
$cache->delete($cacheKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Cache
|
||||
*/
|
||||
protected function getMediaCache()
|
||||
{
|
||||
return Grav::instance()['cache'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getCacheKey();
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
namespace Grav\Common\Page\Interfaces;
|
||||
|
||||
/**
|
||||
* Class implements page interface.
|
||||
*/
|
||||
interface PageInterface
|
||||
{
|
||||
}
|
||||
@@ -24,11 +24,13 @@ class Media extends AbstractMedia
|
||||
protected $standard_exif = ['FileSize', 'MimeType', 'height', 'width'];
|
||||
|
||||
/**
|
||||
* @param $path
|
||||
* @param string $path
|
||||
* @param array $media_order
|
||||
*/
|
||||
public function __construct($path)
|
||||
public function __construct($path, array $media_order = null)
|
||||
{
|
||||
$this->path = $path;
|
||||
$this->media_order = $media_order;
|
||||
|
||||
$this->__wakeup();
|
||||
$this->init();
|
||||
|
||||
@@ -10,9 +10,11 @@ namespace Grav\Common\Page\Medium;
|
||||
|
||||
use Grav\Common\Getters;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Media\Interfaces\MediaCollectionInterface;
|
||||
use Grav\Common\Media\Interfaces\MediaObjectInterface;
|
||||
use Grav\Common\Utils;
|
||||
|
||||
abstract class AbstractMedia extends Getters
|
||||
abstract class AbstractMedia extends Getters implements MediaCollectionInterface
|
||||
{
|
||||
protected $gettersVariable = 'instances';
|
||||
|
||||
@@ -21,6 +23,7 @@ abstract class AbstractMedia extends Getters
|
||||
protected $videos = [];
|
||||
protected $audios = [];
|
||||
protected $files = [];
|
||||
protected $media_order;
|
||||
|
||||
/**
|
||||
* Get medium by filename.
|
||||
@@ -62,7 +65,7 @@ abstract class AbstractMedia extends Getters
|
||||
/**
|
||||
* Get a list of all media.
|
||||
*
|
||||
* @return array|Medium[]
|
||||
* @return array|MediaObjectInterface[]
|
||||
*/
|
||||
public function all()
|
||||
{
|
||||
@@ -74,7 +77,7 @@ abstract class AbstractMedia extends Getters
|
||||
/**
|
||||
* Get a list of all image media.
|
||||
*
|
||||
* @return array|Medium[]
|
||||
* @return array|MediaObjectInterface[]
|
||||
*/
|
||||
public function images()
|
||||
{
|
||||
@@ -85,7 +88,7 @@ abstract class AbstractMedia extends Getters
|
||||
/**
|
||||
* Get a list of all video media.
|
||||
*
|
||||
* @return array|Medium[]
|
||||
* @return array|MediaObjectInterface[]
|
||||
*/
|
||||
public function videos()
|
||||
{
|
||||
@@ -96,7 +99,7 @@ abstract class AbstractMedia extends Getters
|
||||
/**
|
||||
* Get a list of all audio media.
|
||||
*
|
||||
* @return array|Medium[]
|
||||
* @return array|MediaObjectInterface[]
|
||||
*/
|
||||
public function audios()
|
||||
{
|
||||
@@ -107,7 +110,7 @@ abstract class AbstractMedia extends Getters
|
||||
/**
|
||||
* Get a list of all file media.
|
||||
*
|
||||
* @return array|Medium[]
|
||||
* @return array|MediaObjectInterface[]
|
||||
*/
|
||||
public function files()
|
||||
{
|
||||
@@ -117,7 +120,7 @@ abstract class AbstractMedia extends Getters
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param Medium $file
|
||||
* @param MediaObjectInterface $file
|
||||
*/
|
||||
protected function add($name, $file)
|
||||
{
|
||||
@@ -145,14 +148,20 @@ abstract class AbstractMedia extends Getters
|
||||
*/
|
||||
protected function orderMedia($media)
|
||||
{
|
||||
$page = Grav::instance()['pages']->get($this->path);
|
||||
if (null === $this->media_order) {
|
||||
$page = Grav::instance()['pages']->get($this->path);
|
||||
|
||||
if ($page && isset($page->header()->media_order)) {
|
||||
$media_order = array_map('trim', explode(',', $page->header()->media_order));
|
||||
$media = Utils::sortArrayByArray($media, $media_order);
|
||||
if ($page && isset($page->header()->media_order)) {
|
||||
$this->media_order = array_map('trim', explode(',', $page->header()->media_order));
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($this->media_order) && is_array($this->media_order)) {
|
||||
$media = Utils::sortArrayByArray($media, $this->media_order);
|
||||
} else {
|
||||
ksort($media, SORT_NATURAL | SORT_FLAG_CASE);
|
||||
}
|
||||
|
||||
return $media;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Grav\Common\Page\Medium;
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Utils;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
class ImageMedium extends Medium
|
||||
{
|
||||
@@ -164,12 +165,18 @@ class ImageMedium extends Medium
|
||||
*/
|
||||
public function url($reset = true)
|
||||
{
|
||||
$image_path = Grav::instance()['locator']->findResource('cache://images', true);
|
||||
$image_dir = Grav::instance()['locator']->findResource('cache://images', false);
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
$image_path = $locator->findResource('cache://images', true);
|
||||
$image_dir = $locator->findResource('cache://images', false);
|
||||
$saved_image_path = $this->saveImage();
|
||||
|
||||
$output = preg_replace('|^' . preg_quote(GRAV_ROOT, '|') . '|', '', $saved_image_path);
|
||||
|
||||
if ($locator->isStream($output)) {
|
||||
$output = $locator->findResource($output, false);
|
||||
}
|
||||
|
||||
if (Utils::startsWith($output, $image_path)) {
|
||||
$output = '/' . $image_dir . preg_replace('|^' . preg_quote($image_path, '|') . '|', '', $output);
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Data\Data;
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Common\Media\Interfaces\MediaObjectInterface;
|
||||
|
||||
class Medium extends Data implements RenderableInterface
|
||||
class Medium extends Data implements RenderableInterface, MediaObjectInterface
|
||||
{
|
||||
use ParsedownHtmlTrait;
|
||||
|
||||
@@ -199,7 +199,12 @@ class Medium extends Data implements RenderableInterface
|
||||
*/
|
||||
public function url($reset = true)
|
||||
{
|
||||
$output = preg_replace('|^' . preg_quote(GRAV_ROOT) . '|', '', $this->get('filepath'));
|
||||
$output = preg_replace('|^' . preg_quote(GRAV_ROOT, '|') . '|', '', $this->get('filepath'));
|
||||
|
||||
$locator = Grav::instance()['locator'];
|
||||
if ($locator->isStream($output)) {
|
||||
$output = $locator->findResource($output, false);
|
||||
}
|
||||
|
||||
if ($reset) {
|
||||
$this->reset();
|
||||
|
||||
@@ -94,6 +94,40 @@ class VideoMedium extends Medium
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to set the playsinline attribute
|
||||
*
|
||||
* @param bool $status
|
||||
* @return $this
|
||||
*/
|
||||
public function playsinline($status = false)
|
||||
{
|
||||
if($status) {
|
||||
$this->attributes['playsinline'] = true;
|
||||
} else {
|
||||
unset($this->attributes['playsinline']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to set the muted attribute
|
||||
*
|
||||
* @param bool $status
|
||||
* @return $this
|
||||
*/
|
||||
public function muted($status = false)
|
||||
{
|
||||
if($status) {
|
||||
$this->attributes['muted'] = true;
|
||||
} else {
|
||||
unset($this->attributes['muted']);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset medium.
|
||||
*
|
||||
|
||||
@@ -12,11 +12,14 @@ use Exception;
|
||||
use Grav\Common\Cache;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Data\Blueprint;
|
||||
use Grav\Common\File\CompiledYamlFile;
|
||||
use Grav\Common\Filesystem\Folder;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Markdown\Parsedown;
|
||||
use Grav\Common\Markdown\ParsedownExtra;
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Media\Traits\MediaTrait;
|
||||
use Grav\Common\Taxonomy;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Utils;
|
||||
@@ -27,8 +30,10 @@ use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
define('PAGE_ORDER_PREFIX_REGEX', '/^[0-9]+\./u');
|
||||
|
||||
class Page
|
||||
class Page implements PageInterface
|
||||
{
|
||||
use MediaTrait;
|
||||
|
||||
/**
|
||||
* @var string Filename. Leave as null if page is folder.
|
||||
*/
|
||||
@@ -65,7 +70,6 @@ class Page
|
||||
protected $summary;
|
||||
protected $raw_content;
|
||||
protected $pagination;
|
||||
protected $media;
|
||||
protected $metadata;
|
||||
protected $title;
|
||||
protected $max_count;
|
||||
@@ -318,8 +322,6 @@ class Page
|
||||
if (!$this->header) {
|
||||
$file = $this->file();
|
||||
if ($file) {
|
||||
// Set some options
|
||||
$file->settings(['native' => true, 'compat' => true]);
|
||||
try {
|
||||
$this->raw_content = $file->markdown();
|
||||
$this->frontmatter = $file->frontmatter();
|
||||
@@ -328,11 +330,12 @@ class Page
|
||||
if (!Utils::isAdminPlugin()) {
|
||||
// If there's a `frontmatter.yaml` file merge that in with the page header
|
||||
// note page's own frontmatter has precedence and will overwrite any defaults
|
||||
$frontmatter_file = $this->path . '/' . $this->folder . '/frontmatter.yaml';
|
||||
if (file_exists($frontmatter_file)) {
|
||||
$frontmatter_data = (array)Yaml::parse(file_get_contents($frontmatter_file));
|
||||
$frontmatterFile = CompiledYamlFile::instance($this->path . '/' . $this->folder . '/frontmatter.yaml');
|
||||
if ($frontmatterFile->exists()) {
|
||||
$frontmatter_data = (array)$frontmatterFile->content();
|
||||
$this->header = (object)array_replace_recursive($frontmatter_data,
|
||||
(array)$this->header);
|
||||
$frontmatterFile->free();
|
||||
}
|
||||
// Process frontmatter with Twig if enabled
|
||||
if (Grav::instance()['config']->get('system.pages.frontmatter.process_twig') === true) {
|
||||
@@ -1124,6 +1127,14 @@ class Page
|
||||
return json_encode($this->toArray());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheKey()
|
||||
{
|
||||
return $this->id();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets and sets the associated media as found in the page folder.
|
||||
*
|
||||
@@ -1133,23 +1144,33 @@ class Page
|
||||
*/
|
||||
public function media($var = null)
|
||||
{
|
||||
/** @var Cache $cache */
|
||||
$cache = Grav::instance()['cache'];
|
||||
|
||||
if ($var) {
|
||||
$this->media = $var;
|
||||
}
|
||||
if ($this->media === null) {
|
||||
// Use cached media if possible.
|
||||
$media_cache_id = md5('media' . $this->id());
|
||||
if (!$media = $cache->fetch($media_cache_id)) {
|
||||
$media = new Media($this->path());
|
||||
$cache->save($media_cache_id, $media);
|
||||
}
|
||||
$this->media = $media;
|
||||
$this->setMedia($var);
|
||||
}
|
||||
|
||||
return $this->media;
|
||||
return $this->getMedia();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filesystem path to the associated media.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getMediaFolder()
|
||||
{
|
||||
return $this->path();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get display order for the associated media.
|
||||
*
|
||||
* @return array Empty array means default ordering.
|
||||
*/
|
||||
public function getMediaOrder()
|
||||
{
|
||||
$header = $this->header();
|
||||
|
||||
return isset($header->media_order) ? array_map('trim', explode(',', (string)$header->media_order)) : [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1628,14 +1649,19 @@ class Page
|
||||
* Gets the url for the Page.
|
||||
*
|
||||
* @param bool $include_host Defaults false, but true would include http://yourhost.com
|
||||
* @param bool $canonical true to return the canonical URL
|
||||
* @param bool $include_lang
|
||||
* @param bool $canonical True to return the canonical URL
|
||||
* @param bool $include_base Include base url on multisite as well as language code
|
||||
* @param bool $raw_route
|
||||
*
|
||||
* @return string The url.
|
||||
*/
|
||||
public function url($include_host = false, $canonical = false, $include_lang = true, $raw_route = false)
|
||||
public function url($include_host = false, $canonical = false, $include_base = true, $raw_route = false)
|
||||
{
|
||||
// Override any URL when external_url is set
|
||||
if (isset($this->external_url)) {
|
||||
return $this->external_url;
|
||||
}
|
||||
|
||||
$grav = Grav::instance();
|
||||
|
||||
/** @var Pages $pages */
|
||||
@@ -1644,41 +1670,25 @@ class Page
|
||||
/** @var Config $config */
|
||||
$config = $grav['config'];
|
||||
|
||||
/** @var Language $language */
|
||||
$language = $grav['language'];
|
||||
|
||||
/** @var Uri $uri */
|
||||
$uri = $grav['uri'];
|
||||
|
||||
// Override any URL when external_url is set
|
||||
if (isset($this->external_url)) {
|
||||
return $this->external_url;
|
||||
}
|
||||
|
||||
// get pre-route
|
||||
if ($include_lang && $language->enabled()) {
|
||||
$pre_route = $language->getLanguageURLPrefix();
|
||||
} else {
|
||||
$pre_route = '';
|
||||
}
|
||||
// get base route (multisite base and language)
|
||||
$route = $include_base ? $pages->baseRoute() : '';
|
||||
|
||||
// add full route if configured to do so
|
||||
if ($config->get('system.absolute_urls', false)) {
|
||||
if (!$include_host && $config->get('system.absolute_urls', false)) {
|
||||
$include_host = true;
|
||||
}
|
||||
|
||||
// get canonical route if requested
|
||||
if ($canonical) {
|
||||
$route = $pre_route . $this->routeCanonical();
|
||||
$route .= $this->routeCanonical();
|
||||
} elseif ($raw_route) {
|
||||
$route = $pre_route . $this->rawRoute();
|
||||
$route .= $this->rawRoute();
|
||||
} else {
|
||||
$route = $pre_route . $this->route();
|
||||
$route .= $this->route();
|
||||
}
|
||||
|
||||
$rootUrl = $uri->rootUrl($include_host) . $pages->base();
|
||||
|
||||
$url = $rootUrl . '/' . trim($route, '/') . $this->urlExtension();
|
||||
/** @var Uri $uri */
|
||||
$uri = $grav['uri'];
|
||||
$url = $uri->rootUrl($include_host) . '/' . trim($route, '/') . $this->urlExtension();
|
||||
|
||||
// trim trailing / if not root
|
||||
if ($url !== '/') {
|
||||
|
||||
@@ -49,7 +49,7 @@ class Pages
|
||||
/**
|
||||
* @var array|string[]
|
||||
*/
|
||||
protected $baseUrl = [];
|
||||
protected $baseRoute = [];
|
||||
|
||||
/**
|
||||
* @var array|string[]
|
||||
@@ -120,47 +120,69 @@ class Pages
|
||||
if ($path !== null) {
|
||||
$path = trim($path, '/');
|
||||
$this->base = $path ? '/' . $path : null;
|
||||
$this->baseUrl = [];
|
||||
$this->baseRoute = [];
|
||||
}
|
||||
|
||||
return $this->base;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get base route for Grav pages.
|
||||
*
|
||||
* @param string $lang Optional language code for multilingual routes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function baseRoute($lang = null)
|
||||
{
|
||||
$key = $lang ?: 'default';
|
||||
|
||||
if (!isset($this->baseRoute[$key])) {
|
||||
/** @var Language $language */
|
||||
$language = $this->grav['language'];
|
||||
|
||||
$path_base = rtrim($this->base(), '/');
|
||||
$path_lang = $language->enabled() ? $language->getLanguageURLPrefix($lang) : '';
|
||||
|
||||
$this->baseRoute[$key] = $path_base . $path_lang;
|
||||
}
|
||||
|
||||
return $this->baseRoute[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get route for Grav site.
|
||||
*
|
||||
* @param string $route Optional route to the page.
|
||||
* @param string $lang Optional language code for multilingual links.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function route($route = '/', $lang = null)
|
||||
{
|
||||
if (!$route || $route === '/') {
|
||||
return $this->baseRoute($lang) ?: '/';
|
||||
}
|
||||
|
||||
return $this->baseRoute($lang) . $route;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Get base URL for Grav pages.
|
||||
*
|
||||
* @param string $lang Optional language code for multilingual links.
|
||||
* @param bool $absolute If true, return absolute url, if false, return relative url. Otherwise return default.
|
||||
* @param string $lang Optional language code for multilingual links.
|
||||
* @param bool|null $absolute If true, return absolute url, if false, return relative url. Otherwise return default.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function baseUrl($lang = null, $absolute = null)
|
||||
{
|
||||
$lang = (string) $lang;
|
||||
$type = $absolute === null ? 'base_url' : ($absolute ? 'base_url_absolute' : 'base_url_relative');
|
||||
$key = "{$lang} {$type}";
|
||||
|
||||
if (!isset($this->baseUrl[$key])) {
|
||||
/** @var Config $config */
|
||||
$config = $this->grav['config'];
|
||||
|
||||
/** @var Language $language */
|
||||
$language = $this->grav['language'];
|
||||
|
||||
if (!$lang) {
|
||||
$lang = $language->getActive();
|
||||
}
|
||||
|
||||
$path_append = rtrim($this->grav['pages']->base(), '/');
|
||||
if ($language->getDefault() !== $lang || $config->get('system.languages.include_default_lang') === true) {
|
||||
$path_append .= $lang ? '/' . $lang : '';
|
||||
}
|
||||
|
||||
$this->baseUrl[$key] = $this->grav[$type] . $path_append;
|
||||
}
|
||||
|
||||
return $this->baseUrl[$key];
|
||||
return $this->grav[$type] . $this->baseRoute($lang);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,7 +201,7 @@ class Pages
|
||||
|
||||
/**
|
||||
*
|
||||
* Get home URL for Grav site.
|
||||
* Get URL for Grav site.
|
||||
*
|
||||
* @param string $route Optional route to the page.
|
||||
* @param string $lang Optional language code for multilingual links.
|
||||
@@ -189,7 +211,7 @@ class Pages
|
||||
*/
|
||||
public function url($route = '/', $lang = null, $absolute = null)
|
||||
{
|
||||
if ($route === '/') {
|
||||
if (!$route || $route === '/') {
|
||||
return $this->homeUrl($lang, $absolute);
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
|
||||
namespace Grav\Common\Processors;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Utils;
|
||||
|
||||
class InitializeProcessor extends ProcessorBase implements ProcessorInterface
|
||||
{
|
||||
public $id = 'init';
|
||||
@@ -15,29 +19,36 @@ class InitializeProcessor extends ProcessorBase implements ProcessorInterface
|
||||
|
||||
public function process()
|
||||
{
|
||||
$this->container['config']->debug();
|
||||
/** @var Config $config */
|
||||
$config = $this->container['config'];
|
||||
$config->debug();
|
||||
|
||||
// Use output buffering to prevent headers from being sent too early.
|
||||
ob_start();
|
||||
if ($this->container['config']->get('system.cache.gzip')) {
|
||||
if ($config->get('system.cache.gzip') && !@ob_start('ob_gzhandler')) {
|
||||
// Enable zip/deflate with a fallback in case of if browser does not support compressing.
|
||||
if (!@ob_start("ob_gzhandler")) {
|
||||
ob_start();
|
||||
}
|
||||
ob_start();
|
||||
}
|
||||
|
||||
// Initialize the timezone.
|
||||
if ($this->container['config']->get('system.timezone')) {
|
||||
if ($config->get('system.timezone')) {
|
||||
date_default_timezone_set($this->container['config']->get('system.timezone'));
|
||||
}
|
||||
|
||||
// FIXME: Initialize session should happen later after plugins have been loaded. This is a workaround to fix session issues in AWS.
|
||||
if ($this->container['config']->get('system.session.initialize', 1) && isset($this->container['session'])) {
|
||||
if (isset($this->container['session']) && $config->get('system.session.initialize', true)) {
|
||||
$this->container['session']->init();
|
||||
}
|
||||
|
||||
// Initialize uri.
|
||||
$this->container['uri']->init();
|
||||
/** @var Uri $uri */
|
||||
$uri = $this->container['uri'];
|
||||
$uri->init();
|
||||
|
||||
// Redirect pages with trailing slash if configured to do so.
|
||||
$path = $uri->path() ?: '/';
|
||||
if ($path !== '/' && $config->get('system.pages.redirect_trailing_slash', false) && Utils::endsWith($path, '/')) {
|
||||
$this->container->redirect(rtrim($path, '/'), 302);
|
||||
}
|
||||
|
||||
$this->container->setLocale();
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ use Grav\Common\Config\ConfigFileFinder;
|
||||
use Grav\Common\Config\Setup;
|
||||
use Pimple\Container;
|
||||
use Pimple\ServiceProviderInterface;
|
||||
use RocketTheme\Toolbox\File\YamlFile;
|
||||
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
|
||||
|
||||
class ConfigServiceProvider implements ServiceProviderInterface
|
||||
@@ -31,7 +32,14 @@ class ConfigServiceProvider implements ServiceProviderInterface
|
||||
};
|
||||
|
||||
$container['config'] = function ($c) {
|
||||
return static::load($c);
|
||||
$config = static::load($c);
|
||||
|
||||
// After configuration has been loaded, we can disable YAML compatibility if strict mode has been enabled.
|
||||
if (!$config->get('system.strict_mode.yaml_compat', true)) {
|
||||
YamlFile::globalSettings(['compat' => false, 'native' => true]);
|
||||
}
|
||||
|
||||
return $config;
|
||||
};
|
||||
|
||||
$container['languages'] = function ($c) {
|
||||
@@ -65,6 +73,10 @@ class ConfigServiceProvider implements ServiceProviderInterface
|
||||
return $blueprints->name("master-{$setup->environment}")->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Container $container
|
||||
* @return Config
|
||||
*/
|
||||
public static function load(Container $container)
|
||||
{
|
||||
/** Setup $setup */
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
namespace Grav\Common\Service;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Page\Page;
|
||||
@@ -26,35 +27,33 @@ class PageServiceProvider implements ServiceProviderInterface
|
||||
/** @var Pages $pages */
|
||||
$pages = $c['pages'];
|
||||
|
||||
/** @var Config $config */
|
||||
$config = $c['config'];
|
||||
|
||||
/** @var Uri $uri */
|
||||
$uri = $c['uri'];
|
||||
|
||||
$path = $uri->path(); // Don't trim to support trailing slash default routes
|
||||
$path = $path ?: '/';
|
||||
|
||||
$path = $uri->path() ?: '/'; // Don't trim to support trailing slash default routes
|
||||
$page = $pages->dispatch($path);
|
||||
|
||||
// Redirection tests
|
||||
if ($page) {
|
||||
/** @var Language $language */
|
||||
$language = $c['language'];
|
||||
|
||||
// some debugger override logic
|
||||
if ($page->debugger() === false) {
|
||||
$c['debugger']->enabled(false);
|
||||
}
|
||||
|
||||
if ($c['config']->get('system.force_ssl')) {
|
||||
if (!isset($_SERVER['HTTPS']) || $_SERVER["HTTPS"] != "on") {
|
||||
$url = "https://" . $_SERVER["HTTP_HOST"] . $_SERVER["REQUEST_URI"];
|
||||
if ($config->get('system.force_ssl')) {
|
||||
if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
|
||||
$url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
|
||||
$c->redirect($url);
|
||||
}
|
||||
}
|
||||
|
||||
$url = $page->route();
|
||||
$url = $pages->route($page->route());
|
||||
|
||||
if ($uri->params()) {
|
||||
if ($url == '/') { //Avoid double slash
|
||||
if ($url === '/') { //Avoid double slash
|
||||
$url = $uri->params();
|
||||
} else {
|
||||
$url .= $uri->params();
|
||||
@@ -67,18 +66,16 @@ class PageServiceProvider implements ServiceProviderInterface
|
||||
$url .= '#' . $uri->fragment();
|
||||
}
|
||||
|
||||
/** @var Language $language */
|
||||
$language = $c['language'];
|
||||
|
||||
// Language-specific redirection scenarios
|
||||
if ($language->enabled()) {
|
||||
if ($language->isLanguageInUrl() && !$language->isIncludeDefaultLanguage()) {
|
||||
$c->redirect($url);
|
||||
}
|
||||
if (!$language->isLanguageInUrl() && $language->isIncludeDefaultLanguage()) {
|
||||
$c->redirectLangSafe($url);
|
||||
}
|
||||
if ($language->enabled() && ($language->isLanguageInUrl() xor $language->isIncludeDefaultLanguage())) {
|
||||
$c->redirect($url);
|
||||
}
|
||||
// Default route test and redirect
|
||||
if ($c['config']->get('system.pages.redirect_default_route') && $page->route() != $path) {
|
||||
$c->redirectLangSafe($url);
|
||||
if ($config->get('system.pages.redirect_default_route') && $page->route() !== $path) {
|
||||
$c->redirect($url);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,21 +29,22 @@ class SessionServiceProvider implements ServiceProviderInterface
|
||||
/** @var Uri $uri */
|
||||
$uri = $c['uri'];
|
||||
|
||||
// Get session parameters.
|
||||
$session_timeout = (int)$config->get('system.session.timeout', 1800);
|
||||
$session_path = $config->get('system.session.path');
|
||||
if (null === $session_path) {
|
||||
$session_path = '/' . ltrim(Uri::filterPath($uri->rootUrl(false)), '/');
|
||||
}
|
||||
$domain = $uri->host();
|
||||
if ($domain === 'localhost') {
|
||||
$domain = '';
|
||||
}
|
||||
|
||||
// Get session options.
|
||||
$secure = (bool)$config->get('system.session.secure', false);
|
||||
$httponly = (bool)$config->get('system.session.httponly', true);
|
||||
$enabled = (bool)$config->get('system.session.enabled', false);
|
||||
$cookie_secure = (bool)$config->get('system.session.secure', false);
|
||||
$cookie_httponly = (bool)$config->get('system.session.httponly', true);
|
||||
$cookie_lifetime = (int)$config->get('system.session.timeout', 1800);
|
||||
$cookie_path = $config->get('system.session.path');
|
||||
if (null === $cookie_path) {
|
||||
$cookie_path = '/' . trim(Uri::filterPath($uri->rootUrl(false)), '/');
|
||||
}
|
||||
// Session cookie path requires trailing slash.
|
||||
$cookie_path = rtrim($cookie_path, '/') . '/';
|
||||
|
||||
$cookie_domain = $uri->host();
|
||||
if ($cookie_domain === 'localhost') {
|
||||
$cookie_domain = '';
|
||||
}
|
||||
|
||||
// Activate admin if we're inside the admin path.
|
||||
$is_admin = false;
|
||||
@@ -56,14 +57,14 @@ class SessionServiceProvider implements ServiceProviderInterface
|
||||
// Check no language, simple language prefix (en) and region specific language prefix (en-US).
|
||||
$pos = strpos($current_route, $base);
|
||||
if ($pos === 0 || $pos === 3 || $pos === 6) {
|
||||
$session_timeout = $config->get('plugins.admin.session.timeout', 1800);
|
||||
$cookie_lifetime = $config->get('plugins.admin.session.timeout', 1800);
|
||||
$enabled = $is_admin = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Fix for HUGE session timeouts.
|
||||
if ($session_timeout > 99999999999) {
|
||||
$session_timeout = 9999999999;
|
||||
if ($cookie_lifetime > 99999999999) {
|
||||
$cookie_lifetime = 9999999999;
|
||||
}
|
||||
|
||||
$inflector = new Inflector();
|
||||
@@ -73,10 +74,16 @@ class SessionServiceProvider implements ServiceProviderInterface
|
||||
}
|
||||
|
||||
// Define session service.
|
||||
$session = new Session($session_timeout, $session_path, $domain);
|
||||
$session->setName($session_name);
|
||||
$session->setSecure($secure);
|
||||
$session->setHttpOnly($httponly);
|
||||
$options = [
|
||||
'name' => $session_name,
|
||||
'cookie_lifetime' => $cookie_lifetime,
|
||||
'cookie_path' => $cookie_path,
|
||||
'cookie_domain' => $cookie_domain,
|
||||
'cookie_secure' => $cookie_secure,
|
||||
'cookie_httponly' => $cookie_httponly
|
||||
] + (array) $config->get('system.session.options');
|
||||
|
||||
$session = new Session($options);
|
||||
$session->setAutoStart($enabled);
|
||||
|
||||
return $session;
|
||||
|
||||
@@ -8,34 +8,18 @@
|
||||
|
||||
namespace Grav\Common;
|
||||
|
||||
use RocketTheme\Toolbox\Session\Session as BaseSession;
|
||||
|
||||
class Session extends BaseSession
|
||||
class Session extends \Grav\Framework\Session\Session
|
||||
{
|
||||
/** @var bool */
|
||||
protected $autoStart = false;
|
||||
|
||||
protected $lifetime;
|
||||
protected $path;
|
||||
protected $domain;
|
||||
protected $secure;
|
||||
protected $httpOnly;
|
||||
|
||||
/**
|
||||
* @param int $lifetime Defaults to 1800 seconds.
|
||||
* @param string $path Cookie path.
|
||||
* @param string $domain Optional, domain for the session
|
||||
* @throws \RuntimeException
|
||||
* @return \Grav\Framework\Session\Session
|
||||
* @deprecated 1.5
|
||||
*/
|
||||
public function __construct($lifetime, $path, $domain = null)
|
||||
public static function instance()
|
||||
{
|
||||
$this->lifetime = $lifetime;
|
||||
$this->path = $path;
|
||||
$this->domain = $domain;
|
||||
|
||||
if (php_sapi_name() !== 'cli') {
|
||||
parent::__construct($lifetime, $path, $domain);
|
||||
}
|
||||
return static::getInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -48,9 +32,6 @@ class Session extends BaseSession
|
||||
if ($this->autoStart) {
|
||||
$this->start();
|
||||
|
||||
// TODO: This setcookie shouldn't be here, session should by itself be able to update its cookie.
|
||||
setcookie(session_name(), session_id(), $this->lifetime ? time() + $this->lifetime : 0, $this->path, $this->domain, $this->secure, $this->httpOnly);
|
||||
|
||||
$this->autoStart = false;
|
||||
}
|
||||
}
|
||||
@@ -67,27 +48,25 @@ class Session extends BaseSession
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $secure
|
||||
* @return $this
|
||||
* Returns attributes.
|
||||
*
|
||||
* @return array Attributes
|
||||
* @deprecated 1.5
|
||||
*/
|
||||
public function setSecure($secure)
|
||||
public function all()
|
||||
{
|
||||
$this->secure = $secure;
|
||||
ini_set('session.cookie_secure', (bool)$secure);
|
||||
|
||||
return $this;
|
||||
return $this->getAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $httpOnly
|
||||
* @return $this
|
||||
* Checks if the session was started.
|
||||
*
|
||||
* @return Boolean
|
||||
* @deprecated 1.5
|
||||
*/
|
||||
public function setHttpOnly($httpOnly)
|
||||
public function started()
|
||||
{
|
||||
$this->httpOnly = $httpOnly;
|
||||
ini_set('session.cookie_httponly', (bool)$httpOnly);
|
||||
|
||||
return $this;
|
||||
return $this->isStarted();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -12,7 +12,7 @@ class TwigNodeMarkdown extends \Twig_Node implements \Twig_NodeOutputInterface
|
||||
{
|
||||
public function __construct(\Twig_Node $body, $lineno, $tag = 'markdown')
|
||||
{
|
||||
parent::__construct(array('body' => $body), array(), $lineno, $tag);
|
||||
parent::__construct(['body' => $body], [], $lineno, $tag);
|
||||
}
|
||||
/**
|
||||
* Compiles the node to PHP.
|
||||
|
||||
@@ -24,20 +24,17 @@ class TwigNodeSwitch extends \Twig_Node implements \Twig_NodeOutputInterface
|
||||
{
|
||||
$compiler
|
||||
->addDebugInfo($this)
|
||||
->write("switch (")
|
||||
->write('switch (')
|
||||
->subcompile($this->getNode('value'))
|
||||
->raw(") {\n")
|
||||
->indent();
|
||||
|
||||
foreach ($this->getNode('cases') as $case)
|
||||
{
|
||||
if (!$case->hasNode('body'))
|
||||
{
|
||||
foreach ($this->getNode('cases') as $case) {
|
||||
if (!$case->hasNode('body')) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($case->getNode('values') as $value)
|
||||
{
|
||||
foreach ($case->getNode('values') as $value) {
|
||||
$compiler
|
||||
->write('case ')
|
||||
->subcompile($value)
|
||||
@@ -53,8 +50,7 @@ class TwigNodeSwitch extends \Twig_Node implements \Twig_NodeOutputInterface
|
||||
->write("}\n");
|
||||
}
|
||||
|
||||
if ($this->hasNode('default') && $this->getNode('default') !== null)
|
||||
{
|
||||
if ($this->hasNode('default') && $this->getNode('default') !== null) {
|
||||
$compiler
|
||||
->write("default:\n")
|
||||
->write("{\n")
|
||||
|
||||
@@ -37,8 +37,7 @@ class TwigTokenParserSwitch extends \Twig_TokenParser
|
||||
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
|
||||
|
||||
// There can be some whitespace between the {% switch %} and first {% case %} tag.
|
||||
while ($stream->getCurrent()->getType() == \Twig_Token::TEXT_TYPE && trim($stream->getCurrent()->getValue()) == '')
|
||||
{
|
||||
while ($stream->getCurrent()->getType() === \Twig_Token::TEXT_TYPE && trim($stream->getCurrent()->getValue()) === '') {
|
||||
$stream->next();
|
||||
}
|
||||
|
||||
@@ -47,56 +46,45 @@ class TwigTokenParserSwitch extends \Twig_TokenParser
|
||||
$expressionParser = $this->parser->getExpressionParser();
|
||||
|
||||
$default = null;
|
||||
$cases = array();
|
||||
$cases = [];
|
||||
$end = false;
|
||||
|
||||
while (!$end)
|
||||
{
|
||||
while (!$end) {
|
||||
$next = $stream->next();
|
||||
|
||||
switch ($next->getValue())
|
||||
{
|
||||
switch ($next->getValue()) {
|
||||
case 'case':
|
||||
{
|
||||
$values = array();
|
||||
$values = [];
|
||||
|
||||
while (true)
|
||||
{
|
||||
$values[] = $expressionParser->parsePrimaryExpression();
|
||||
// Multiple allowed values?
|
||||
if ($stream->test(\Twig_Token::OPERATOR_TYPE, 'or'))
|
||||
{
|
||||
$stream->next();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
while (true) {
|
||||
$values[] = $expressionParser->parsePrimaryExpression();
|
||||
// Multiple allowed values?
|
||||
if ($stream->test(\Twig_Token::OPERATOR_TYPE, 'or')) {
|
||||
$stream->next();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
|
||||
$body = $this->parser->subparse(array($this, 'decideIfFork'));
|
||||
$cases[] = new \Twig_Node([
|
||||
'values' => new \Twig_Node($values),
|
||||
'body' => $body
|
||||
]);
|
||||
break;
|
||||
|
||||
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
|
||||
$body = $this->parser->subparse(array($this, 'decideIfFork'));
|
||||
$cases[] = new \Twig_Node(array(
|
||||
'values' => new \Twig_Node($values),
|
||||
'body' => $body
|
||||
));
|
||||
break;
|
||||
}
|
||||
case 'default':
|
||||
{
|
||||
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
|
||||
$default = $this->parser->subparse(array($this, 'decideIfEnd'));
|
||||
break;
|
||||
}
|
||||
$stream->expect(\Twig_Token::BLOCK_END_TYPE);
|
||||
$default = $this->parser->subparse(array($this, 'decideIfEnd'));
|
||||
break;
|
||||
|
||||
case 'endswitch':
|
||||
{
|
||||
$end = true;
|
||||
break;
|
||||
}
|
||||
$end = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
throw new \Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "case", "default", or "endswitch" to close the "switch" block started at line %d)', $lineno), -1);
|
||||
}
|
||||
throw new \Twig_Error_Syntax(sprintf('Unexpected end of template. Twig was looking for the following tags "case", "default", or "endswitch" to close the "switch" block started at line %d)', $lineno), -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +115,6 @@ class TwigTokenParserSwitch extends \Twig_TokenParser
|
||||
return $token->test(array('endswitch'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
||||
@@ -113,7 +113,10 @@ class Twig
|
||||
$params['cache'] = new \Twig_Cache_Filesystem($cachePath, \Twig_Cache_Filesystem::FORCE_BYTECODE_INVALIDATION);
|
||||
}
|
||||
|
||||
if (!empty($this->autoescape)) {
|
||||
if (!$config->get('system.strict_mode.twig_compat', true)) {
|
||||
// Force autoescape on for all files if in strict mode.
|
||||
$params['autoescape'] = true;
|
||||
} elseif (!empty($this->autoescape)) {
|
||||
$params['autoescape'] = $this->autoescape;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
new \Twig_SimpleFilter('fieldName', [$this, 'fieldNameFilter']),
|
||||
new \Twig_SimpleFilter('ksort', [$this, 'ksortFilter']),
|
||||
new \Twig_SimpleFilter('ltrim', [$this, 'ltrimFilter']),
|
||||
new \Twig_SimpleFilter('markdown', [$this, 'markdownFunction']),
|
||||
new \Twig_SimpleFilter('markdown', [$this, 'markdownFunction'], ['is_safe' => ['html']]),
|
||||
new \Twig_SimpleFilter('md5', [$this, 'md5Filter']),
|
||||
new \Twig_SimpleFilter('base32_encode', [$this, 'base32EncodeFilter']),
|
||||
new \Twig_SimpleFilter('base32_decode', [$this, 'base32DecodeFilter']),
|
||||
@@ -88,9 +88,6 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
new \Twig_SimpleFilter('safe_truncate_html', ['\Grav\Common\Utils', 'safeTruncateHTML']),
|
||||
new \Twig_SimpleFilter('sort_by_key', [$this, 'sortByKeyFilter']),
|
||||
new \Twig_SimpleFilter('starts_with', [$this, 'startsWithFilter']),
|
||||
new \Twig_SimpleFilter('t', [$this, 'translate']),
|
||||
new \Twig_SimpleFilter('tl', [$this, 'translateLanguage']),
|
||||
new \Twig_SimpleFilter('ta', [$this, 'translateArray']),
|
||||
new \Twig_SimpleFilter('truncate', ['\Grav\Common\Utils', 'truncate']),
|
||||
new \Twig_SimpleFilter('truncate_html', ['\Grav\Common\Utils', 'truncateHTML']),
|
||||
new \Twig_SimpleFilter('json_decode', [$this, 'jsonDecodeFilter']),
|
||||
@@ -100,6 +97,18 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
new \Twig_SimpleFilter('print_r', 'print_r'),
|
||||
new \Twig_SimpleFilter('yaml_encode', [$this, 'yamlEncodeFilter']),
|
||||
new \Twig_SimpleFilter('yaml_decode', [$this, 'yamlDecodeFilter']),
|
||||
|
||||
// Translations
|
||||
new \Twig_SimpleFilter('t', [$this, 'translate']),
|
||||
new \Twig_SimpleFilter('tl', [$this, 'translateLanguage']),
|
||||
new \Twig_SimpleFilter('ta', [$this, 'translateArray']),
|
||||
|
||||
// Casting values
|
||||
new \Twig_SimpleFilter('string', [$this, 'stringFilter']),
|
||||
new \Twig_SimpleFilter('int', [$this, 'intFilter'], ['is_safe' => true]),
|
||||
new \Twig_SimpleFilter('bool', [$this, 'boolFilter']),
|
||||
new \Twig_SimpleFilter('float', [$this, 'floatFilter'], ['is_safe' => true]),
|
||||
new \Twig_SimpleFilter('array', [$this, 'arrayFilter']),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -111,7 +120,7 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
public function getFunctions()
|
||||
{
|
||||
return [
|
||||
new \Twig_SimpleFunction('array', [$this, 'arrayFunc']),
|
||||
new \Twig_SimpleFunction('array', [$this, 'arrayFilter']),
|
||||
new \Twig_SimpleFunction('array_key_value', [$this, 'arrayKeyValueFunc']),
|
||||
new \Twig_SimpleFunction('array_key_exists', 'array_key_exists'),
|
||||
new \Twig_SimpleFunction('array_unique', 'array_unique'),
|
||||
@@ -132,9 +141,6 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
new \Twig_SimpleFunction('regex_replace', [$this, 'regexReplace']),
|
||||
new \Twig_SimpleFunction('regex_filter', [$this, 'regexFilter']),
|
||||
new \Twig_SimpleFunction('string', [$this, 'stringFunc']),
|
||||
new \Twig_simpleFunction('t', [$this, 'translate']),
|
||||
new \Twig_simpleFunction('tl', [$this, 'translateLanguage']),
|
||||
new \Twig_simpleFunction('ta', [$this, 'translateArray']),
|
||||
new \Twig_SimpleFunction('url', [$this, 'urlFunc']),
|
||||
new \Twig_SimpleFunction('json_decode', [$this, 'jsonDecodeFilter']),
|
||||
new \Twig_SimpleFunction('get_cookie', [$this, 'getCookie']),
|
||||
@@ -151,6 +157,10 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
new \Twig_SimpleFunction('nicefilesize', [$this, 'niceFilesizeFunc']),
|
||||
new \Twig_SimpleFunction('nicetime', [$this, 'nicetimeFilter']),
|
||||
|
||||
// Translations
|
||||
new \Twig_simpleFunction('t', [$this, 'translate']),
|
||||
new \Twig_simpleFunction('tl', [$this, 'translateLanguage']),
|
||||
new \Twig_simpleFunction('ta', [$this, 'translateArray']),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -617,6 +627,62 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
return ltrim($value, $chars);
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts input to string.
|
||||
*
|
||||
* @param mixed $input
|
||||
* @return string
|
||||
*/
|
||||
public function stringFilter($input)
|
||||
{
|
||||
return (string) $input;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Casts input to int.
|
||||
*
|
||||
* @param mixed $input
|
||||
* @return int
|
||||
*/
|
||||
public function intFilter($input)
|
||||
{
|
||||
return (int) $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts input to bool.
|
||||
*
|
||||
* @param mixed $input
|
||||
* @return bool
|
||||
*/
|
||||
public function boolFilter($input)
|
||||
{
|
||||
return (bool) $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts input to float.
|
||||
*
|
||||
* @param mixed $input
|
||||
* @return float
|
||||
*/
|
||||
public function floatFilter($input)
|
||||
{
|
||||
return (float) $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Casts input to array.
|
||||
*
|
||||
* @param mixed $input
|
||||
* @return array
|
||||
*/
|
||||
public function arrayFilter($input)
|
||||
{
|
||||
return (array) $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
@@ -693,7 +759,6 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
|
||||
$template = $env->createTemplate($twig);
|
||||
return $template->render($context);
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -748,7 +813,7 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
* Output a Gist
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $file
|
||||
* @param string|bool $file
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -788,19 +853,6 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
return str_pad($input, (int)$pad_length, $pad_string, $pad_type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cast a value to array
|
||||
*
|
||||
* @param $value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function arrayFunc($value)
|
||||
{
|
||||
return (array)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Workaround for twig associative array initialization
|
||||
* Returns a key => val array
|
||||
@@ -976,7 +1028,7 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
public function redirectFunc($url, $statusCode = 303)
|
||||
{
|
||||
header('Location: ' . $url, true, $statusCode);
|
||||
die();
|
||||
exit();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1060,7 +1112,7 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
|
||||
if (file_exists($filepath)) {
|
||||
return file_get_contents($filepath);
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Grav\Common;
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Language\Language;
|
||||
use Grav\Common\Page\Page;
|
||||
use Grav\Common\Page\Pages;
|
||||
use Grav\Framework\Route\RouteFactory;
|
||||
use Grav\Framework\Uri\UriFactory;
|
||||
use Grav\Framework\Uri\UriPartsFilter;
|
||||
@@ -156,12 +157,6 @@ class Uri
|
||||
$uri = preg_replace('|^' . preg_quote($setup_base, '|') . '|', '', $uri);
|
||||
}
|
||||
|
||||
// If configured to, redirect trailing slash URI's with a 302 redirect
|
||||
$redirect = str_replace($this->root, '', rtrim($uri, '/'));
|
||||
if ($redirect && $uri !== '/' && $redirect !== $this->base() && $config->get('system.pages.redirect_trailing_slash', false) && Utils::endsWith($uri, '/')) {
|
||||
$grav->redirect($redirect, 302);
|
||||
}
|
||||
|
||||
// process params
|
||||
$uri = $this->processParams($uri, $config->get('system.param_sep'));
|
||||
|
||||
@@ -206,9 +201,9 @@ class Uri
|
||||
}
|
||||
|
||||
// Set some Grav stuff
|
||||
$grav['base_url_absolute'] = $grav['config']->get('system.custom_base_url') ?: $this->rootUrl(true);
|
||||
$grav['base_url_absolute'] = $config->get('system.custom_base_url') ?: $this->rootUrl(true);
|
||||
$grav['base_url_relative'] = $this->rootUrl(false);
|
||||
$grav['base_url'] = $grav['config']->get('system.absolute_urls') ? $grav['base_url_absolute'] : $grav['base_url_relative'];
|
||||
$grav['base_url'] = $config->get('system.absolute_urls') ? $grav['base_url_absolute'] : $grav['base_url_relative'];
|
||||
|
||||
RouteFactory::setRoot($this->root_path);
|
||||
RouteFactory::setLanguage($language->getLanguageURLPrefix());
|
||||
@@ -376,6 +371,17 @@ class Uri
|
||||
return $this->extension;
|
||||
}
|
||||
|
||||
public function method()
|
||||
{
|
||||
$method = isset($_SERVER['REQUEST_METHOD']) ? strtoupper($_SERVER['REQUEST_METHOD']) : 'GET';
|
||||
|
||||
if ($method === 'POST' && isset($_SERVER['X-HTTP-METHOD-OVERRIDE'])) {
|
||||
$method = strtoupper($_SERVER['X-HTTP-METHOD-OVERRIDE']);
|
||||
}
|
||||
|
||||
return $method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the scheme of the URI
|
||||
*
|
||||
@@ -481,11 +487,9 @@ class Uri
|
||||
{
|
||||
if ($include_root) {
|
||||
return $this->uri;
|
||||
} else {
|
||||
$uri = str_replace($this->root_path, '', $this->uri);
|
||||
return $uri;
|
||||
}
|
||||
|
||||
return str_replace($this->root_path, '', $this->uri);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -508,16 +512,10 @@ class Uri
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
|
||||
// Link processing should prepend language
|
||||
$language = $grav['language'];
|
||||
$language_append = '';
|
||||
if ($language->enabled()) {
|
||||
$language_append = $language->getLanguageURLPrefix();
|
||||
}
|
||||
/** @var Pages $pages */
|
||||
$pages = $grav['pages'];
|
||||
|
||||
$base = $grav['base_url_relative'];
|
||||
|
||||
return rtrim($base . $grav['pages']->base(), '/') . $language_append;
|
||||
return $pages->baseUrl(null, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -633,10 +631,9 @@ class Uri
|
||||
}
|
||||
|
||||
return $ip;
|
||||
|
||||
}
|
||||
/**
|
||||
|
||||
/**
|
||||
* Returns current Uri.
|
||||
*
|
||||
* @return \Grav\Framework\Uri\Uri
|
||||
@@ -883,7 +880,26 @@ class Uri
|
||||
public static function parseUrl($url)
|
||||
{
|
||||
$grav = Grav::instance();
|
||||
$parts = parse_url($url);
|
||||
|
||||
$encodedUrl = preg_replace_callback(
|
||||
'%[^:/@?&=#]+%usD',
|
||||
function ($matches) { return rawurlencode($matches[0]); },
|
||||
$url
|
||||
);
|
||||
|
||||
$parts = parse_url($encodedUrl);
|
||||
|
||||
if (false === $parts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
foreach($parts as $name => $value) {
|
||||
$parts[$name] = rawurldecode($value);
|
||||
}
|
||||
|
||||
if (!isset($parts['path'])) {
|
||||
$parts['path'] = '';
|
||||
}
|
||||
|
||||
list($stripped_path, $params) = static::extractParams($parts['path'], $grav['config']->get('system.param_sep'));
|
||||
|
||||
@@ -1262,7 +1278,7 @@ class Uri
|
||||
{
|
||||
if (!$this->post) {
|
||||
$content_type = $this->getContentType();
|
||||
if ($content_type == 'application/json') {
|
||||
if ($content_type === 'application/json') {
|
||||
$json = file_get_contents('php://input');
|
||||
$this->post = json_decode($json, true);
|
||||
} elseif (!empty($_POST)) {
|
||||
@@ -1270,7 +1286,7 @@ class Uri
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->post && !is_null($element)) {
|
||||
if ($this->post && null !== $element) {
|
||||
$item = Utils::getDotNotation($this->post, $element);
|
||||
if ($filter_type) {
|
||||
$item = filter_var($item, $filter_type);
|
||||
|
||||
@@ -45,8 +45,20 @@ abstract class Utils
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
|
||||
// Get relative path to the resource (or false if not found).
|
||||
$resource = $locator->findResource($input, false);
|
||||
$parts = Uri::parseUrl($input);
|
||||
|
||||
if ($parts) {
|
||||
$resource = $locator->findResource("{$parts['scheme']}://{$parts['host']}{$parts['path']}", false);
|
||||
|
||||
if (isset($parts['query'])) {
|
||||
$resource = $resource . '?' . $parts['query'];
|
||||
}
|
||||
} else {
|
||||
// Not a valid URL (can still be a stream).
|
||||
$resource = $locator->findResource($input, false);
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
$resource = $input;
|
||||
}
|
||||
@@ -262,7 +274,7 @@ abstract class Utils
|
||||
// is $break present between $limit and the end of the string?
|
||||
if ($up_to_break && false !== ($breakpoint = mb_strpos($string, $break, $limit))) {
|
||||
if ($breakpoint < mb_strlen($string) - 1) {
|
||||
$string = mb_substr($string, 0, $breakpoint) . $break;
|
||||
$string = mb_substr($string, 0, $breakpoint) . $pad;
|
||||
}
|
||||
} else {
|
||||
$string = mb_substr($string, 0, $limit) . $pad;
|
||||
@@ -705,11 +717,11 @@ abstract class Utils
|
||||
* with reverse proxy setups.
|
||||
*
|
||||
* @param string $action
|
||||
* @param bool $plusOneTick if true, generates the token for the next tick (the next 12 hours)
|
||||
* @param bool $previousTick if true, generates the token for the previous tick (the previous 12 hours)
|
||||
*
|
||||
* @return string the nonce string
|
||||
*/
|
||||
private static function generateNonceString($action, $plusOneTick = false)
|
||||
private static function generateNonceString($action, $previousTick = false)
|
||||
{
|
||||
$username = '';
|
||||
if (isset(Grav::instance()['user'])) {
|
||||
@@ -720,29 +732,8 @@ abstract class Utils
|
||||
$token = session_id();
|
||||
$i = self::nonceTick();
|
||||
|
||||
if ($plusOneTick) {
|
||||
$i++;
|
||||
}
|
||||
|
||||
return ($i . '|' . $action . '|' . $username . '|' . $token . '|' . Grav::instance()['config']->get('security.salt'));
|
||||
}
|
||||
|
||||
//Added in version 1.0.8 to ensure that existing nonces are not broken.
|
||||
private static function generateNonceStringOldStyle($action, $plusOneTick = false)
|
||||
{
|
||||
if (isset(Grav::instance()['user'])) {
|
||||
$user = Grav::instance()['user'];
|
||||
$username = $user->username;
|
||||
if (isset($_SERVER['REMOTE_ADDR'])) {
|
||||
$username .= $_SERVER['REMOTE_ADDR'];
|
||||
}
|
||||
} else {
|
||||
$username = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '';
|
||||
}
|
||||
$token = session_id();
|
||||
$i = self::nonceTick();
|
||||
if ($plusOneTick) {
|
||||
$i++;
|
||||
if ($previousTick) {
|
||||
$i--;
|
||||
}
|
||||
|
||||
return ($i . '|' . $action . '|' . $username . '|' . $token . '|' . Grav::instance()['config']->get('security.salt'));
|
||||
@@ -768,33 +759,20 @@ abstract class Utils
|
||||
* action is the same for 12 hours.
|
||||
*
|
||||
* @param string $action the action the nonce is tied to (e.g. save-user-admin or move-page-homepage)
|
||||
* @param bool $plusOneTick if true, generates the token for the next tick (the next 12 hours)
|
||||
* @param bool $previousTick if true, generates the token for the previous tick (the previous 12 hours)
|
||||
*
|
||||
* @return string the nonce
|
||||
*/
|
||||
public static function getNonce($action, $plusOneTick = false)
|
||||
public static function getNonce($action, $previousTick = false)
|
||||
{
|
||||
// Don't regenerate this again if not needed
|
||||
if (isset(static::$nonces[$action])) {
|
||||
return static::$nonces[$action];
|
||||
if (isset(static::$nonces[$action][$previousTick])) {
|
||||
return static::$nonces[$action][$previousTick];
|
||||
}
|
||||
$nonce = md5(self::generateNonceString($action, $plusOneTick));
|
||||
static::$nonces[$action] = $nonce;
|
||||
$nonce = md5(self::generateNonceString($action, $previousTick));
|
||||
static::$nonces[$action][$previousTick] = $nonce;
|
||||
|
||||
return static::$nonces[$action];
|
||||
}
|
||||
|
||||
//Added in version 1.0.8 to ensure that existing nonces are not broken.
|
||||
public static function getNonceOldStyle($action, $plusOneTick = false)
|
||||
{
|
||||
// Don't regenerate this again if not needed
|
||||
if (isset(static::$nonces[$action])) {
|
||||
return static::$nonces[$action];
|
||||
}
|
||||
$nonce = md5(self::generateNonceStringOldStyle($action, $plusOneTick));
|
||||
static::$nonces[$action] = $nonce;
|
||||
|
||||
return static::$nonces[$action];
|
||||
return static::$nonces[$action][$previousTick];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -818,20 +796,8 @@ abstract class Utils
|
||||
}
|
||||
|
||||
//Nonce generated 12-24 hours ago
|
||||
$plusOneTick = true;
|
||||
if ($nonce === self::getNonce($action, $plusOneTick)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Added in version 1.0.8 to ensure that existing nonces are not broken.
|
||||
//Nonce generated 0-12 hours ago
|
||||
if ($nonce === self::getNonceOldStyle($action)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//Nonce generated 12-24 hours ago
|
||||
$plusOneTick = true;
|
||||
if ($nonce === self::getNonceOldStyle($action, $plusOneTick)) {
|
||||
$previousTick = true;
|
||||
if ($nonce === self::getNonce($action, $previousTick)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user