maj grav and plugin
This commit is contained in:
@@ -51,7 +51,11 @@ trait LegacyAssetsTrait
|
||||
// special case to handle old attributes being passed in
|
||||
if (isset($arguments['attributes'])) {
|
||||
$old_attributes = $arguments['attributes'];
|
||||
$arguments = array_merge($arguments, $old_attributes);
|
||||
if (is_array($old_attributes)) {
|
||||
$arguments = array_merge($arguments, $old_attributes);
|
||||
} else {
|
||||
$arguments['type'] = $old_attributes;
|
||||
}
|
||||
}
|
||||
unset($arguments['attributes']);
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
|
||||
namespace Grav\Common;
|
||||
|
||||
use function donatj\UserAgent\parse_user_agent;
|
||||
|
||||
/**
|
||||
* Internally uses the PhpUserAgent package https://github.com/donatj/PhpUserAgent
|
||||
*/
|
||||
|
||||
@@ -136,7 +136,7 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
{
|
||||
$messages = $this->checkRequired($data, $rules);
|
||||
|
||||
foreach ($data as $key => $field) {
|
||||
foreach ($data as $key => $child) {
|
||||
$val = $rules[$key] ?? $rules['*'] ?? null;
|
||||
$rule = \is_string($val) ? $this->items[$val] : null;
|
||||
|
||||
@@ -147,10 +147,10 @@ class BlueprintSchema extends BlueprintSchemaBase implements ExportInterface
|
||||
continue;
|
||||
}
|
||||
|
||||
$messages += Validation::validate($field, $rule);
|
||||
} elseif (\is_array($field) && \is_array($val)) {
|
||||
$messages += Validation::validate($child, $rule);
|
||||
} elseif (\is_array($child) && \is_array($val)) {
|
||||
// Array has been defined in blueprints.
|
||||
$messages += $this->validateArray($field, $val);
|
||||
$messages += $this->validateArray($child, $val);
|
||||
} elseif (isset($rules['validation']) && $rules['validation'] === 'strict') {
|
||||
// Undefined/extra item.
|
||||
throw new \RuntimeException(sprintf('%s is not defined in blueprints', $key));
|
||||
|
||||
@@ -32,6 +32,12 @@ class Data implements DataInterface, \ArrayAccess, \Countable, \JsonSerializable
|
||||
/** @var File */
|
||||
protected $storage;
|
||||
|
||||
/** @var bool */
|
||||
private $missingValuesAsNull = false;
|
||||
|
||||
/** @var bool */
|
||||
private $keepEmptyValues = true;
|
||||
|
||||
/**
|
||||
* @param array $items
|
||||
* @param Blueprint|callable $blueprints
|
||||
@@ -42,6 +48,28 @@ class Data implements DataInterface, \ArrayAccess, \Countable, \JsonSerializable
|
||||
$this->blueprints = $blueprints;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setKeepEmptyValues(bool $value)
|
||||
{
|
||||
$this->keepEmptyValues = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $value
|
||||
* @return $this
|
||||
*/
|
||||
public function setMissingValuesAsNull(bool $value)
|
||||
{
|
||||
$this->missingValuesAsNull = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get value by using dot notation for nested arrays/objects.
|
||||
*
|
||||
@@ -202,8 +230,8 @@ class Data implements DataInterface, \ArrayAccess, \Countable, \JsonSerializable
|
||||
public function filter()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$missingValuesAsNull = (bool)(array_shift($args) ?: false);
|
||||
$keepEmptyValues = (bool)(array_shift($args) ?: false);
|
||||
$missingValuesAsNull = (bool)(array_shift($args) ?? $this->missingValuesAsNull);
|
||||
$keepEmptyValues = (bool)(array_shift($args) ?? $this->keepEmptyValues);
|
||||
|
||||
$this->items = $this->blueprints()->filter($this->items, $missingValuesAsNull, $keepEmptyValues);
|
||||
|
||||
|
||||
@@ -166,9 +166,18 @@ class Validation
|
||||
return (string) $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
* @param array $params
|
||||
* @param array $field
|
||||
* @return string|null
|
||||
*/
|
||||
protected static function filterCheckbox($value, array $params, array $field)
|
||||
{
|
||||
return (bool) $value;
|
||||
$value = (string)$value;
|
||||
$field_value = (string)($field['value'] ?? '1');
|
||||
|
||||
return $value === $field_value ? $value : null;
|
||||
}
|
||||
|
||||
protected static function filterCommaList($value, array $params, array $field)
|
||||
|
||||
@@ -347,7 +347,7 @@ class Debugger
|
||||
*/
|
||||
public function deprecatedErrorHandler($errno, $errstr, $errfile, $errline)
|
||||
{
|
||||
if ($errno !== E_USER_DEPRECATED) {
|
||||
if ($errno !== E_USER_DEPRECATED && $errno !== E_DEPRECATED) {
|
||||
if ($this->errorHandler) {
|
||||
return \call_user_func($this->errorHandler, $errno, $errstr, $errfile, $errline);
|
||||
}
|
||||
|
||||
@@ -22,6 +22,10 @@ abstract class Folder
|
||||
*/
|
||||
public static function lastModifiedFolder($path)
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$last_modified = 0;
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
@@ -56,6 +60,10 @@ abstract class Folder
|
||||
*/
|
||||
public static function lastModifiedFile($path, $extensions = 'md|yaml')
|
||||
{
|
||||
if (!file_exists($path)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$last_modified = 0;
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
@@ -92,21 +100,24 @@ abstract class Folder
|
||||
*/
|
||||
public static function hashAllFiles($path)
|
||||
{
|
||||
$flags = \RecursiveDirectoryIterator::SKIP_DOTS;
|
||||
$files = [];
|
||||
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
if ($locator->isStream($path)) {
|
||||
$directory = $locator->getRecursiveIterator($path, $flags);
|
||||
} else {
|
||||
$directory = new \RecursiveDirectoryIterator($path, $flags);
|
||||
}
|
||||
if (file_exists($path)) {
|
||||
$flags = \RecursiveDirectoryIterator::SKIP_DOTS;
|
||||
|
||||
$iterator = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
/** @var UniformResourceLocator $locator */
|
||||
$locator = Grav::instance()['locator'];
|
||||
if ($locator->isStream($path)) {
|
||||
$directory = $locator->getRecursiveIterator($path, $flags);
|
||||
} else {
|
||||
$directory = new \RecursiveDirectoryIterator($path, $flags);
|
||||
}
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
$files[] = $file->getPathname() . '?'. $file->getMTime();
|
||||
$iterator = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
$files[] = $file->getPathname() . '?'. $file->getMTime();
|
||||
}
|
||||
}
|
||||
|
||||
return md5(serialize($files));
|
||||
@@ -199,6 +210,9 @@ abstract class Folder
|
||||
if ($path === false) {
|
||||
throw new \RuntimeException("Path doesn't exist.");
|
||||
}
|
||||
if (!file_exists($path)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
$compare = isset($params['compare']) ? 'get' . $params['compare'] : null;
|
||||
$pattern = $params['pattern'] ?? null;
|
||||
@@ -235,7 +249,7 @@ abstract class Folder
|
||||
/** @var \RecursiveDirectoryIterator $file */
|
||||
foreach ($iterator as $file) {
|
||||
// Ignore hidden files.
|
||||
if (strpos($file->getFilename(), '.') === 0) {
|
||||
if (strpos($file->getFilename(), '.') === 0 && $file->isFile()) {
|
||||
continue;
|
||||
}
|
||||
if (!$folders && $file->isDir()) {
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Grav\Common\GPM\Local;
|
||||
|
||||
use Grav\Common\Data\Data;
|
||||
use Grav\Common\GPM\Common\Package as BasePackage;
|
||||
use Grav\Framework\Parsedown\Parsedown;
|
||||
|
||||
class Package extends BasePackage
|
||||
{
|
||||
@@ -23,7 +24,7 @@ class Package extends BasePackage
|
||||
|
||||
$this->settings = $package->toArray();
|
||||
|
||||
$html_description = \Parsedown::instance()->line($this->__get('description'));
|
||||
$html_description = Parsedown::instance()->line($this->__get('description'));
|
||||
$this->data->set('slug', $package->__get('slug'));
|
||||
$this->data->set('description_html', $html_description);
|
||||
$this->data->set('description_plain', strip_tags($html_description));
|
||||
|
||||
@@ -409,7 +409,7 @@ class Response
|
||||
} else {
|
||||
$code = (int)curl_getinfo($rch, CURLINFO_HTTP_CODE);
|
||||
if ($code === 301 || $code === 302 || $code === 303) {
|
||||
preg_match('/Location:(.*?)\n/', $header, $matches);
|
||||
preg_match('/(?:^|\n)Location:(.*?)\n/i', $header, $matches);
|
||||
$uri = trim(array_pop($matches));
|
||||
} else {
|
||||
$code = 0;
|
||||
|
||||
@@ -170,6 +170,29 @@ class Grav extends Container
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize CLI environment.
|
||||
*
|
||||
* Call after `$grav->setup($environment)`
|
||||
*
|
||||
* - Load configuration
|
||||
* - Disable debugger
|
||||
* - Set timezone, locale
|
||||
* - Load plugins
|
||||
* - Set Users type to be used in the site
|
||||
*
|
||||
* This method WILL NOT initialize assets, twig or pages.
|
||||
*
|
||||
* @param string|null $environment
|
||||
* @return $this
|
||||
*/
|
||||
public function initializeCli()
|
||||
{
|
||||
InitializeProcessor::initializeCli($this);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a request
|
||||
*/
|
||||
@@ -247,9 +270,21 @@ class Grav extends Container
|
||||
$collection = new RequestHandler($this->middleware, $default, $container);
|
||||
|
||||
$response = $collection->handle($this['request']);
|
||||
$body = $response->getBody();
|
||||
|
||||
// Handle ETag and If-None-Match headers.
|
||||
if ($response->getHeaderLine('ETag') === '1') {
|
||||
$etag = md5($body);
|
||||
$response = $response->withHeader('ETag', $etag);
|
||||
|
||||
if ($this['request']->getHeaderLine('If-None-Match') === $etag) {
|
||||
$response = $response->withStatus(304);
|
||||
$body = '';
|
||||
}
|
||||
}
|
||||
|
||||
$this->header($response);
|
||||
echo $response->getBody();
|
||||
echo $body;
|
||||
|
||||
$debugger->render();
|
||||
|
||||
@@ -281,7 +316,10 @@ class Grav extends Container
|
||||
/** @var Uri $uri */
|
||||
$uri = $this['uri'];
|
||||
|
||||
//Check for code in route
|
||||
// Clean route for redirect
|
||||
$route = preg_replace("#^\/[\\\/]+\/#", '/', $route);
|
||||
|
||||
// Check for code in route
|
||||
$regex = '/.*(\[(30[1-7])\])$/';
|
||||
preg_match($regex, $route, $matches);
|
||||
if ($matches) {
|
||||
@@ -427,11 +465,16 @@ class Grav extends Container
|
||||
* Used to call closures.
|
||||
*
|
||||
* Source: http://stackoverflow.com/questions/419804/closures-as-class-members
|
||||
*
|
||||
* @param string $method
|
||||
* @param array $args
|
||||
* @return
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
$closure = $this->{$method};
|
||||
\call_user_func_array($closure, $args);
|
||||
$closure = $this->{$method} ?? null;
|
||||
|
||||
return is_callable($closure) ? $closure(...$args) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -193,6 +193,8 @@ class Inflector
|
||||
$regex3 = preg_replace('/([0-9])([A-Z])/', '\1-\2', $regex2);
|
||||
$regex4 = preg_replace('/[^A-Z^a-z^0-9]+/', '-', $regex3);
|
||||
|
||||
$regex4 = trim($regex4, '-');
|
||||
|
||||
return strtolower($regex4);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ namespace Grav\Common\Markdown;
|
||||
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Page\Markdown\Excerpts;
|
||||
use Grav\Framework\Parsedown\Parsedown as ParsedownLib;
|
||||
|
||||
class Parsedown extends \Parsedown
|
||||
class Parsedown extends ParsedownLib
|
||||
{
|
||||
use ParsedownGravTrait;
|
||||
|
||||
|
||||
@@ -11,8 +11,9 @@ namespace Grav\Common\Markdown;
|
||||
|
||||
use Grav\Common\Page\Interfaces\PageInterface;
|
||||
use Grav\Common\Page\Markdown\Excerpts;
|
||||
use Grav\Framework\Parsedown\ParsedownExtra as ParsedownExtraLib;
|
||||
|
||||
class ParsedownExtra extends \ParsedownExtra
|
||||
class ParsedownExtra extends ParsedownExtraLib
|
||||
{
|
||||
use ParsedownGravTrait;
|
||||
|
||||
|
||||
@@ -125,5 +125,5 @@ trait MediaTrait
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getCacheKey();
|
||||
abstract protected function getCacheKey(): string;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ class Excerpts
|
||||
);
|
||||
|
||||
// Valid attributes supported.
|
||||
$valid_attributes = ['rel', 'target', 'id', 'class', 'classes'];
|
||||
$valid_attributes = Grav::instance()['config']->get('system.pages.markdown.valid_link_attributes');
|
||||
|
||||
// Unless told to not process, go through actions.
|
||||
if (array_key_exists('noprocess', $actions)) {
|
||||
@@ -232,6 +232,7 @@ class Excerpts
|
||||
$url_parts = is_string($url) ? $this->parseUrl($url) : $url;
|
||||
$actions = [];
|
||||
|
||||
|
||||
// if there is a query, then parse it and build action calls
|
||||
if (isset($url_parts['query'])) {
|
||||
$actions = array_reduce(
|
||||
|
||||
@@ -516,6 +516,15 @@ class ImageMedium extends Medium
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle this commonly used variant
|
||||
*/
|
||||
public function cropZoom()
|
||||
{
|
||||
$this->__call('zoomCrop', func_get_args());
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forward the call to the image processing method.
|
||||
*
|
||||
@@ -525,10 +534,6 @@ class ImageMedium extends Medium
|
||||
*/
|
||||
public function __call($method, $args)
|
||||
{
|
||||
if ($method === 'cropZoom') {
|
||||
$method = 'zoomCrop';
|
||||
}
|
||||
|
||||
if (!\in_array($method, self::$magic_actions, true)) {
|
||||
return parent::__call($method, $args);
|
||||
}
|
||||
|
||||
@@ -529,9 +529,9 @@ class Page implements PageInterface
|
||||
$headers['Last-Modified'] = $last_modified_date;
|
||||
}
|
||||
|
||||
// Calculate ETag based on the raw file
|
||||
// Ask Grav to calculate ETag from the final content.
|
||||
if ($this->eTag()) {
|
||||
$headers['ETag'] = '"' . md5($this->raw() . $this->modified()).'"';
|
||||
$headers['ETag'] = '1';
|
||||
}
|
||||
|
||||
// Set Vary: Accept-Encoding header
|
||||
@@ -608,12 +608,12 @@ class Page implements PageInterface
|
||||
return $content;
|
||||
}
|
||||
|
||||
return mb_strimwidth($content, 0, $size, '...', 'utf-8');
|
||||
return mb_strimwidth($content, 0, $size, '…', 'UTF-8');
|
||||
}
|
||||
|
||||
$summary = Utils::truncateHtml($content, $size);
|
||||
|
||||
return html_entity_decode($summary);
|
||||
return html_entity_decode($summary, ENT_COMPAT | ENT_HTML401, 'UTF-8');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -659,7 +659,7 @@ class Page implements PageInterface
|
||||
// Load cached content
|
||||
/** @var Cache $cache */
|
||||
$cache = Grav::instance()['cache'];
|
||||
$cache_id = md5('page' . $this->id());
|
||||
$cache_id = md5('page' . $this->getCacheKey());
|
||||
$content_obj = $cache->fetch($cache_id);
|
||||
|
||||
if (is_array($content_obj)) {
|
||||
@@ -865,7 +865,7 @@ class Page implements PageInterface
|
||||
public function cachePageContent()
|
||||
{
|
||||
$cache = Grav::instance()['cache'];
|
||||
$cache_id = md5('page' . $this->id());
|
||||
$cache_id = md5('page' . $this->getCacheKey());
|
||||
$cache->save($cache_id, ['content' => $this->content, 'content_meta' => $this->content_meta]);
|
||||
}
|
||||
|
||||
@@ -1200,7 +1200,7 @@ class Page implements PageInterface
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function getCacheKey()
|
||||
public function getCacheKey(): string
|
||||
{
|
||||
return $this->id();
|
||||
}
|
||||
@@ -1694,9 +1694,9 @@ class Page implements PageInterface
|
||||
$metadata['generator'] = 'GravCMS';
|
||||
|
||||
// Get initial metadata for the page
|
||||
$metadata = array_merge($metadata, Grav::instance()['config']->get('site.metadata'));
|
||||
$metadata = array_merge($metadata, Grav::instance()['config']->get('site.metadata', []));
|
||||
|
||||
if (isset($this->header->metadata)) {
|
||||
if (isset($this->header->metadata) && is_array($this->header->metadata)) {
|
||||
// Merge any site.metadata settings in with page metadata
|
||||
$metadata = array_merge($metadata, $this->header->metadata);
|
||||
}
|
||||
@@ -2009,6 +2009,10 @@ class Page implements PageInterface
|
||||
*/
|
||||
public function id($var = null)
|
||||
{
|
||||
if (null === $this->id) {
|
||||
// We need to set unique id to avoid potential cache conflicts between pages.
|
||||
$var = time() . md5($this->filePath());
|
||||
}
|
||||
if ($var !== null) {
|
||||
// store unique per language
|
||||
$active_lang = Grav::instance()['language']->getLanguage() ?: '';
|
||||
@@ -2824,7 +2828,7 @@ class Page implements PageInterface
|
||||
if ($pagination) {
|
||||
$params = $collection->params();
|
||||
|
||||
$limit = $params['limit'] ?? 0;
|
||||
$limit = (int)($params['limit'] ?? 0);
|
||||
$start = !empty($params['pagination']) ? ($uri->currentPage() - 1) * $limit : 0;
|
||||
|
||||
if ($limit && $collection->count() > $limit) {
|
||||
|
||||
@@ -95,6 +95,8 @@ class Pages
|
||||
|
||||
protected $initialized = false;
|
||||
|
||||
protected $active_lang;
|
||||
|
||||
/**
|
||||
* @var Types
|
||||
*/
|
||||
@@ -143,7 +145,7 @@ class Pages
|
||||
*/
|
||||
public function baseRoute($lang = null)
|
||||
{
|
||||
$key = $lang ?: 'default';
|
||||
$key = $lang ?: $this->active_lang ?: 'default';
|
||||
|
||||
if (!isset($this->baseRoute[$key])) {
|
||||
/** @var Language $language */
|
||||
@@ -236,6 +238,16 @@ class Pages
|
||||
$this->check_method = strtolower($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset pages (used in search indexing etc).
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->initialized = false;
|
||||
|
||||
$this->init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Class initialization. Must be called before using this class.
|
||||
*/
|
||||
@@ -958,6 +970,9 @@ class Pages
|
||||
|
||||
$pages_dir = $locator->findResource('page://');
|
||||
|
||||
// Set active language
|
||||
$this->active_lang = $language->getActive();
|
||||
|
||||
if ($config->get('system.cache.enabled')) {
|
||||
/** @var Cache $cache */
|
||||
$cache = $this->grav['cache'];
|
||||
@@ -982,17 +997,19 @@ class Pages
|
||||
|
||||
$this->pages_cache_id = md5($pages_dir . $hash . $language->getActive() . $config->checksum());
|
||||
|
||||
list($this->instances, $this->routes, $this->children, $taxonomy_map, $this->sort) = $cache->fetch($this->pages_cache_id);
|
||||
if (!$this->instances) {
|
||||
$cached = $cache->fetch($this->pages_cache_id);
|
||||
if ($cached) {
|
||||
$this->grav['debugger']->addMessage('Page cache hit.');
|
||||
|
||||
list($this->instances, $this->routes, $this->children, $taxonomy_map, $this->sort) = $cached;
|
||||
|
||||
// If pages was found in cache, set the taxonomy
|
||||
$taxonomy->taxonomy($taxonomy_map);
|
||||
} else {
|
||||
$this->grav['debugger']->addMessage('Page cache missed, rebuilding pages..');
|
||||
|
||||
// recurse pages and cache result
|
||||
$this->resetPages($pages_dir);
|
||||
|
||||
} else {
|
||||
// If pages was found in cache, set the taxonomy
|
||||
$this->grav['debugger']->addMessage('Page cache hit.');
|
||||
$taxonomy->taxonomy($taxonomy_map);
|
||||
}
|
||||
} else {
|
||||
$this->recurse($pages_dir);
|
||||
@@ -1261,14 +1278,13 @@ class Pages
|
||||
{
|
||||
$list = [];
|
||||
$header_default = null;
|
||||
$header_query = null;
|
||||
$header_query = [];
|
||||
|
||||
// do this header query work only once
|
||||
if (strpos($order_by, 'header.') === 0) {
|
||||
$header_query = explode('|', str_replace('header.', '', $order_by));
|
||||
if (isset($header_query[1])) {
|
||||
$header_default = $header_query[1];
|
||||
}
|
||||
$query = explode('|', str_replace('header.', '', $order_by), 2);
|
||||
$header_query = array_shift($query) ?? '';
|
||||
$header_default = array_shift($query);
|
||||
}
|
||||
|
||||
foreach ($pages as $key => $info) {
|
||||
@@ -1306,11 +1322,17 @@ class Pages
|
||||
case 'folder':
|
||||
$list[$key] = $child->folder();
|
||||
break;
|
||||
case (is_string($header_query[0])):
|
||||
$child_header = new Header((array)$child->header());
|
||||
$header_value = $child_header->get($header_query[0]);
|
||||
case 'manual':
|
||||
case 'default':
|
||||
default:
|
||||
if (is_string($header_query)) {
|
||||
$child_header = $child->header();
|
||||
if (!$child_header instanceof Header) {
|
||||
$child_header = new Header((array)$child_header);
|
||||
}
|
||||
$header_value = $child_header->get($header_query);
|
||||
if (is_array($header_value)) {
|
||||
$list[$key] = implode(',',$header_value);
|
||||
$list[$key] = implode(',', $header_value);
|
||||
} elseif ($header_value) {
|
||||
$list[$key] = $header_value;
|
||||
} else {
|
||||
@@ -1318,11 +1340,9 @@ class Pages
|
||||
}
|
||||
$sort_flags = $sort_flags ?: SORT_REGULAR;
|
||||
break;
|
||||
case 'manual':
|
||||
case 'default':
|
||||
default:
|
||||
$list[$key] = $key;
|
||||
$sort_flags = $sort_flags ?: SORT_REGULAR;
|
||||
}
|
||||
$list[$key] = $key;
|
||||
$sort_flags = $sort_flags ?: SORT_REGULAR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -305,7 +305,7 @@ class Plugin implements EventSubscriberInterface, \ArrayAccess
|
||||
|
||||
// Create new config object and set it on the page object so it's cached for next time
|
||||
$page->modifyHeader($class_name_merged, new Data($header));
|
||||
} else if (isset($page_header->{$class_name_merged})) {
|
||||
} elseif (isset($page_header->{$class_name_merged})) {
|
||||
$merged = $page_header->{$class_name_merged};
|
||||
$header = $merged->toArray();
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
namespace Grav\Common\Processors;
|
||||
|
||||
use Grav\Common\Config\Config;
|
||||
use Grav\Common\Grav;
|
||||
use Grav\Common\Uri;
|
||||
use Grav\Common\Utils;
|
||||
use Grav\Framework\Session\Exceptions\SessionException;
|
||||
@@ -22,6 +23,22 @@ class InitializeProcessor extends ProcessorBase
|
||||
public $id = 'init';
|
||||
public $title = 'Initialize';
|
||||
|
||||
/** @var bool */
|
||||
private static $cli_initialized = false;
|
||||
|
||||
/**
|
||||
* @param Grav $grav
|
||||
*/
|
||||
public static function initializeCli(Grav $grav)
|
||||
{
|
||||
if (!static::$cli_initialized) {
|
||||
static::$cli_initialized = true;
|
||||
|
||||
$instance = new static($grav);
|
||||
$instance->processCli();
|
||||
}
|
||||
}
|
||||
|
||||
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
|
||||
{
|
||||
$this->startTimer();
|
||||
@@ -77,4 +94,35 @@ class InitializeProcessor extends ProcessorBase
|
||||
|
||||
return $handler->handle($request);
|
||||
}
|
||||
|
||||
public function processCli(): void
|
||||
{
|
||||
// Load configuration.
|
||||
$this->container['config']->init();
|
||||
$this->container['plugins']->setup();
|
||||
|
||||
// Disable debugger.
|
||||
$this->container['debugger']->enabled(false);
|
||||
|
||||
// Set timezone, locale.
|
||||
/** @var Config $config */
|
||||
$config = $this->container['config'];
|
||||
$timezone = $config->get('system.timezone');
|
||||
if ($timezone) {
|
||||
date_default_timezone_set($timezone);
|
||||
}
|
||||
$this->container->setLocale();
|
||||
|
||||
// Load plugins.
|
||||
$this->container['plugins']->init();
|
||||
|
||||
// Initialize URI.
|
||||
/** @var Uri $uri */
|
||||
$uri = $this->container['uri'];
|
||||
$uri->init();
|
||||
|
||||
// Load accounts.
|
||||
// TODO: remove in 2.0.
|
||||
$this->container['accounts'];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ class Cron
|
||||
'name_year' => 'année',
|
||||
'text_period' => 'Chaque %s',
|
||||
'text_mins' => 'à %s minutes',
|
||||
'text_time' => 'à %s:%s',
|
||||
'text_time' => 'à %02s:%02s',
|
||||
'text_dow' => 'le %s',
|
||||
'text_month' => 'de %s',
|
||||
'text_dom' => 'le %s',
|
||||
@@ -86,7 +86,7 @@ class Cron
|
||||
'name_year' => 'year',
|
||||
'text_period' => 'Every %s',
|
||||
'text_mins' => 'at %s minutes past the hour',
|
||||
'text_time' => 'at %s:%s',
|
||||
'text_time' => 'at %02s:%02s',
|
||||
'text_dow' => 'on %s',
|
||||
'text_month' => 'of %s',
|
||||
'text_dom' => 'on the %s',
|
||||
|
||||
@@ -26,6 +26,19 @@ class PagesServiceProvider implements ServiceProviderInterface
|
||||
return new Pages($c);
|
||||
};
|
||||
|
||||
if (\defined('GRAV_CLI')) {
|
||||
$container['page'] = static function ($c) {
|
||||
$path = $c['locator']->findResource('system://pages/notfound.md');
|
||||
$page = new Page();
|
||||
$page->init(new \SplFileInfo($path));
|
||||
$page->routable(false);
|
||||
|
||||
return $page;
|
||||
};
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$container['page'] = function ($c) {
|
||||
/** @var Grav $c */
|
||||
|
||||
|
||||
@@ -1055,7 +1055,7 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
|
||||
*/
|
||||
public function jsonDecodeFilter($str, $assoc = false, $depth = 512, $options = 0)
|
||||
{
|
||||
return json_decode(html_entity_decode($str), $assoc, $depth, $options);
|
||||
return json_decode(html_entity_decode($str, ENT_COMPAT | ENT_HTML401, 'UTF-8'), $assoc, $depth, $options);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -151,7 +151,7 @@ class Uri
|
||||
|
||||
$this->url = $this->base . $this->uri;
|
||||
|
||||
$uri = str_replace(static::filterPath($this->root), '', $this->url);
|
||||
$uri = Utils::replaceFirstOccurrence(static::filterPath($this->root), '', $this->url);
|
||||
|
||||
// remove the setup.php based base if set:
|
||||
$setup_base = $grav['pages']->base();
|
||||
@@ -195,7 +195,7 @@ class Uri
|
||||
// set the new url
|
||||
$this->url = $this->root . $path;
|
||||
$this->path = static::cleanPath($path);
|
||||
$this->content_path = trim(str_replace($this->base, '', $this->path), '/');
|
||||
$this->content_path = trim(Utils::replaceFirstOccurrence($this->base, '', $this->path), '/');
|
||||
if ($this->content_path !== '') {
|
||||
$this->paths = explode('/', $this->content_path);
|
||||
}
|
||||
@@ -306,7 +306,7 @@ class Uri
|
||||
public function param($id)
|
||||
{
|
||||
if (isset($this->params[$id])) {
|
||||
return html_entity_decode(rawurldecode($this->params[$id]));
|
||||
return html_entity_decode(rawurldecode($this->params[$id]), ENT_COMPAT | ENT_HTML401, 'UTF-8');
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -340,7 +340,7 @@ class Uri
|
||||
return $this->url;
|
||||
}
|
||||
|
||||
$url = str_replace($this->base, '', rtrim($this->url, '/'));
|
||||
$url = Utils::replaceFirstOccurrence($this->base, '', rtrim($this->url, '/'));
|
||||
|
||||
return $url ?: '/';
|
||||
}
|
||||
@@ -489,7 +489,7 @@ class Uri
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
return str_replace($this->root_path, '', $this->uri);
|
||||
return Utils::replaceFirstOccurrence($this->root_path, '', $this->uri);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -531,7 +531,7 @@ class Uri
|
||||
return $this->root;
|
||||
}
|
||||
|
||||
return str_replace($this->base, '', $this->root);
|
||||
return Utils::replaceFirstOccurrence($this->base, '', $this->root);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -541,7 +541,9 @@ class Uri
|
||||
*/
|
||||
public function currentPage()
|
||||
{
|
||||
return $this->params['page'] ?? 1;
|
||||
$page = (int)($this->params['page'] ?? 1);
|
||||
|
||||
return max(1, $page);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -629,9 +631,9 @@ class Uri
|
||||
{
|
||||
if (getenv('HTTP_CLIENT_IP')) {
|
||||
$ip = getenv('HTTP_CLIENT_IP');
|
||||
} elseif (getenv('HTTP_X_FORWARDED_FOR')) {
|
||||
} elseif (getenv('HTTP_X_FORWARDED_FOR') && Grav::instance()['config']->get('system.http_x_forwarded.ip')) {
|
||||
$ip = getenv('HTTP_X_FORWARDED_FOR');
|
||||
} elseif (getenv('HTTP_X_FORWARDED')) {
|
||||
} elseif (getenv('HTTP_X_FORWARDED') && Grav::instance()['config']->get('system.http_x_forwarded.ip')) {
|
||||
$ip = getenv('HTTP_X_FORWARDED');
|
||||
} elseif (getenv('HTTP_FORWARDED_FOR')) {
|
||||
$ip = getenv('HTTP_FORWARDED_FOR');
|
||||
@@ -783,7 +785,7 @@ class Uri
|
||||
}
|
||||
|
||||
// special check to see if path checking is required.
|
||||
$just_path = str_replace($normalized_url, '', $normalized_path);
|
||||
$just_path = Utils::replaceFirstOccurrence($normalized_url, '', $normalized_path);
|
||||
if ($normalized_url === '/' || $just_path === $page->path()) {
|
||||
$url_path = $normalized_url;
|
||||
} else {
|
||||
@@ -852,7 +854,7 @@ class Uri
|
||||
}
|
||||
|
||||
// strip base from this path
|
||||
$target_path = str_replace($uri->rootUrl(), '', $target_path);
|
||||
$target_path = Utils::replaceFirstOccurrence($uri->rootUrl(), '', $target_path);
|
||||
|
||||
// set to / if root
|
||||
if (empty($target_path)) {
|
||||
@@ -877,7 +879,7 @@ class Uri
|
||||
|
||||
// Handle route only
|
||||
if ($route_only) {
|
||||
$url_path = str_replace(static::filterPath($base_url), '', $url_path);
|
||||
$url_path = Utils::replaceFirstOccurrence(static::filterPath($base_url), '', $url_path);
|
||||
}
|
||||
|
||||
// transform back to string/array as needed
|
||||
@@ -998,7 +1000,7 @@ class Uri
|
||||
}
|
||||
|
||||
// special check to see if path checking is required.
|
||||
$just_path = str_replace($normalized_url, '', $normalized_path);
|
||||
$just_path = Utils::replaceFirstOccurrence($normalized_url, '', $normalized_path);
|
||||
if ($just_path === $page->path()) {
|
||||
return $normalized_url;
|
||||
}
|
||||
@@ -1148,7 +1150,7 @@ class Uri
|
||||
protected function createFromEnvironment(array $env)
|
||||
{
|
||||
// Build scheme.
|
||||
if (isset($env['HTTP_X_FORWARDED_PROTO'])) {
|
||||
if (isset($env['HTTP_X_FORWARDED_PROTO']) && Grav::instance()['config']->get('system.http_x_forwarded.protocol')) {
|
||||
$this->scheme = $env['HTTP_X_FORWARDED_PROTO'];
|
||||
} elseif (isset($env['X-FORWARDED-PROTO'])) {
|
||||
$this->scheme = $env['X-FORWARDED-PROTO'];
|
||||
@@ -1166,11 +1168,14 @@ class Uri
|
||||
$this->password = $env['PHP_AUTH_PW'] ?? null;
|
||||
|
||||
// Build host.
|
||||
$hostname = 'localhost';
|
||||
if (isset($env['HTTP_HOST'])) {
|
||||
if (isset($env['HTTP_X_FORWARDED_HOST']) && Grav::instance()['config']->get('system.http_x_forwarded.host')) {
|
||||
$hostname = $env['HTTP_X_FORWARDED_HOST'];
|
||||
} else if (isset($env['HTTP_HOST'])) {
|
||||
$hostname = $env['HTTP_HOST'];
|
||||
} elseif (isset($env['SERVER_NAME'])) {
|
||||
$hostname = $env['SERVER_NAME'];
|
||||
} else {
|
||||
$hostname = 'localhost';
|
||||
}
|
||||
// Remove port from HTTP_HOST generated $hostname
|
||||
$hostname = Utils::substrToString($hostname, ':');
|
||||
@@ -1178,7 +1183,7 @@ class Uri
|
||||
$this->host = $this->validateHostname($hostname) ? $hostname : 'unknown';
|
||||
|
||||
// Build port.
|
||||
if (isset($env['HTTP_X_FORWARDED_PORT'])) {
|
||||
if (isset($env['HTTP_X_FORWARDED_PORT']) && Grav::instance()['config']->get('system.http_x_forwarded.port')) {
|
||||
$this->port = (int)$env['HTTP_X_FORWARDED_PORT'];
|
||||
} elseif (isset($env['X-FORWARDED-PORT'])) {
|
||||
$this->port = (int)$env['X-FORWARDED-PORT'];
|
||||
|
||||
Reference in New Issue
Block a user