Skip to content

Commit

Permalink
Merge branch 'main' of github.com:ncla/statamic-responsive-images int…
Browse files Browse the repository at this point in the history
…o main
  • Loading branch information
ncla committed Feb 11, 2023
2 parents 9df29eb + 7373747 commit 3c74106
Show file tree
Hide file tree
Showing 6 changed files with 182 additions and 17 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@

All notable changes to `statamic-responsive-images` will be documented in this file

## v3.1.2 - 2023-02-11

### What's Changed

- GraphQL: let responsive field/fieldtype fail more gracefully when default breakpoint asset has not been found by @ncla in https://github.com/spatie/statamic-responsive-images/pull/208

**Full Changelog**: https://github.com/spatie/statamic-responsive-images/compare/v3.1.1...v3.1.2

## v3.1.1 - 2023-02-09

### What's Changed
Expand Down Expand Up @@ -32,6 +40,7 @@ GraphQL improvements by @ncla in https://github.com/spatie/statamic-responsive-i
- - Developers now can customize the amount of images that get generated and their exact dimensions through a custom `DimensionCalculator` that developers bind in `ServiceProvider`. Calculations can be done for each breakpoint and source, and receive `Breakpoint` / `Source` in the calculation methods, which allows to access breakpoint parameters, original asset and more. For motivation and examples of this, please see the PR and the original issue associated with it.
-
-
-
- Fix max widths config value or glide width param not being respected in some cases
- Fix floating numbers being output for width and height values for Glide endpoint, they are now rounded integers
- Placeholder now can be toggled per breakpoint
Expand All @@ -40,9 +49,11 @@ GraphQL improvements by @ncla in https://github.com/spatie/statamic-responsive-i
- Properties have been renamed to be more descriptive:
- - `value` to `minWidth`
-
-
- - `unit` to `widthUnit`
-
-
-
- Add `mimeType` property to explicitly help browsers determine what images does the `<source>` contain
- Housekeeping: add additional tests for dimension calculator and GraphQL

Expand Down
15 changes: 13 additions & 2 deletions src/GraphQL/ResponsiveField.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use GraphQL\Type\Definition\Type;
use Rebing\GraphQL\Support\Field;
use Spatie\ResponsiveImages\AssetNotFoundException;
use Spatie\ResponsiveImages\Breakpoint;
use Spatie\ResponsiveImages\Responsive;
use Statamic\Assets\Asset;
Expand All @@ -18,7 +19,11 @@ class ResponsiveField extends Field

public function type(): Type
{
return GraphQL::listOf(GraphQL::type(BreakPointType::NAME));
return GraphQL::listOf(
GraphQL::nonNull(
GraphQL::type(BreakPointType::NAME)
)
);
}

public function args(): array
Expand All @@ -32,7 +37,13 @@ protected function resolve(Asset|array $root, array $args)
return [str_replace('_', ':', $key) => $value];
})->toArray();

$responsive = new Responsive($root, new Parameters($args));
try {
$responsive = new Responsive($root, new Parameters($args));
} catch (AssetNotFoundException $e) {
logger()->error($e->getMessage());

return null;
}

