diff --git a/Neos.Fusion/Classes/FusionObjects/ComponentImplementation.php b/Neos.Fusion/Classes/FusionObjects/ComponentImplementation.php index 873128d0c2d..8d7f9da3209 100644 --- a/Neos.Fusion/Classes/FusionObjects/ComponentImplementation.php +++ b/Neos.Fusion/Classes/FusionObjects/ComponentImplementation.php @@ -80,8 +80,10 @@ protected function getProps(array $context): \ArrayAccess protected function render(array $context) { $this->runtime->pushContextArray($context); - $result = $this->runtime->render($this->path . '/renderer'); - $this->runtime->popContext(); - return $result; + try { + return $this->runtime->render($this->path . '/renderer'); + } finally { + $this->runtime->popContext(); + } } } diff --git a/Neos.Media.Browser/Classes/Controller/AssetController.php b/Neos.Media.Browser/Classes/Controller/AssetController.php index c17b24b671c..a4ee773a8ca 100644 --- a/Neos.Media.Browser/Classes/Controller/AssetController.php +++ b/Neos.Media.Browser/Classes/Controller/AssetController.php @@ -50,6 +50,7 @@ use Neos\Media\Domain\Repository\AssetRepository; use Neos\Media\Domain\Repository\TagRepository; use Neos\Media\Domain\Service\AssetService; +use Neos\Media\Domain\Service\AssetVariantGenerator; use Neos\Media\Exception\AssetServiceException; use Neos\Media\TypeConverter\AssetInterfaceConverter; use Neos\Neos\Controller\BackendUserTranslationTrait; @@ -140,6 +141,12 @@ class AssetController extends ActionController */ protected $assetSourceService; + /** + * @Flow\Inject + * @var AssetVariantGenerator + */ + protected $assetVariantGenerator; + /** * @var AssetSourceInterface[] */ @@ -469,6 +476,32 @@ public function variantsAction(string $assetSourceIdentifier, string $assetProxy } } + /** + * Create missing variants for the given image + * + * @param string $assetSourceIdentifier + * @param string $assetProxyIdentifier + * @param string $overviewAction + * @throws StopActionException + * @throws UnsupportedRequestTypeException + */ + public function createVariantsAction(string $assetSourceIdentifier, string $assetProxyIdentifier, string $overviewAction): void + { + $assetSource = $this->assetSources[$assetSourceIdentifier]; + $assetProxyRepository = $assetSource->getAssetProxyRepository(); + + $assetProxy = $assetProxyRepository->getAssetProxy($assetProxyIdentifier); + $asset = $this->persistenceManager->getObjectByIdentifier($assetProxy->getLocalAssetIdentifier(), Asset::class); + + /** @var VariantSupportInterface $originalAsset */ + $originalAsset = ($asset instanceof AssetVariantInterface ? $asset->getOriginalAsset() : $asset); + + $this->assetVariantGenerator->createVariants($originalAsset); + $this->assetRepository->update($originalAsset); + + $this->redirect('variants', null, null, ['assetSourceIdentifier' => $assetSourceIdentifier, 'assetProxyIdentifier' => $assetProxyIdentifier, 'overviewAction' => $overviewAction]); + } + /** * @return void * @throws NoSuchArgumentException diff --git a/Neos.Media.Browser/Configuration/Policy.yaml b/Neos.Media.Browser/Configuration/Policy.yaml index 24e025b8edb..a237114296c 100644 --- a/Neos.Media.Browser/Configuration/Policy.yaml +++ b/Neos.Media.Browser/Configuration/Policy.yaml @@ -6,7 +6,7 @@ privilegeTargets: 'Neos.Media.Browser:ManageAssets': label: Allowed to manage assets - matcher: 'method(Neos\Media\Browser\Controller\(Asset|Image)Controller->(index|new|show|edit|update|initializeCreate|create|replaceAssetResource|updateAssetResource|initializeUpload|upload|tagAsset|delete|createTag|editTag|updateTag|deleteTag|addAssetToCollection|relatedNodes|variants)Action()) || method(Neos\Media\Browser\Controller\ImageVariantController->(update)Action())' + matcher: 'method(Neos\Media\Browser\Controller\(Asset|Image)Controller->(index|new|show|edit|update|initializeCreate|create|replaceAssetResource|updateAssetResource|initializeUpload|upload|tagAsset|delete|createTag|editTag|updateTag|deleteTag|addAssetToCollection|relatedNodes|variants|createVariants)Action()) || method(Neos\Media\Browser\Controller\ImageVariantController->(update)Action())' 'Neos.Media.Browser:AssetUsage': label: Allowed to calculate asset usages diff --git a/Neos.Media.Browser/Resources/Private/Templates/Asset/Variants.html b/Neos.Media.Browser/Resources/Private/Templates/Asset/Variants.html index 0c035452335..e024a452100 100644 --- a/Neos.Media.Browser/Resources/Private/Templates/Asset/Variants.html +++ b/Neos.Media.Browser/Resources/Private/Templates/Asset/Variants.html @@ -24,6 +24,13 @@ + + + diff --git a/Neos.Media.Browser/Resources/Private/Translations/en/Main.xlf b/Neos.Media.Browser/Resources/Private/Translations/en/Main.xlf index 81cddf67e1e..07f3354ed02 100644 --- a/Neos.Media.Browser/Resources/Private/Translations/en/Main.xlf +++ b/Neos.Media.Browser/Resources/Private/Translations/en/Main.xlf @@ -427,6 +427,9 @@ No document node found for this node + + Create missing variants + diff --git a/Neos.Media/Classes/Domain/Service/AssetVariantGenerator.php b/Neos.Media/Classes/Domain/Service/AssetVariantGenerator.php index 4a8224515c0..69d4c12e379 100644 --- a/Neos.Media/Classes/Domain/Service/AssetVariantGenerator.php +++ b/Neos.Media/Classes/Domain/Service/AssetVariantGenerator.php @@ -127,6 +127,11 @@ public function createVariant(AssetInterface $asset, string $presetIdentifier, s $createdVariant = null; $preset = $this->getVariantPresets()[$presetIdentifier] ?? null; if ($preset instanceof VariantPreset && $preset->matchesMediaType($asset->getMediaType())) { + $existingVariant = $asset->getVariant($presetIdentifier, $variantIdentifier); + if ($existingVariant !== null) { + return $existingVariant; + } + $variantConfiguration = $preset->variants()[$variantIdentifier] ?? null; if ($variantConfiguration instanceof Configuration\Variant) { diff --git a/Neos.Media/Classes/Package.php b/Neos.Media/Classes/Package.php index 299f827307c..dd5b7b06fb5 100644 --- a/Neos.Media/Classes/Package.php +++ b/Neos.Media/Classes/Package.php @@ -11,8 +11,10 @@ * source code. */ +use Neos\Flow\Configuration\ConfigurationManager; use Neos\Flow\Core\Bootstrap; use Neos\Flow\Package\Package as BasePackage; +use Neos\Media\Domain\Model\AssetInterface; use Neos\Media\Domain\Model\ImportedAssetManager; use Neos\Media\Domain\Service\AssetService; use Neos\Media\Domain\Service\AssetVariantGenerator; @@ -30,7 +32,12 @@ class Package extends BasePackage public function boot(Bootstrap $bootstrap) { $dispatcher = $bootstrap->getSignalSlotDispatcher(); - $dispatcher->connect(AssetService::class, 'assetCreated', AssetVariantGenerator::class, 'createVariants'); + $dispatcher->connect(AssetService::class, 'assetCreated', function (AssetInterface $asset) use ($bootstrap) { + $configurationManager = $bootstrap->getObjectManager()->get(ConfigurationManager::class); + if ($configurationManager->getConfiguration(ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'Neos.Media.autoCreateImageVariantPresets')) { + $bootstrap->getObjectManager()->get(AssetVariantGenerator::class)->createVariants($asset); + } + }); $dispatcher->connect(AssetService::class, 'assetCreated', ThumbnailGenerator::class, 'createThumbnails'); $dispatcher->connect(AssetService::class, 'assetCreated', ImportedAssetManager::class, 'registerCreatedAsset'); $dispatcher->connect(AssetService::class, 'assetRemoved', ImportedAssetManager::class, 'registerRemovedAsset'); diff --git a/Neos.Media/Configuration/Settings.yaml b/Neos.Media/Configuration/Settings.yaml index 035e4020d23..8025a3d5774 100644 --- a/Neos.Media/Configuration/Settings.yaml +++ b/Neos.Media/Configuration/Settings.yaml @@ -65,7 +65,7 @@ Neos: # Variant presets variantPresets: [] # Automatically create asset variants for configured presets when assets are added - autoCreateImageVariantPresets: false + autoCreateImageVariantPresets: true thumbnailGenerators: diff --git a/Neos.Media/Documentation/VariantPresets.rst b/Neos.Media/Documentation/VariantPresets.rst index 02976ec41b2..d43dd11e921 100644 --- a/Neos.Media/Documentation/VariantPresets.rst +++ b/Neos.Media/Documentation/VariantPresets.rst @@ -92,14 +92,14 @@ The following example shows the required structure and possible fields of the pr options: aspectRatio: '1:1' -The automatic variant generation for new assets has to be enabled via setting as -by default this feature is disabled. +The automatic variant generation for new assets is active by default. +It can be disabled via setting: .. code-block:: yaml Neos: Media: - autoCreateImageVariantPresets: true + autoCreateImageVariantPresets: false To show and edit the variants in the media module the variants tab has to be enabled. diff --git a/Neos.Neos/Documentation/Appendixes/ChangeLogs/7316.rst b/Neos.Neos/Documentation/Appendixes/ChangeLogs/7316.rst new file mode 100644 index 00000000000..512236f16b2 --- /dev/null +++ b/Neos.Neos/Documentation/Appendixes/ChangeLogs/7316.rst @@ -0,0 +1,175 @@ +`7.3.16 (2023-10-21) `_ +================================================================================================ + +Overview of merged pull requests +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +`BUGFIX: Only discard nodes in same workspace `_ +--------------------------------------------------------------------------------------------------------------- + +* Resolves: `#4577 `_ + +* Packages: ``ContentRepository`` + +`BUGFIX: Load all thumbnails for an asset to skip further requests `_ +------------------------------------------------------------------------------------------------------------------------------------ + +For the usecase of images with responsive variants this change prevents additional database requests for each additional variant of an image. + +This can greatly reduce the number of queries on pages with many source tags or sources attributes for pictures and images. + +**Review instructions** + +As soon as an image is rendered in several sizes on a page the patch should skip additional db requests in the thumbnails repository. +Persistent resources and image entities are still queried as via the node property getter and to resolve the thumbnail. + + +* Packages: ``Neos`` ``Media`` + +`BUGFIX: Allow unsetting thumbnail presets `_ +------------------------------------------------------------------------------------------------------------ + +* Resolves: `#3544 `_ + +* Packages: ``Neos`` ``Media`` + +`BUGFIX: Don’t query for abstract nodetypes in nodedata repository `_ +-------------------------------------------------------------------------------------------------------------------------------------- + +As abstract nodetypes don't (shouldn't) appear in the database it makes no sense to query them. + +This is a regression that was introduced a long time ago, when the default parameter to include abstract nodetypes was added to the ``getSubNodeTypes`` method in the ``NodeTypeManager`` without adjusting the call in the ``NodeDataRepository->getNodeTypeFilterConstraintsForDql`` which relied on the previous behaviour. + +The call in the method ``getNodeTypeFilterConstraints`` was fixed some years ago, but that method seems unused. + +* Packages: ``ContentRepository`` + +`BUGFIX: Consistently initialize asset sources via `createFromConfiguration` `_ +---------------------------------------------------------------------------------------------------------------------------------------------- + +fixes: `#3965 `_ + +**The Problem** + +The case at hand was an asset source that uses a value object to validate the incoming asset source options. I expected to be able to define a promoted constructor property with said value object as its declared type: + +```php +final class MyAssetSource implements AssetSourceInterface +{ + public function __construct( + private readonly string $assetSourceIdentifier, + private readonly Options $options + ) { + } + + /* ... */ +} +``` + +...and initialize the value object in the ``createFromConfiguration`` static factory method defined by the ``AssetSourceInterface``: + +```php +final class MyAssetSource implements AssetSourceInterface +{ + /* ... */ + + public static function createFromConfiguration(string $assetSourceIdentifier, array $assetSourceOptions): AssetSourceInterface + { + return new static( + $assetSourceIdentifier, + Options::fromArray($assetSourceOptions) + ); + } +} +``` + +This failed with a Type Error, because the ``AssetSourceService``, which is responsible for initializing asset sources, at one point does not utilize ``createFromConfiguration`` to perform initialization, but calls the asset source constructor directly: + +https://github.com/neos/neos-development-collection/blob/`a4791b623161259b31d2d11b343310bd7ef76507 `_/Neos.Media/Classes/Domain/Service/AssetSourceService.php#L178 + +**The Solution** + +I adjusted the aforementioned routine of the ``AssetSourceService`` to use the ``AssetSourceInterface``-defined ``createFromConfiguration`` static factory method instead of the asset source's constructor. + +Even though the pattern I described above only makes sense in a PHP >8.0 environment, I decided to target Neos 7.3 with this PR, because it should constitute a non-breaking bugfix. + +* Packages: ``Neos`` ``Media`` + +`BUGFIX: Guard that Fusion path cannot be empty `_ +----------------------------------------------------------------------------------------------------------------- + +Previously in php 7.4 this ``Neos\\Fusion\\Exception\\MissingFusionObjectException`` was thrown + +> No Fusion object found in path "" + +but with php 8 this ``ValueError`` is thrown which is unexpected + +> strrpos(): Argument `#3 ``_($offset) must be contained in argument ``#1 `_($haystack) + +This change takes care of throwing an explicit ``Neos\\Fusion\\Exception`` instead: + +> Fusion path cannot be empty. + + +-------- + +This error was noticed in the out of band rendering, when there is no content element wrapping: https://discuss.neos.io/t/argument-3-offset-must-be-contained-in-argument-1-haystack/6416/4 + +image + + + +**Upgrade instructions** + +**Review instructions** + + +* Packages: ``Neos`` ``Fusion`` + +`BUGFIX: Fix `NodeType` `getTypeOfAutoCreatedChildNode` and `getPropertyType` `_ +----------------------------------------------------------------------------------------------------------------------------------------------- + +resolves partially `#4333 `_ +resolves partially `#4344 `_ + +**Upgrade instructions** + +**Review instructions** + + +* Packages: ``Neos`` ``ContentRepository`` + +`TASK: Fix documentation builds `_ +------------------------------------------------------------------------------------------------- + +… by pinning updated dependencies. + +**Review instructions** + +Best is to see if the builds succeed on RTD again with this merged… + + +* Packages: ``Neos`` ``Media`` + +`TASK: Fix paths for Neos.Media RTD rendering setup `_ +--------------------------------------------------------------------------------------------------------------------- + +The paths need to be from the repo root, not relative to the ``.readthedocs.yaml`` file (it seems). + + +* Packages: ``Neos`` ``Media`` + +`TASK: Add configuration files for RTD `_ +-------------------------------------------------------------------------------------------------------- + +This add ``.readthedocs.yaml`` files for the collection (handling ``Neos.Neos``) and for ``neos.Media``, to solve failing documentation rendering. + +**Review instructions** + +This can be compared to the configuration we have in place for ``Neos.Flow`` in the Flow development collection. + + +* Packages: ``Media`` + +`Detailed log `_ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/Neos.Neos/composer.json b/Neos.Neos/composer.json index cf50b030147..8d7ace8e9a7 100644 --- a/Neos.Neos/composer.json +++ b/Neos.Neos/composer.json @@ -7,18 +7,18 @@ "description": "An open source Content Application Platform based on Flow. A set of core Content Management features is resting within a larger context that allows you to build a perfectly customized experience for your users.", "require": { "php": "^8.0", - "neos/diff": "~8.0.0", + "neos/diff": "self.version", "neos/flow": "~8.0.0", - "neos/media-browser": "~8.0.0", + "neos/media-browser": "self.version", "neos/party": "*", "neos/twitter-bootstrap": "*", - "neos/content-repository": "~8.0.0", - "neos/fusion": "~8.0.0", + "neos/content-repository": "self.version", + "neos/fusion": "self.version", "neos/fusion-afx": "self.version", "neos/fusion-form": "^1.0 || ^2.0", "neos/fluid-adaptor": "~8.0.0", "behat/transliterator": "~1.0", - "neos/media": "~8.0.0" + "neos/media": "self.version" }, "suggest": { "neos/site-kickstarter": "Helps with creating new site packages for Neos.",