Fixed calls to undefined Media methods, they will now return null in order to fix twig templates with undefined variables

This commit is contained in:
Matias Griese
2022-05-11 11:23:46 +03:00
parent ec703ef7e2
commit fb25f33281
7 changed files with 67 additions and 34 deletions

View File

@@ -13,6 +13,7 @@
* Fixed locking and reading files using `Framework\File` classes
* Fixed `Utils::resolveTokenPath()` with `@variable@` not working properly
* Fixed remote URLs in markdown if using subfolder setup
* Fixed calls to undefined `Media` methods, they will now return `null` in order to fix twig templates with undefined variables
# v1.7.33
## 04/25/2022

View File

@@ -240,14 +240,23 @@ interface MediaObjectInterface extends \Grav\Framework\Media\Interfaces\MediaObj
public function style(string $style);
/**
* Allow any action to be called on this medium from twig or markdown
* Checks if the action is supported by the media object.
*
* @param string $method
* @return bool
* @phpstan-pure
*/
public function isAction(string $method): bool;
/**
* Adds query string to the media object.
*
* @param string $var
* @param array $args
* @return $this
* @phpstan-impure
*/
public function __call(string $method, array $args);
public function addQuerystring(string $var, array $args);
/**
* Get value by using dot notation for nested arrays/objects.

View File

@@ -36,8 +36,9 @@ trait ImageMediaTrait
public static array $magic_actions = [
'resize', 'forceResize', 'cropResize', 'crop', 'zoomCrop',
'negate', 'brightness', 'contrast', 'grayscale', 'emboss',
'smooth', 'sharp', 'edge', 'colorize', 'sepia', 'enableProgressive',
'rotate', 'flip', 'fixOrientation', 'gaussianBlur', 'format', 'create', 'fill', 'merge'
'smooth', 'sharp', 'edge', 'colorize', 'sepia',
'enableProgressive', 'rotate', 'flip', 'fixOrientation', 'gaussianBlur',
'format', 'create', 'fill', 'merge'
];
/** @var array */
@@ -471,9 +472,7 @@ trait ImageMediaTrait
*/
public function cropZoom(...$args)
{
$this->__call('zoomCrop', $args);
return $this;
return $this->zoomCrop(...$args);
}
/**
@@ -552,7 +551,7 @@ trait ImageMediaTrait
break;
}
$this->__call('merge', [$watermark, $positionX, $positionY]);
$this->merge($watermark, $positionX, $positionY);
return $this;
}
@@ -579,11 +578,11 @@ trait ImageMediaTrait
$frame = ImageFile::create($dst_width, $dst_height);
$frame->__call('fill', [$color]);
$frame->fill($color);
$this->image = $frame;
$this->__call('merge', [$image, $border, $border]);
$this->merge($image, $border, $border);
$this->saveImage();
*/
@@ -591,6 +590,15 @@ trait ImageMediaTrait
return $this;
}
/**
* @param string $method
* @return bool
*/
public function isAction(string $method): bool
{
return in_array($method, static::$magic_actions, true) || parent::isAction($method);
}
/**
* Forward the call to the image processing method.
*
@@ -602,7 +610,7 @@ trait ImageMediaTrait
public function __call(string $method, array $args)
{
if (!in_array($method, static::$magic_actions, true)) {
return parent::__call($method, $args);
return null;
}
// Always initialize image.
@@ -628,7 +636,7 @@ trait ImageMediaTrait
}
// Do the same call for alternative media.
$medium->__call($method, $args_copy);
$medium->{$method}(...$args_copy);
}
} catch (BadFunctionCallException $e) {
}

View File

@@ -11,7 +11,6 @@ namespace Grav\Common\Media\Traits;
use Grav\Common\Data\Data;
use Grav\Common\Media\Interfaces\ImageMediaInterface;
use Grav\Common\Media\Interfaces\MediaFileInterface;
use Grav\Common\Media\Interfaces\MediaLinkInterface;
use Grav\Common\Media\Interfaces\MediaObjectInterface;
use Grav\Common\Page\Medium\Medium;
@@ -574,27 +573,34 @@ trait MediaObjectTrait
}
/**
* Allow any action to be called on this medium from twig or markdown
*
* @param string $method
* @param array $args
* @return MediaObjectInterface|MediaLinkInterface
* @return bool
*/
public function __call(string $method, array $args)
public function isAction(string $method): bool
{
return false;
}
/**
* @param string $var
* @param array $args
* @return static
*/
public function addQuerystring(string $var, array $args)
{
$count = count($args);
if ($count > 1 || ($count === 1 && !empty($args[0]))) {
$method .= '=' . implode(',', array_map(static function ($a) {
if (is_array($a)) {
$a = '[' . implode(',', $a) . ']';
}
$var .= '=' . implode(',', array_map(static function ($a) {
if (is_array($a)) {
$a = '[' . implode(',', $a) . ']';
}
return rawurlencode($a);
}, $args));
return rawurlencode($a);
}, $args));
}
if (!empty($method)) {
$this->querystring($this->querystring(null, false) . '&' . $method);
if (!empty($var)) {
$this->querystring($this->querystring(null, false) . '&' . $var);
}
return $this;

View File

@@ -19,11 +19,11 @@ use Grav\Common\Utils;
use RocketTheme\Toolbox\Event\Event;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
use function array_key_exists;
use function call_user_func_array;
use function count;
use function dirname;
use function in_array;
use function is_bool;
use function is_callable;
use function is_string;
/**
@@ -282,7 +282,7 @@ class Excerpts
$actions = [];
// if there is a query, then parse it and build action calls
// if there is a query, then parse it and build action calls.
if (isset($url_parts['query'])) {
$actions = array_reduce(
explode('&', $url_parts['query']),
@@ -297,6 +297,7 @@ class Excerpts
);
}
// Add default actions.
$defaults = $this->config['images']['defaults'] ?? [];
if (count($defaults)) {
foreach ($defaults as $method => $params) {
@@ -313,13 +314,22 @@ class Excerpts
foreach ($actions as $action) {
$matches = [];
if (preg_match('/\[(.*)\]/', $action['params'], $matches)) {
if (preg_match('/\[(.*)]/', $action['params'], $matches)) {
$args = [explode(',', $matches[1])];
} else {
$args = explode(',', $action['params']);
}
$medium = call_user_func_array([$medium, $action['method']], $args);
$method = $action['method'];
$result = null;
if (is_callable([$medium, $method]) || $medium->isAction($method)) {
$result = $medium->{$method}(...$args);
}
if ($result instanceof Medium) {
$medium = $result;
} else {
$medium->addQuerystring($method, $args);
}
}
if (isset($url_parts['fragment'])) {

View File

@@ -335,7 +335,7 @@ class ImageMedium extends Medium implements ImageMediaInterface, ImageManipulate
}
if ($width && $height) {
$this->__call('cropResize', [$width, $height]);
$this->cropResize($width, $height);
}
return parent::lightbox($width, $height, $reset);

View File

@@ -105,12 +105,11 @@ class Link implements RenderableInterface, MediaLinkInterface
public function __call(string $method, array $args)
{
$object = $this->source;
$callable = [$object, $method];
if (!is_callable($callable)) {
if (!(is_callable([$object, $method]) || $object->isAction($method))) {
throw new BadMethodCallException(get_class($object) . '::' . $method . '() not found.');
}
$object = call_user_func_array($callable, $args);
$object = $object->{$method}(...$args);
if (!$object instanceof MediaLinkInterface) {
// Don't start nesting links, if user has multiple link calls in his
// actions, we will drop the previous links.