return $responsive->breakPoints()->map(function (Breakpoint $breakpoint) use ($args) {
return $breakpoint->toGql($args);
Expand Down
25 changes: 18 additions & 7 deletions src/GraphQL/ResponsiveFieldType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use GraphQL\Type\Definition\ResolveInfo;
use Rebing\GraphQL\Support\Type;
use Spatie\ResponsiveImages\AssetNotFoundException;
use Spatie\ResponsiveImages\Breakpoint;
use Spatie\ResponsiveImages\Responsive;
use Statamic\Facades\GraphQL;
Expand All @@ -22,7 +23,11 @@ public function fields(): array
{
return [
'breakpoints' => [
'type' => GraphQL::listOf(GraphQL::type(BreakpointType::NAME)),
'type' => GraphQL::listOf(
GraphQL::nonNull(
GraphQL::type(BreakpointType::NAME)
)
),
'resolve' => function (array $field, array $args, ?array $context, ResolveInfo $info) {
$field = array_map(function ($value) {
if ($value instanceof Value) {
Expand All @@ -32,13 +37,19 @@ public function fields(): array
return $value;
}, $field);

$responsive = new Responsive($field['src'], new Parameters($field));
try {
$responsive = new Responsive($field['src'], new Parameters($field));

return $responsive->breakPoints()->map(function (Breakpoint $breakpoint) {
return $breakpoint->toGql([
'placeholder' => config('statamic.responsive-images.placeholder'),
]);
})->toArray();
return $responsive->breakPoints()->map(function (Breakpoint $breakpoint) {
return $breakpoint->toGql([
'placeholder' => config('statamic.responsive-images.placeholder'),
]);
})->toArray();
} catch (AssetNotFoundException $e) {
logger()->error($e->getMessage());

return null;
}
},
],
'responsive' => ResponsiveField::class,
Expand Down
11 changes: 11 additions & 0 deletions src/Responsive.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ class Responsive
/** @var Collection<Breakpoint> */
private Collection $breakpoints;

/**
* @param $assetParam
* @param Parameters $parameters
* @throws AssetNotFoundException
* @throws InvalidAssetException
*/
public function __construct($assetParam, Parameters $parameters)
{
$this->parameters = $parameters;
Expand All @@ -47,6 +53,11 @@ public function __construct($assetParam, Parameters $parameters)
}
}

/**
* @param $assetParam
* @return Asset
* @throws AssetNotFoundException
*/
private function retrieveAsset($assetParam): Asset
{
if ($assetParam instanceof Asset) {
Expand Down
136 changes: 128 additions & 8 deletions tests/Feature/GraphQLTest.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
<?php

use Facades\Statamic\Fields\BlueprintRepository;
use Illuminate\Support\Facades\Route;
use Spatie\ResponsiveImages\AssetNotFoundException;
use Spatie\ResponsiveImages\Fieldtypes\ResponsiveFieldtype;
use Statamic\Facades\Blueprint;
use Spatie\ResponsiveImages\Tests\Factories\EntryFactory;
Expand All @@ -13,10 +15,10 @@ function assertMatchesJsonSnapshotWithoutSvg($value)
assertMatchesJsonSnapshot($value);
}

function createEntryWithResponsiveField()
function createEntryWithField($additionalFieldConfig = [], $additionalEntryData = [])
{
$article = Blueprint::makeFromFields([
'hero' => [
'hero' => array_merge([
'type' => 'responsive',
'container' => 'test_container',
'max_files' => 1,
Expand All @@ -30,7 +32,7 @@ function createEntryWithResponsiveField()
'listable' => 'hidden',
'instructions_position' => 'above',
'visibility' => 'visible',
],
], $additionalFieldConfig),
]);

BlueprintRepository::partialMock()->shouldReceive('in')->with('collections/blog')->andReturn(collect([
Expand All @@ -39,9 +41,7 @@ function createEntryWithResponsiveField()

(new EntryFactory)->collection('blog')->id('1')->data([
'title' => 'Responsive Images addon is awesome',
'hero' => [
'src' => 'test_container::test.jpg',
],
'hero' => empty($additionalEntryData) ? ['src' => 'test.jpg'] : $additionalEntryData,
])->create();
}

Expand Down Expand Up @@ -107,7 +107,7 @@ function createEntryWithResponsiveField()
config()->set('statamic.responsive-images.webp', false);
config()->set('statamic.responsive-images.placeholder', false);

createEntryWithResponsiveField();
createEntryWithField();

$query = '
{
Expand Down Expand Up @@ -215,7 +215,7 @@ function createEntryWithResponsiveField()
});

test('responsive field accepts responsive fieldtype data', function () {
createEntryWithResponsiveField();
createEntryWithField();

$query = '
{
Expand Down Expand Up @@ -276,4 +276,124 @@ function createEntryWithResponsiveField()

expect($response['asset']['responsive'][0]['sources'][0]['srcSet'])->toContain('?filt=greyscale');
expect($response['asset']['responsive'][1]['sources'][0]['srcSet'])->toContain('?filt=greyscale');
});

it('fails silently and returns null when asset is not found when using fieldtype data', function () {
createEntryWithField([], ['src' => 'not-exist.jpg']);

$query = '
{
entry(id: "1") {
title
... on Entry_Blog_Article {
hero {
breakpoints {
sources {
srcSet
}
}
}
}
}
}
';

$response = $this
->withoutExceptionHandling()
->postJson('/graphql/', ['query' => $query])
->getContent();

$response = json_decode($response, true);

expect(isset($response['errors']))->toBeFalse();
expect($response['data']['entry']['hero']['breakpoints'])->toBeNull();
});

it('fails silently and returns null when asset is not found when using responsive field on asset', function () {
test()->createEntryWithField(
['type' => 'assets'],
'not-exist.jpg'
);

$query = '
{
entry(id: "1") {
title
... on Entry_Blog_Article {
hero {
responsive(placeholder: false, webp: false) {
asset {
id
}
label
minWidth
widthUnit
ratio
sources {
format
mimeType
minWidth
mediaWidthUnit
mediaString
srcSet
}
}
}
}
}
}
';

$response = $this
->withoutExceptionHandling()
->postJson('/graphql/', ['query' => $query])
->getContent();

$response = json_decode($response, true);

expect(isset($response['errors']))->toBeFalse();
expect($response['data']['entry']['hero'])->toBeNull();
});

it('missing lg breakpoint asset uses default breakpoint asset instead', function () {
test()->createEntryWithField(
[
'breakpoints' => [
'lg'
]
],
[
'src' => 'test.jpg',
'lg:src' => 'not-exist.jpg',
]
);

$query = '
{
entry(id: "1") {
title
... on Entry_Blog_Article {
hero {
breakpoints {
label
sources {
srcSet
}
}
}
}
}
}
';

$response = $this
->withoutExceptionHandling()
->postJson('/graphql/', ['query' => $query])
->getContent();

$response = json_decode($response, true);

expect(isset($response['errors']))->toBeFalse();
expect($response['data']['entry']['hero']['breakpoints'][0]['sources'][0]['srcSet'])
->toEqual($response['data']['entry']['hero']['breakpoints'][1]['sources'][0]['srcSet']);
});
1 change: 1 addition & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ protected function resolveApplicationConfiguration($app)
$app['config']->set('statamic.assets.image_manipulation.driver', 'imagick');

$app['config']->set('statamic.graphql.enabled', true);
$app['config']->set('statamic.graphql.cache', false);
$app['config']->set('statamic.graphql.resources', [
'collections' => true,
'assets' => true,
Expand Down

0 comments on commit 3c74106

Please sign in to comment.