Skip to content

Commit

Permalink
Update various functions and parameters for output and image processing
Browse files Browse the repository at this point in the history
This commit refactors several functions in different files, most notably modifying image processing in both GDImageProcessor and ImagickImageProcessor to handle non-square images more accurately. An array of favicons was also added to the test config, and various parameter types were updated in multiple files. Several functions have been streamlined for greater efficiency and clarity.
  • Loading branch information
Spomky committed Apr 28, 2024
1 parent 826b264 commit efd300b
Show file tree
Hide file tree
Showing 16 changed files with 435 additions and 82 deletions.
34 changes: 22 additions & 12 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,11 @@ parameters:
count: 1
path: src/Dto/BackgroundSync.php

-
message: "#^Class SpomkyLabs\\\\PwaBundle\\\\Dto\\\\Favicons has an uninitialized property \\$src\\. Give it default value or assign it in the constructor\\.$#"
count: 1
path: src/Dto/Favicons.php

-
message: "#^Class SpomkyLabs\\\\PwaBundle\\\\Dto\\\\File has an uninitialized property \\$accept\\. Give it default value or assign it in the constructor\\.$#"
count: 1
Expand Down Expand Up @@ -440,14 +445,24 @@ parameters:
count: 1
path: src/ImageProcessor/GDImageProcessor.php

-
message: "#^Parameter \\#1 \\$dst_image of function imagecopyresampled expects GdImage, GdImage\\|false given\\.$#"
count: 1
path: src/ImageProcessor/GDImageProcessor.php

-
message: "#^Parameter \\#1 \\$image of function imagealphablending expects GdImage, GdImage\\|false given\\.$#"
count: 1
path: src/ImageProcessor/GDImageProcessor.php

-
message: "#^Parameter \\#1 \\$image of function imagepng expects GdImage, GdImage\\|false given\\.$#"
count: 1
path: src/ImageProcessor/GDImageProcessor.php

-
message: "#^Parameter \\#1 \\$image of function imagesavealpha expects GdImage, GdImage\\|false given\\.$#"
count: 1
count: 2
path: src/ImageProcessor/GDImageProcessor.php

-
Expand Down Expand Up @@ -485,6 +500,11 @@ parameters:
count: 1
path: src/Normalizer/ServiceWorkerNormalizer.php

-
message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#"
count: 1
path: src/Resources/config/definition/favicons.php

-
message: "#^Call to an undefined method Symfony\\\\Component\\\\Config\\\\Definition\\\\Builder\\\\NodeDefinition\\:\\:children\\(\\)\\.$#"
count: 1
Expand Down Expand Up @@ -623,14 +643,4 @@ parameters:
-
message: "#^Method SpomkyLabs\\\\PwaBundle\\\\SpomkyLabsPwaBundle\\:\\:loadExtension\\(\\) has parameter \\$config with no value type specified in iterable type array\\.$#"
count: 1
path: src/SpomkyLabsPwaBundle.php

-
message: "#^Property SpomkyLabs\\\\PwaBundle\\\\Subscriber\\\\ManifestCompileEventListener\\:\\:\\$jsonOptions type has no value type specified in iterable type array\\.$#"
count: 1
path: src/Subscriber/ManifestCompileEventListener.php

-
message: "#^Property SpomkyLabs\\\\PwaBundle\\\\Subscriber\\\\PwaDevServerSubscriber\\:\\:\\$jsonOptions type has no value type specified in iterable type array\\.$#"
count: 1
path: src/Subscriber/PwaDevServerSubscriber.php
path: src/SpomkyLabsPwaBundle.php
41 changes: 41 additions & 0 deletions src/Dto/Favicons.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace SpomkyLabs\PwaBundle\Dto;

use Symfony\Component\Serializer\Attribute\SerializedName;

