maj && modif graphique

This commit is contained in:
Tessier
2020-10-30 17:09:07 +01:00
parent 584e63567d
commit b1e14f5f7b
881 changed files with 4606 additions and 7069 deletions
@@ -0,0 +1,56 @@
<?php
/**
* @package Grav\Common\Twig
*
* @copyright Copyright (C) 2015 - 2020 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Twig\Node;
use Twig\Compiler;
use Twig\Node\Expression\AbstractExpression;
use Twig\Node\Node;
class TwigNodeCache extends Node
{
/**
* @param string $key unique name for key
* @param int $lifetime in seconds
* @param Node $body
* @param integer $lineno
* @param string $tag
*/
public function __construct(string $key, int $lifetime, Node $body, $lineno, $tag = null)
{
parent::__construct(array('body' => $body), array( 'key' => $key, 'lifetime' => $lifetime), $lineno, $tag);
}
/**
* {@inheritDoc}
*/
public function compile(Compiler $compiler)
{
$boo = $this->getAttribute('key');
$compiler
->addDebugInfo($this)
->write("\$cache = \\Grav\\Common\\Grav::instance()['cache'];\n")
->write("\$key = \"twigcache-\" . \"" . $this->getAttribute('key') . "\";\n")
->write("\$lifetime = " . $this->getAttribute('lifetime') . ";\n")
->write("\$cache_body = \$cache->fetch(\$key);\n")
->write("if (\$cache_body === false) {\n")
->indent()
->write("ob_start();\n")
->indent()
->subcompile($this->getNode('body'))
->outdent()
->write("\n")
->write("\$cache_body = ob_get_clean();\n")
->write("\$cache->save(\$key, \$cache_body, \$lifetime);\n")
->outdent()
->write("}\n")
->write("echo \$cache_body;\n")
;
}
}
@@ -0,0 +1,68 @@
<?php
/**
* @package Grav\Common\Twig
*
* @copyright Copyright (C) 2015 - 2020 Trilby Media, LLC. All rights reserved.
* @license MIT License; see LICENSE file for details.
*/
namespace Grav\Common\Twig\TokenParser;
use Grav\Common\Grav;
use Grav\Common\Twig\Node\TwigNodeCache;
use Twig\Token;
use Twig\TokenParser\AbstractTokenParser;
/**
* Adds ability to cache Twig between tags.
*
* {% cache 600 %}
* {{ some_complex_work() }}
* {% endcache %}
*
* Where the `600` is an optional lifetime in seconds
*/
class TwigTokenParserCache extends AbstractTokenParser
{
/**
* {@inheritDoc}
*/
public function parse(Token $token)
{
$lineno = $token->getLine();
$stream = $this->parser->getStream();
$key = $this->parser->getVarName() . $lineno;
$lifetime = Grav::instance()['cache']->getLifetime();
// Check for optional lifetime override
if (!$stream->test(Token::BLOCK_END_TYPE)) {
$lifetime_expr = $this->parser->getExpressionParser()->parseExpression();
$lifetime = $lifetime_expr->getAttribute('value');
}
$stream->expect(Token::BLOCK_END_TYPE);
$body = $this->parser->subparse(array($this, 'decideCacheEnd'), true);
$stream->expect(Token::BLOCK_END_TYPE);
return new TwigNodeCache($key, $lifetime, $body, $lineno, $this->getTag());
}
/**
* Decide if current token marks end of cache block.
*
* @param Token $token
* @return bool
*/
public function decideCacheEnd(Token $token)
{
return $token->test('endcache');
}
/**
* {@inheritDoc}
*/
public function getTag()
{
return 'cache';
}
}
+98 -44
View File
@@ -11,10 +11,12 @@ namespace Grav\Common\Twig;
use Cron\CronExpression;
use Grav\Common\Config\Config;
use Grav\Common\Data\Data;
use Grav\Common\Debugger;
use Grav\Common\Grav;
use Grav\Common\Language\Language;
use Grav\Common\Page\Collection;
use Grav\Common\Page\Interfaces\PageInterface;
use Grav\Common\Page\Media;
use Grav\Common\Scheduler\Cron;
use Grav\Common\Security;
@@ -25,6 +27,7 @@ use Grav\Common\Twig\TokenParser\TwigTokenParserSwitch;
use Grav\Common\Twig\TokenParser\TwigTokenParserThrow;
use Grav\Common\Twig\TokenParser\TwigTokenParserTryCatch;
use Grav\Common\Twig\TokenParser\TwigTokenParserMarkdown;
use Grav\Common\Twig\TokenParser\TwigTokenParserCache;
use Grav\Common\User\Interfaces\UserInterface;
use Grav\Common\Utils;
use Grav\Common\Yaml;
@@ -167,13 +170,14 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
new \Twig_SimpleFunction('exif', [$this, 'exifFunc']),
new \Twig_SimpleFunction('media_directory', [$this, 'mediaDirFunc']),
new \Twig_SimpleFunction('body_class', [$this, 'bodyClassFunc']),
new \Twig_SimpleFunction('theme_var', [$this, 'themeVarFunc']),
new \Twig_SimpleFunction('header_var', [$this, 'pageHeaderVarFunc']),
new \Twig_SimpleFunction('theme_var', [$this, 'themeVarFunc'], ['needs_context' => true]),
new \Twig_SimpleFunction('header_var', [$this, 'pageHeaderVarFunc'], ['needs_context' => true]),
new \Twig_SimpleFunction('read_file', [$this, 'readFileFunc']),
new \Twig_SimpleFunction('nicenumber', [$this, 'niceNumberFunc']),
new \Twig_SimpleFunction('nicefilesize', [$this, 'niceFilesizeFunc']),
new \Twig_SimpleFunction('nicetime', [$this, 'nicetimeFunc']),
new \Twig_SimpleFunction('cron', [$this, 'cronFunc']),
new \Twig_SimpleFunction('svg_image', [$this, 'svgImageFunction']),
new \Twig_SimpleFunction('xss', [$this, 'xssFunc']),
@@ -201,6 +205,7 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
new TwigTokenParserStyle(),
new TwigTokenParserMarkdown(),
new TwigTokenParserSwitch(),
new TwigTokenParserCache(),
];
}
@@ -1055,7 +1060,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);
}
/**
@@ -1281,17 +1286,64 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
/**
* Get a theme variable
* Will try to get the variable for the current page, if not found, it tries it's parent page on up to root.
* If still not found, will use the theme's configuration value,
* If still not found, will use the $default value passed in
*
* @param string $var
* @param bool $default
* @param $context Twig Context
* @param string $var variable to be found (using dot notation)
* @param null $default the default value to be used as last resort
* @param null $page an optional page to use for the current page
* @param bool $exists toggle to simply return the page where the variable is set, else null
* @return string
*/
public function themeVarFunc($var, $default = null)
public function themeVarFunc($context, $var, $default = null, $page = null, $exists = false)
{
$header = $this->grav['page']->header();
$header_classes = $header->{$var} ?? null;
$page = $page ?? $context['page'] ?? Grav::instance()['page'] ?? null;
return $header_classes ?: $this->config->get('theme.' . $var, $default);
// Try to find var in the page headers
if ($page instanceof PageInterface && $page->exists()) {
// Loop over pages and look for header vars
while ($page && !$page->root()) {
$header = new Data((array)$page->header());
$value = $header->get($var);
if (isset($value)) {
if ($exists) {
return $page;
} else {
return $value;
}
}
$page = $page->parent();
}
}
if ($exists) {
return false;
} else {
return Grav::instance()['config']->get('theme.' . $var, $default);
}
}
/**
* Look for a page header variable in an array of pages working its way through until a value is found
*
* @param $context
* @param string $var the variable to look for in the page header
* @param string|string[]|null $pages array of pages to check (current page upwards if not null)
* @param bool $exists if true, return the page where the var is found, not the value
* @return mixed
* @deprecated 1.7 Use themeVarFunc() instead
*/
public function pageHeaderVarFunc($context, $var, $pages = null)
{
if (is_array($pages)) {
$page = array_shift($pages);
} else {
$page = null;
}
return $this->themeVarFunc($context, $var, null, $page);
}
/**
@@ -1319,41 +1371,6 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
return $body_classes;
}
/**
* Look for a page header variable in an array of pages working its way through until a value is found
*
* @param string $var
* @param string|string[]|null $pages
* @return mixed
*/
public function pageHeaderVarFunc($var, $pages = null)
{
if ($pages === null) {
$pages = $this->grav['page'];
}
// Make sure pages are an array
if (!\is_array($pages)) {
$pages = [$pages];
}
// Loop over pages and look for header vars
foreach ($pages as $page) {
if (\is_string($page)) {
$page = $this->grav['pages']->find($page);
}
if ($page) {
$header = $page->header();
if (isset($header->{$var})) {
return $header->{$var};
}
}
}
return null;
}
/**
* Dump/Encode data into YAML format
*
@@ -1442,4 +1459,41 @@ class TwigExtension extends \Twig_Extension implements \Twig_Extension_GlobalsIn
break;
}
}
/**
* Returns the content of an SVG image and adds extra classes as needed
*
* @param $path
* @param $classes
* @return string|string[]|null
*/
public static function svgImageFunction($path, $classes)
{
$path = Utils::fullPath($path);
if (file_exists($path)) {
$svg = file_get_contents($path);
$classes = " inline-block $classes";
$matched = false;
//Look for existing class
$svg = preg_replace_callback('/^<svg.*?(class=\"(.*?)").*>/', function($matches) use ($classes, &$matched) {
if (isset($matches[2])) {
$new_classes = $matches[2] . $classes;
$matched = true;
return str_replace($matches[1], "class=\"$new_classes\"", $matches[0]);
}
}, $svg
);
// no matches found just add the class
if (!$matched) {
$classes = trim($classes);
$svg = str_replace('<svg ', "<svg class=\"$classes\" ", $svg);
}
return $svg;
}
}
}