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

# Conflicts:
#	CHANGELOG.md
This commit is contained in:
Andy Miller
2020-09-18 12:51:00 -06:00
18 changed files with 187 additions and 297 deletions

View File

@@ -4,9 +4,11 @@
1. [](#improved)
* Fall back through various templates scenarios if they don't exist in theme to avoid unhelpful error.
* Added default templates for `external.html.twig`, `default.html.twig`, and `modular.html.twig`
* Improve Media classes
1. [](#bugfix)
* Fixed `Security::sanitizeSVG()` creating an empty file if SVG file cannot be parsed
* Fixed infinite loop in blueprints with `extend@` to a parent stream
* Added missing `Stream::create()` method
# v1.7.0-rc.16
## 09/01/2020

291
composer.lock generated
View File

@@ -305,16 +305,6 @@
"user agent",
"useragent"
],
"funding": [
{
"url": "https://www.paypal.me/donatj/15",
"type": "custom"
},
{
"url": "https://github.com/donatj",
"type": "github"
}
],
"time": "2020-09-01T16:13:00+00:00"
},
{
@@ -724,16 +714,16 @@
},
{
"name": "itsgoingd/clockwork",
"version": "v4.1.7",
"version": "v4.1.8",
"source": {
"type": "git",
"url": "https://github.com/itsgoingd/clockwork.git",
"reference": "49c28d7c43f6021eca4c290f620f13ee7d15f668"
"reference": "0dc2e5be39de88b18719bb4f3cdacfa605ad2146"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/49c28d7c43f6021eca4c290f620f13ee7d15f668",
"reference": "49c28d7c43f6021eca4c290f620f13ee7d15f668",
"url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/0dc2e5be39de88b18719bb4f3cdacfa605ad2146",
"reference": "0dc2e5be39de88b18719bb4f3cdacfa605ad2146",
"shasum": ""
},
"require": {
@@ -779,7 +769,7 @@
"profiling",
"slim"
],
"time": "2020-08-25T20:05:21+00:00"
"time": "2020-09-17T19:21:25+00:00"
},
{
"name": "kodus/psr7-server",
@@ -2019,20 +2009,6 @@
],
"description": "Symfony Console Component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-09-02T07:07:21+00:00"
},
{
@@ -2110,20 +2086,6 @@
"interoperability",
"standards"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-09-02T16:08:58+00:00"
},
{
@@ -2194,20 +2156,6 @@
],
"description": "Symfony EventDispatcher Component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-08-13T14:18:44+00:00"
},
{
@@ -2276,20 +2224,6 @@
],
"description": "Symfony HttpClient component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-09-02T08:01:15+00:00"
},
{
@@ -2714,20 +2648,6 @@
],
"description": "Symfony Process Component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-07-23T08:31:43+00:00"
},
{
@@ -2805,20 +2725,6 @@
"debug",
"dump"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-08-17T07:31:35+00:00"
},
{
@@ -2878,20 +2784,6 @@
],
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-08-26T08:30:46+00:00"
},
{
@@ -3289,20 +3181,6 @@
}
],
"description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)",
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://github.com/composer",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
"time": "2020-08-25T05:50:16+00:00"
},
{
@@ -3347,20 +3225,6 @@
"Xdebug",
"performance"
],
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://github.com/composer",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
"time": "2020-08-19T10:27:58+00:00"
},
{
@@ -3417,20 +3281,6 @@
"constructor",
"instantiate"
],
"funding": [
{
"url": "https://www.doctrine-project.org/sponsorship.html",
"type": "custom"
},
{
"url": "https://www.patreon.com/phpdoctrine",
"type": "patreon"
},
{
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
"type": "tidelift"
}
],
"time": "2020-05-29T17:27:14+00:00"
},
{
@@ -3664,24 +3514,24 @@
},
{
"name": "jean85/pretty-package-versions",
"version": "1.5.0",
"version": "1.5.1",
"source": {
"type": "git",
"url": "https://github.com/Jean85/pretty-package-versions.git",
"reference": "e9f4324e88b8664be386d90cf60fbc202e1f7fc9"
"reference": "a917488320c20057da87f67d0d40543dd9427f7a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/e9f4324e88b8664be386d90cf60fbc202e1f7fc9",
"reference": "e9f4324e88b8664be386d90cf60fbc202e1f7fc9",
"url": "https://api.github.com/repos/Jean85/pretty-package-versions/zipball/a917488320c20057da87f67d0d40543dd9427f7a",
"reference": "a917488320c20057da87f67d0d40543dd9427f7a",
"shasum": ""
},
"require": {
"composer/package-versions-deprecated": "^1.8.0",
"php": "^7.0"
"php": "^7.0|^8.0"
},
"require-dev": {
"phpunit/phpunit": "^6.0"
"phpunit/phpunit": "^6.0|^8.5|^9.2"
},
"type": "library",
"extra": {
@@ -3711,7 +3561,7 @@
"release",
"versions"
],
"time": "2020-06-23T06:23:06+00:00"
"time": "2020-09-14T08:43:34+00:00"
},
{
"name": "myclabs/deep-copy",
@@ -3759,12 +3609,6 @@
"object",
"object graph"
],
"funding": [
{
"url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
"type": "tidelift"
}
],
"time": "2020-06-29T13:22:24+00:00"
},
{
@@ -4106,16 +3950,16 @@
},
{
"name": "nette/robot-loader",
"version": "v3.3.0",
"version": "v3.3.1",
"source": {
"type": "git",
"url": "https://github.com/nette/robot-loader.git",
"reference": "737ff8ee1709eff053d9cc27e6c661d82395bd8b"
"reference": "15c1ecd0e6e69e8d908dfc4cca7b14f3b850a96b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/robot-loader/zipball/737ff8ee1709eff053d9cc27e6c661d82395bd8b",
"reference": "737ff8ee1709eff053d9cc27e6c661d82395bd8b",
"url": "https://api.github.com/repos/nette/robot-loader/zipball/15c1ecd0e6e69e8d908dfc4cca7b14f3b850a96b",
"reference": "15c1ecd0e6e69e8d908dfc4cca7b14f3b850a96b",
"shasum": ""
},
"require": {
@@ -4165,7 +4009,7 @@
"nette",
"trait"
],
"time": "2020-07-28T13:34:12+00:00"
"time": "2020-09-15T15:14:17+00:00"
},
{
"name": "nette/schema",
@@ -5844,20 +5688,6 @@
],
"description": "Symfony BrowserKit Component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-05-22T17:28:00+00:00"
},
{
@@ -5911,20 +5741,6 @@
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-07-05T09:39:30+00:00"
},
{
@@ -5986,20 +5802,6 @@
],
"description": "Symfony DomCrawler Component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-08-12T06:20:35+00:00"
},
{
@@ -6049,20 +5851,6 @@
],
"description": "Symfony Finder Component",
"homepage": "https://symfony.com",
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-08-17T09:56:45+00:00"
},
{
@@ -6134,20 +5922,6 @@
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-08-04T06:02:08+00:00"
},
{
@@ -6215,20 +5989,6 @@
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-07-14T12:35:20+00:00"
},
{
@@ -6292,20 +6052,6 @@
"portable",
"shim"
],
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2020-07-14T12:35:20+00:00"
},
{
@@ -6464,6 +6210,5 @@
"platform-dev": [],
"platform-overrides": {
"php": "7.1.3"
},
"plugin-api-version": "1.1.0"
}
}