final class Favicons
{
public bool $enabled = false;

public Asset $src;

#[SerializedName('background_color')]
public null|string $backgroundColor = null;

#[SerializedName('safari_pinned_tab_color')]
public null|string $safariPinnedTabColor = null;

#[SerializedName('tile_color')]
public null|string $tileColor = null;

/**
* @var int<1, 50>|null
*/
#[SerializedName('border_radius')]
public null|int $borderRadius = null;

/**
* @var int<1, 100>|null
*/
#[SerializedName('image_scale')]
public null|int $imageScale = null;

#[SerializedName('only_high_resolution')]
public null|bool $onlyHighResolution = null;

#[SerializedName('only_tile_silhouette')]
public null|bool $onlyTileSilhouette = null;
}
10 changes: 9 additions & 1 deletion src/ImageProcessor/GDImageProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,15 @@ public function process(string $image, ?int $width, ?int $height, ?string $forma
assert($image !== false);
imagealphablending($image, true);
if ($width !== null && $height !== null) {
$image = imagescale($image, $width, $height);
if ($width === $height) {
$image = imagescale($image, $width, $height);
} else {
$newImage = imagecreatetruecolor($width, $height);
imagealphablending($newImage, false);
imagesavealpha($newImage, true);
imagecopyresampled($newImage, $image, 0, 0, 0, 0, $width, $height, imagesx($image), imagesy($image));
$image = $newImage;
}
}
ob_start();
imagesavealpha($image, true);
Expand Down
18 changes: 11 additions & 7 deletions src/ImageProcessor/ImagickImageProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,6 @@

final readonly class ImagickImageProcessor implements ImageProcessorInterface
{
public function __construct(
private int $filters = Imagick::FILTER_LANCZOS2,
private float $blur = 1,
) {
}

public function process(string $image, ?int $width, ?int $height, ?string $format): string
{
if ($width === null && $height === null) {
Expand All @@ -23,7 +17,17 @@ public function process(string $image, ?int $width, ?int $height, ?string $forma
$imagick = new Imagick();
$imagick->readImageBlob($image);
if ($width !== null && $height !== null) {
$imagick->resizeImage($width, $height, $this->filters, $this->blur, true);
if ($width === $height) {
$imagick->scaleImage($width, $height);
} else {
$imagick->scaleImage(min($width, $height), min($width, $height));
$imagick->extentImage(
$width,
$height,
-($width - min($width, $height)) / 2,
-($height - min($width, $height)) / 2
);
}
}
$imagick->setImageBackgroundColor(new ImagickPixel('transparent'));
if ($format !== null) {
Expand Down
71 changes: 71 additions & 0 deletions src/Resources/config/definition/favicons.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator;

return static function (DefinitionConfigurator $definition): void {
$definition->rootNode()
->beforeNormalization()
->ifTrue(
static fn (array $v): bool => isset($v['manifest']) && $v['manifest']['enabled'] === true && isset($v['favicons']) && $v['favicons']['enabled'] === true && isset($v['manifest']['theme_color'])
)
->then(static function (array $v): array {
$v['favicons']['background_color'] = $v['manifest']['theme_color'];
return $v;
})
->end()
->children()
->arrayNode('favicons')
->canBeEnabled()
->children()
->scalarNode('src')
->isRequired()
->info('The source of the favicon. Shall be a SVG or large PNG.')
->end()
->scalarNode('background_color')
->defaultNull()
->info(
'The background color of the application. If this value is not defined and that of the Manifest section is, the value of the latter will be used.'
)
->example(['red', '#f5ef06'])
->end()
->scalarNode('safari_pinned_tab_color')
->defaultNull()
->info('The color of the Safari pinned tab.')
->example(['red', '#f5ef06'])
->end()
->scalarNode('tile_color')
->defaultNull()
->info('The color of the tile for Windows 8+.')
->example(['red', '#f5ef06'])
->end()
->integerNode('border_radius')
->defaultNull()
->min(1)
->max(50)
->info('The border radius of the icon.')
->end()
->integerNode('image_scale')
->defaultNull()
->min(1)
->max(100)
->info('The scale of the icon.')
->end()
->booleanNode('generate_precomposed')
->defaultFalse()
->info('Generate precomposed icons. Useful for old iOS devices.')
->end()
->booleanNode('only_high_resolution')
->defaultTrue()
->info('Only high resolution icons.')
->end()
->booleanNode('only_tile_silhouette')
->defaultTrue()
->info('Only tile silhouette for Windows 8+.')
->end()
->end()
->end()
->end()
->end();
};
14 changes: 14 additions & 0 deletions src/Resources/config/services.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,15 @@
use SpomkyLabs\PwaBundle\Command\CreateScreenshotCommand;
use SpomkyLabs\PwaBundle\Command\ListCacheStrategiesCommand;
use SpomkyLabs\PwaBundle\DataCollector\PwaCollector;
use SpomkyLabs\PwaBundle\Dto\Favicons;
use SpomkyLabs\PwaBundle\Dto\Manifest;
use SpomkyLabs\PwaBundle\Dto\ServiceWorker;
use SpomkyLabs\PwaBundle\EventSubscriber\ScreenshotSubscriber;
use SpomkyLabs\PwaBundle\ImageProcessor\GDImageProcessor;
use SpomkyLabs\PwaBundle\ImageProcessor\ImagickImageProcessor;
use SpomkyLabs\PwaBundle\MatchCallbackHandler\MatchCallbackHandlerInterface;
use SpomkyLabs\PwaBundle\Service\FaviconsBuilder;
use SpomkyLabs\PwaBundle\Service\FaviconsCompiler;
use SpomkyLabs\PwaBundle\Service\FileCompilerInterface;
use SpomkyLabs\PwaBundle\Service\ManifestBuilder;
use SpomkyLabs\PwaBundle\Service\ManifestCompiler;
Expand Down Expand Up @@ -56,6 +59,17 @@
;
$container->set(ManifestCompiler::class);

/*** Favicons ***/
$container->set(FaviconsBuilder::class)
->args([
'$config' => param('spomky_labs_pwa.favicons.config'),
])
;
$container->set(Favicons::class)
->factory([service(FaviconsBuilder::class), 'create'])
;
$container->set(FaviconsCompiler::class);

/*** Service Worker ***/
$container->set(ServiceWorkerBuilder::class)
->args([
Expand Down
6 changes: 3 additions & 3 deletions src/Service/Data.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,17 @@
final readonly class Data
{
/**
* @param string[] $headers
* @param array<string, string|bool> $headers
*/
public function __construct(
public string $url,
public string $data,
public array $headers
){
) {
}

/**
* @param array<string, string> $headers
* @param array<string, string|bool> $headers
*/
public static function create(string $url, string $data, array $headers = []): self
{
Expand Down
34 changes: 34 additions & 0 deletions src/Service/FaviconsBuilder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace SpomkyLabs\PwaBundle\Service;

use SpomkyLabs\PwaBundle\Dto\Favicons;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use function assert;

final class FaviconsBuilder
{
private null|Favicons $favicons = null;

/**
* @param array<string, mixed> $config
*/
public function __construct(
private readonly DenormalizerInterface $denormalizer,
private readonly array $config,
) {
}

public function create(): Favicons
{
if ($this->favicons === null) {
$result = $this->denormalizer->denormalize($this->config, Favicons::class);
assert($result instanceof Favicons);
$this->favicons = $result;
}

return $this->favicons;
}
}
Loading

0 comments on commit efd300b

Please sign in to comment.