Updated: Comment #0

Problem/Motivation

ImageStyle::createDerivative is a 'black box', given an image style andi source/target URIs you get effects applied to source to obtain target, but you can not interact with the process.

In a contrib module, I am using an effect to set a canvas, and further effects add on top of that canvas. The 'first' effect is setting a parameter (i.e. the color to use if the canvas has to be resized by following effects) that is 'carried on' along the subsequent effects.

I am saving the setting of the parameter to be carried on in a static variable, and the other effects are reading that variable.

This works fine, but the only potential issue is that to be 'clean', I would like to reset that static variable before I invoke createDerivative, so that there are no risks to use a value that is coming from a previous image style.

Proposed resolution

Introduce a new hook like e.g. hook_image_style_create_derivative that modules can use to do their stuff? Something like hook_image_style_flush.

Remaining tasks

  • Agree
  • Write patch

User interface changes

None

API changes

One more hook

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

mondrake’s picture

Status: Active » Needs review
FileSize
2.01 KB

Patch.

claudiu.cristea’s picture

Hey @mondrake, isn't this related #1826362: ImageEffects of the same image style should be able to pass variables between them?

Check also my comment from #1826362-7: ImageEffects of the same image style should be able to pass variables between them. I wonder how can we merge these 2 issues. Definitely I see the need that effects of the same image style should be able to pass variables between them. I just want to find a more modern way to do this without placing hook invocations all over the code.

dawehner’s picture

+++ b/core/modules/image/image.api.php
@@ -38,6 +38,36 @@ function hook_image_style_flush($style) {
+function hook_image_create_derivative($style, $original_uri, $derivative_uri) {

It would be good to typehint the image style in the actual function signature.

mondrake’s picture

#2 - @claudiu.cristea well I guess we may add to the ImageStyle entity a protected variable (being an array of parameters that the effects can get/set) and public getters/setters for the effects to use.

Then passing the $style to applyEffect would enable doing what you say in #2, i.e. passing variables between effects, as you commented in #1826362-7: ImageEffects of the same image style should be able to pass variables between them.

This would be good for my use case (Textimage module sets a background color in an effect, and following effects take that if the image needs to be resized).

However, I believe a hook in this case is still needed if we want to enable modules to initialize those parameters upon calling createDerivative and before the first effect is applied, or to take other actions (e.g. logging the request like in the example in the patch).

I believe I can write a patch in this sense, but opinions first?

mondrake’s picture

This patch combines #1 with #1826362: ImageEffects of the same image style should be able to pass variables between them, plus introduces a 'parameters' protected variable in ImageStyle with getters/setter. The idea is that effects can access a pool of style-level parameters at run-time, during the creation of a derivative. So image effects can effectively transfer information between them if needed.

Status: Needs review » Needs work

The last submitted patch, 2098247-style_parameters-5.patch, failed testing.

mondrake’s picture

Status: Needs work » Needs review
Issue tags: +API change
FileSize
3.04 KB
16.74 KB

With tests.

Status: Needs review » Needs work

The last submitted patch, 2098247-style_parameters-7.patch, failed testing.

mondrake’s picture

Oh yes

mondrake’s picture

Status: Needs work » Needs review
fietserwin’s picture

Status: Needs review » Needs work

Why add a parameter at all?
By passing info via a parameter construct, both effects (the "setting" and "receiving" one) become dependent from each other, while only the setting one should have to know about this. With getConfiguration() and setConfiguration() on ImageEffectInterface (being a ConfigurablePluginInterface), we can already hack into other effects if we have access to the effect.

Thus if a "special canvas" effect wants to influence the (background) color of a subsequent text, resize or rotate effect, that effect should be happily unaware of its context (no way that the core rotate effect is going to use a parameter set by a contrib effect). So, it should be the special canvas effect that alters the color value in the configuration of the rotate, text or whatever effect.

Aside: if you insist on adding a parameter property, make it a key-value store and you don't have to add any adding, setting or deleting method yourself, not in the interface, not in this class. Compare my patch in #2168511: Allow to pass save options to ImageInterface::save.

What context should be passed to an effect?

  • We (imagecache_actions) have had (valid) feature request in which there was a wish to alter the target URI (change image format). So is only passing in the image style enough?
  • How sure are we that an image effect will never be used outside an image style? An example of an image effect outside an image style could be resizing an image field directly on upload. That one is now calling the resize operation on an Image directly, whereas, IMO, it should be calling an image effect because an image effect should do the (toolkit agnostic) calculations.
  • If we are absolutely sure about the tie between ImageStyle and ImageEffect, I think that a (protected) property $imageStyle on ImageEffect would be more appropriate.

So are we passing in specific context or too few context? My idea for now: we can add the imageStyle parameter to applyEffect, but make it optional by adding "= NULL".

mondrake’s picture

Status: Needs work » Closed (duplicate)

Marking as duplicate of #1826362: ImageEffects of the same image style should be able to pass variables between them, let's continue there. Introduction of ThirdPartySettingsTrait to the ImageStyle solves part of this, we need to make sure that these are accessible from the effects.

mondrake’s picture