View File

@@ -253,8 +253,8 @@ class PageObject extends FlexPageObject
// Backwards compatibility with older plugins.
$fireEvents = $reorder && $this->isAdminSite() && $this->getFlexDirectory()->getConfig('object.compat.events', true);
$grav = $this->getContainer();
if ($fireEvents) {
$grav = $this->getContainer();
$self = $this;
$grav->fireEvent('onAdminSave', new Event(['type' => 'flex', 'directory' => $this->getFlexDirectory(), 'object' => &$self]));
if ($self !== $this) {

View File

@@ -553,8 +553,8 @@ class UserObject extends FlexObject implements UserInterface, \Countable
// Backwards compatibility with older plugins.
$fireEvents = $this->isAdminSite() && $this->getFlexDirectory()->getConfig('object.compat.events', true);
$grav = $this->getContainer();
if ($fireEvents) {
$grav = $this->getContainer();
$self = $this;
$grav->fireEvent('onAdminSave', new Event(['type' => 'flex', 'directory' => $this->getFlexDirectory(), 'object' => &$self]));
if ($self !== $this) {

View File

@@ -9,6 +9,10 @@
namespace Grav\Common\Media\Interfaces;
use Grav\Common\Data\Blueprint;
use Grav\Common\Page\Medium\ImageFile;
use Grav\Common\Page\Medium\Medium;
/**
* Class implements media collection interface.
*/
@@ -21,6 +25,20 @@ interface MediaCollectionInterface extends \Grav\Framework\Media\Interfaces\Medi
*/
public function getPath();
/**
* @param string|null $path
* @return void
*/
public function setPath(?string $path);
/**
* Get medium by filename.
*
* @param string $filename
* @return Medium|null
*/
public function get($filename);
/**
* Get a list of all media.
*
@@ -28,6 +46,34 @@ interface MediaCollectionInterface extends \Grav\Framework\Media\Interfaces\Medi
*/
public function all();
/**
* Get a list of all image media.
*
* @return MediaObjectInterface[]
*/
public function images();
/**
* Get a list of all video media.
*
* @return MediaObjectInterface[]
*/
public function videos();
/**
* Get a list of all audio media.
*
* @return MediaObjectInterface[]
*/
public function audios();
/**
* Get a list of all file media.
*
* @return MediaObjectInterface[]
*/
public function files();
/**
* Set file modification timestamps (query params) for all the media files.
*
@@ -39,6 +85,31 @@ interface MediaCollectionInterface extends \Grav\Framework\Media\Interfaces\Medi
/**
* @param string $name
* @param MediaObjectInterface $file
* @return void
*/
public function add($name, $file);
/**
* Create Medium from a file.
*
* @param string $file
* @param array $params
* @return Medium|null
*/
public function createFromFile($file, array $params = []);
/**
* Create Medium from array of parameters
*
* @param array $items
* @param Blueprint|null $blueprint
* @return Medium|null
*/
public function createFromArray(array $items = [], Blueprint $blueprint = null);
/**
* @param MediaObjectInterface $mediaObject
* @return ImageFile
*/
public function getImageFileObject(MediaObjectInterface $mediaObject): ImageFile;
}

View File

@@ -16,7 +16,7 @@ use Grav\Common\Data\Data;
*
* @property string $type
*/
interface MediaObjectInterface extends \Grav\Framework\Media\Interfaces\MediaObjectInterface
interface MediaObjectInterface extends \Grav\Framework\Media\Interfaces\MediaObjectInterface, \ArrayAccess
{
/**
* Create a copy of this media object

View File

@@ -13,6 +13,7 @@ use Grav\Common\Config\Config;
use Grav\Common\Filesystem\Folder;
use Grav\Common\Grav;
use Grav\Common\Language\Language;
use Grav\Common\Page\Medium\Medium;
use Grav\Common\Page\Medium\MediumFactory;
use Grav\Common\Security;
use Grav\Common\Utils;
@@ -39,6 +40,18 @@ trait MediaUploadTrait
'destination' => null // Destination path, if empty, exception is thrown.
];
/**
* Create Medium from an uploaded file.
*
* @param UploadedFileInterface $uploadedFile
* @param array $params
* @return Medium|null
*/
public function createFromUploadedFile(UploadedFileInterface $uploadedFile, array $params = [])
{
return MediumFactory::fromUploadedFile($uploadedFile, $params);
}
/**
* Checks that uploaded file meets the requirements. Returns new filename.
*
@@ -187,10 +200,9 @@ trait MediaUploadTrait
* WARNING: Always check uploaded file before copying it!
*
* @example
* $filename = null; // Override filename if needed (ignored if randomizing filenames).
* $settings = ['destination' => 'user://pages/media']; // Settings from the form field.
* $filename = $media->checkUploadedFile($uploadedFile, $filename, $settings);
* $media->copyUploadedFile($uploadedFile, $filename);
* $media->copyUploadedFile($uploadedFile, $filename, $settings);
*
* @param UploadedFileInterface $uploadedFile
* @param string $filename
@@ -208,7 +220,7 @@ trait MediaUploadTrait
}
$path = $settings['destination'] ?? $this->getPath();
if (!$path) {
if (!$path || !$filename) {
throw new RuntimeException($this->translate('PLUGIN_ADMIN.FAILED_TO_MOVE_UPLOADED_FILE'), 400);
}
@@ -406,6 +418,7 @@ trait MediaUploadTrait
throw new RuntimeException('File could not be renamed: ' . $from, 500);
}
// TODO: Add missing logic to handle retina files.
if (is_file($fromPath . '.meta.yaml')) {
$result = rename($fromPath . '.meta.yaml', $toPath . '.meta.yaml');
if (!$result) {

View File

@@ -46,9 +46,9 @@ class Media extends AbstractMedia
*/
public function __wakeup()
{
if (!isset(static::$global)) {
if (null === static::$global) {
// Add fallback to global media.
static::$global = new GlobalMedia();
static::$global = GlobalMedia::getInstance();
}
}
@@ -122,7 +122,7 @@ class Media extends AbstractMedia
* @var array $alt
*/
foreach ($types['alternative'] as $ratio => &$alt) {
$alt['file'] = MediumFactory::fromFile($alt['file']);
$alt['file'] = $this->createFromFile($alt['file']);
if (empty($alt['file'])) {
unset($types['alternative'][$ratio]);
@@ -146,7 +146,7 @@ class Media extends AbstractMedia
$file_path = $medium->path();
$medium = MediumFactory::scaledFromMedium($medium, $max, 1)['file'];
} else {
$medium = MediumFactory::fromFile($types['base']['file']);
$medium = $this->createFromFile($types['base']['file']);
if ($medium) {
$medium->set('size', $types['base']['size']);
$file_path = $medium->path();

View File

@@ -10,6 +10,7 @@
namespace Grav\Common\Page\Medium;
use Grav\Common\Config\Config;
use Grav\Common\Data\Blueprint;
use Grav\Common\Grav;
use Grav\Common\Language\Language;
use Grav\Common\Media\Interfaces\MediaCollectionInterface;
@@ -23,6 +24,7 @@ use RocketTheme\Toolbox\ArrayTraits\Countable;
use RocketTheme\Toolbox\ArrayTraits\Export;
use RocketTheme\Toolbox\ArrayTraits\ExportInterface;
use RocketTheme\Toolbox\ArrayTraits\Iterator;
use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
abstract class AbstractMedia implements ExportInterface, MediaCollectionInterface, MediaUploadInterface
{
@@ -59,6 +61,7 @@ abstract class AbstractMedia implements ExportInterface, MediaCollectionInterfac
/**
* @param string|null $path
* @return void
*/
public function setPath(?string $path): void
{
@@ -166,6 +169,7 @@ abstract class AbstractMedia implements ExportInterface, MediaCollectionInterfac
/**
* @param string $name
* @param MediaObjectInterface|null $file
* @return void
*/
public function add($name, $file)
{
@@ -190,6 +194,30 @@ abstract class AbstractMedia implements ExportInterface, MediaCollectionInterfac
}
}
/**
* Create Medium from a file.
*
* @param string $file
* @param array $params
* @return Medium|null
*/
public function createFromFile($file, array $params = [])
{
return MediumFactory::fromFile($file, $params);
}
/**
* Create Medium from array of parameters
*
* @param array $items
* @param Blueprint|null $blueprint
* @return Medium|null
*/
public function createFromArray(array $items = [], Blueprint $blueprint = null)
{
return MediumFactory::fromArray($items, $blueprint);
}
/**
* @param MediaObjectInterface $mediaObject
* @return ImageFile
@@ -228,6 +256,11 @@ abstract class AbstractMedia implements ExportInterface, MediaCollectionInterfac
return $media;
}
protected function fileExists(string $filename, string $destination): bool
{
return file_exists("{$destination}/{$filename}");
}
/**
* Get filename, extension and meta part.
*
@@ -288,6 +321,8 @@ abstract class AbstractMedia implements ExportInterface, MediaCollectionInterfac
protected function clearCache(): void
{
// TODO: Implement clearCache() method.
/** @var UniformResourceLocator $locator */
$locator = $this->getGrav()['locator'];
$locator->clearCache();
}
}

View File

@@ -14,6 +14,18 @@ use RocketTheme\Toolbox\ResourceLocator\UniformResourceLocator;
class GlobalMedia extends AbstractMedia
{
/** @var self */
protected static $instance;
public static function getInstance(): self
{
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
/**
* Return media path.
*

View File

@@ -1331,12 +1331,12 @@ class TwigExtension extends AbstractExtension implements GlobalsInterface
* If still not found, will use the theme's configuration value,
* If still not found, will use the $default value passed in
*
* @param $context Twig Context
* @param array $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
* @return mixed
*/
public function themeVarFunc($context, $var, $default = null, $page = null, $exists = false)
{
@@ -1370,10 +1370,9 @@ class TwigExtension extends AbstractExtension implements GlobalsInterface
/**
* Look for a page header variable in an array of pages working its way through until a value is found
*
* @param $context
* @param array $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
*/
@@ -1391,7 +1390,7 @@ class TwigExtension extends AbstractExtension implements GlobalsInterface
* takes an array of classes, and if they are not set on body_classes
* look to see if they are set in theme config
*
* @param $context
* @param array $context
* @param string|string[] $classes
* @return string
*/
@@ -1416,8 +1415,8 @@ class TwigExtension extends AbstractExtension implements GlobalsInterface
/**
* Returns the content of an SVG image and adds extra classes as needed
*
* @param $path
* @param $classes
* @param string $path
* @param string|null $classes
* @return string|string[]|null
*/
public static function svgImageFunction($path, $classes = null, $strip_style = false)

View File

@@ -134,7 +134,7 @@ abstract class Utils
* Helper method to find the full path to a file, be it a stream, a relative path, or
* already a full path
*
* @param $path
* @param string $path
* @return string
*/
public static function fullPath($path)

View File

@@ -95,7 +95,7 @@ class PermissionsReader
// Build dependency tree.
foreach ($dependencies as $type => $dep) {
foreach ($dep as $k => &$val) {
foreach (get_object_vars($dep) as $k => &$val) {
if (null === $val) {
$val = $dependencies[$k] ?? new \stdClass();
}

View File

@@ -134,7 +134,7 @@ class Filesystem implements FilesystemInterface
*/
public function basename(string $path, ?string $suffix = null): string
{
return basename($path, $suffix);
return $suffix ? basename($path, $suffix) : basename($path);
}
/**

View File

@@ -270,7 +270,7 @@ trait PageTranslateTrait
/** @var Language $language */
$language = $grav['language'];
$languageCode = $languageCode ?? $language->getLanguage();
$languageCode = $languageCode ?? ($language->getLanguage() ?: '');
if ($languageCode === '' && $fallback) {
return $language->getFallbackLanguages(null, true);
}

View File

@@ -159,8 +159,9 @@ trait FlexMediaTrait
$list = [];
foreach ($files as $field => $group) {
$field = (string)$field;
// Ignore files without a field and resized images.
if ($field === '' || \strpos((string)$field, '/')) {
if ($field === '' || \strpos($field, '/')) {
continue;
}

View File

@@ -59,6 +59,9 @@ class FormFlashFile implements UploadedFileInterface, \JsonSerializable
}
$resource = \fopen($tmpFile, 'rb');
if (false === $resource) {
throw new \RuntimeException('No temporary file');
}
return Stream::create($resource);
}

View File

@@ -18,10 +18,19 @@ class Stream implements StreamInterface
{
use StreamDecoratorTrait;
/**
* @param string|resource|StreamInterface $body
* @return static
*/
public static function create($body = '')
{
return new static($body);
}
/**
* Stream constructor.
*
* @param string $body
* @param string|resource|StreamInterface $body
*/
public function __construct($body = '')
{