Skip to content

Commit 050208f

Browse files
Fix image transforms ignoring focal points (#145)
* Fix non-standard props in non-cloud envs * Fix image transforms ignoring focal points The fields() override called normalize(), which mutated the model by writing computed CF values (fit, gravity, etc.) onto $this. Since Yii's toArray() calls fields(), any serialization path (e.g. srcset via getUrlsBySize) would pre-fill gravity from position, blocking the focal point override in ImageTransformer. Remove fields()/normalize() and refactor toOptions() to compute derived values into the returned array without mutating the model. Fixes #144 Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * code style --------- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
1 parent 468a4f4 commit 050208f

File tree

3 files changed

+17
-23
lines changed

3 files changed

+17
-23
lines changed

src/AppConfig.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,13 @@
77
use craft\cachecascade\CascadeCache;
88
use craft\cloud\fs\TmpFs;
99
use craft\cloud\Helper as CloudHelper;
10-
use craft\cloud\imagetransforms\ImageTransform;
1110
use craft\cloud\queue\SqsQueue;
1211
use craft\cloud\web\AssetManager;
1312
use craft\db\Table;
1413
use craft\debug\Module as DebugModule;
1514
use craft\fs\Temp;
1615
use craft\helpers\App;
1716
use craft\log\MonologTarget;
18-
use craft\models\ImageTransform as CraftImageTransform;
1917
use craft\queue\Queue as CraftQueue;
2018
use yii\caching\ArrayCache;
2119
use yii\redis\Cache as RedisCache;
@@ -159,7 +157,6 @@ private function getDefinitions(): array
159157
{
160158
return [
161159
Temp::class => TmpFs::class,
162-
CraftImageTransform::class => ImageTransform::class,
163160
MonologTarget::class => function($container, $params, $config) {
164161
return new MonologTarget([
165162
'logContext' => false,

src/Module.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
use craft\base\Event;
77
use craft\base\Model;
88
use craft\cloud\fs\AssetsFs;
9+
use craft\cloud\imagetransforms\ImageTransform;
910
use craft\cloud\imagetransforms\ImageTransformer;
1011
use craft\cloud\twig\TwigExtension;
1112
use craft\cloud\web\assets\uploader\UploaderAsset;
@@ -19,6 +20,7 @@
1920
use craft\helpers\App;
2021
use craft\helpers\ConfigHelper;
2122
use craft\log\MonologTarget;
23+
use craft\models\ImageTransform as CraftImageTransform;
2224
use craft\services\Fs as FsService;
2325
use craft\services\ImageTransforms;
2426
use craft\web\Application as WebApplication;
@@ -83,6 +85,10 @@ public function bootstrap($app): void
8385
),
8486
]);
8587

88+
// Replace ImageTransform with cloud ImageTransform via DI
89+
// We do this here and not in AppConfig, because non-Cloud envs need it to support non-standard transform props
90+
Craft::$container->set(CraftImageTransform::class, ImageTransform::class);
91+
8692
if (Helper::isCraftCloud()) {
8793
$this->bootstrapCloud($app);
8894
}

src/imagetransforms/ImageTransform.php

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -110,32 +110,23 @@ class ImageTransform extends \craft\models\ImageTransform
110110

111111
public ?float $zoom = null;
112112

113-
/**
114-
* @inheritdoc
115-
*/
116-
public function fields(): array
117-
{
118-
$this->normalize();
119-
return parent::fields();
120-
}
121-
122-
public function normalize(): static
123-
{
124-
$this->format = $this->computeFormat();
125-
$this->fit = $this->computeFit();
126-
$this->background = $this->computeBackground();
127-
$this->gravity = $this->computeGravity();
128-
return $this;
129-
}
130-
131113
public function toOptions(): array
132114
{
133115
$reflection = new \ReflectionClass($this);
134-
$this->normalize();
135116

136-
return Collection::make($reflection->getProperties(\ReflectionProperty::IS_PUBLIC))
117+
$options = Collection::make($reflection->getProperties(\ReflectionProperty::IS_PUBLIC))
137118
->filter(fn($property) => $property->getDeclaringClass()->getName() === self::class)
138119
->mapWithKeys(fn($property) => [$property->getName() => $property->getValue($this)])
120+
->all();
121+
122+
// Compute derived Cloudflare values from Craft's base transform settings,
123+
// without mutating the model (so the same instance can be safely reused).
124+
$options['format'] = $this->computeFormat();
125+
$options['fit'] = $this->computeFit();
126+
$options['background'] = $this->computeBackground();
127+
$options['gravity'] ??= $this->computeGravity();
128+
129+
return Collection::make($options)
139130
->filter(fn($value) => $value !== null)
140131
->all();
141132
}

0 commit comments

Comments
 (0)