These change affects developers of image toolkit and image toolkit operations plugins only. Image style effects are not impacted, as the API surface that ImageStyleEffect plugins consume is not touched.
The architecture of the image processing toolkits has changed. All the image related data is now stored in an implementation of ImageInterface that is provided by each toolkit. Every state property is removed from ImageToolkit and ImageToolkitOperation plugins, so that they can only be instantiated once, and pass the ImageInterface object with its data to their methods.
In practice:
- the
ImageFactoryreceives a request to provide an image - it determines what is the toolkit to be used
- the toolkit informs the factory about the image object implementing
ImageInterfacethat should be used in connection with the toolkit - the factory only creates an instance of that image object
ImageToolkitandImageToolkitOperationplugin managers create singletons of each plugin needed when needed- the image object is passed to the singletons' methods
How to convert an ImageToolkit plugin to stateless
- Add to the toolkit plugin attribute the
$imageClassparameter, referring to a class implementing anImageInterfaceobject. For example, taking fromGDToolkit:
#[ImageToolkit( id: "gd", title: new TranslatableMarkup("GD2 image manipulation toolkit"), imageClass: GdImageWrapper::class, )] - Move any state property from the toolkit plugin to the class implementing
ImageInterface - Indicate that the toolkit is stateless, adding to the toolkit code the appropriate override of the
$isStatefulproperty:
// phpcs:disable /** * {@inheritdoc} */ public bool $isStateful { get => FALSE; } // phpcs:enable - Change the methods implementing the
ImageToolkitInterfaceAPI so that they receive and handle theImageInterfaceobject:
- public function getHeight() { + public function getHeight($image = NULL) {
Deprecations
Existing toolkits and toolkit operations still work under a backwards compatibility (BC) layer, that will be retained until they are converted to stateless. A number of methods and properties have been deprecated:
ImageInterface::getToolkit()--> Use::toolkit()on stateless toolkits instead.ImageToolkitInterface::getSource()--> Get image source path viaImageInterface::getSource()instead.ImageToolkitInterface::setSource()--> Set image source path viaImageInterface::setSource()instead.ImageToolkitBase::$isClone--> Only introduced to support backwards compatibility; there is no replacement.ImageToolkitBase::$isStateful--> Only introduced to support backwards compatibility; there is no replacement.ImageToolkitBase::$backfillImage--> Only introduced to support backwards compatibility; there is no replacement.ImageToolkitBase::$source--> Access image source path from theImageInterfaceobject directly.ImageToolkitOperationInterface::setToolkit()--> Stateless toolkits must not be injected to the toolkit operation.ImageToolkitOperationBase::$needsToolkitInjection--> Only introduced to support backwards compatibility; there is no replacement.ImageToolkitOperationBase::$toolkit--> Stateless toolkits must not be injected to the toolkit operation.ImageToolkitOperationBase::getToolkit()--> Stateless toolkits must not be injected to the toolkit operation.GDToolkit::$image--> AccessGdImageWrapper::$gdImagethrough its getter/setter instead.GDToolkit::$type--> AccessGdImageWrapper::$typethrough its getter/setter instead.GDToolkit::$preLoadInfo--> AccessGdImageWrapper::$preLoadInfothrough its getter/setter instead.GDToolkit::setImage()--> UseGdImageWrapper::setGdImageObject()instead.GDToolkit::getImage()--> UseGdImageWrapper::getGdImageObject()instead.GDToolkit::setType()--> UseGdImageWrapper::setType()instead.GDToolkit::getType()--> UseGdImageWrapper::getType()instead.