cms icon indicating copy to clipboard operation
cms copied to clipboard

Allow DI on ImageTransform

Open timkelty opened this issue 1 year ago • 0 comments

Description

The goal is to allow developers to write an ImageTransformer that builds URLs using properties other than those included in \craft\models\ImageTransform, eg blur.

This PR does 2 things:

  • Replaces new instance creation with createObject so \craft\models\ImageTransform can be customized through DI.
  • Calls \craft\models\ImageTransform::toArray without any args, so that all properties are returned.

Related issues

https://github.com/craftcms/cms/pull/15062

Example usage

Module/Plugin

<?php

namespace modules\testmodule;

use Craft;
use craft\elements\Asset;
use craft\events\DefineAssetUrlEvent;
use craft\helpers\UrlHelper;
use craft\models\ImageTransform;
use yii\base\Event;
use yii\base\Module as BaseModule;

/**
 * @method static Module getInstance()
 */
class Module extends BaseModule
{
    public function init(): void
    {
        parent::init();

        // Defer most setup tasks until Craft is fully initialized
        Craft::$app->onInit(function() {
            Craft::$container->set(ImageTransform::class, [
                'class' => \modules\testmodule\ImageTransform::class,
            ]);


            Event::on(
                Asset::class,
                Asset::EVENT_DEFINE_URL,
                function (DefineAssetUrlEvent $event) {
                    $transform = $event->transform;

                    if (!$transform) {
                        return;
                    }

                    /** @var Asset $asset */
                    $asset = $event->sender;

                    $url = UrlHelper::urlWithParams(
                        "https://foo.com/$asset->path",
                        $transform,
                    );

                    $event->url = $url;
                });
        });
    }
}
<?php

namespace modules\testmodule;

class ImageTransform extends \craft\models\ImageTransform
{
    public int $blur = 0;
}

Template

{% set transform = {
    mode: 'crop',
    width: 100,
    height: 100,
    quality: 75,
    blur: 40,
} %}
{% set asset = craft.assets().one() %}

{{ asset.getUrl(transform) }}
{{ asset.getImg(transform, ['1.5x', '2.0']) }}

timkelty avatar Sep 03 '24 17:09 timkelty