Skip to content

Commit 1516c90

Browse files
authored
Merge pull request #85 from samicoman/master
add support for converting pictures with src-sets
2 parents 8efb15f + 8fc7a07 commit 1516c90

File tree

7 files changed

+116
-30
lines changed

7 files changed

+116
-30
lines changed

Image/Image.php

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,24 @@ class Image
1616
*/
1717
private $url;
1818

19+
/**
20+
* @var ?string
21+
*/
22+
private $srcSet = null;
23+
1924
/**
2025
* @param string $path
2126
* @param string $url
27+
* @param ?string $srcSet
2228
*/
2329
public function __construct(
2430
string $path,
25-
string $url
31+
string $url,
32+
?string $srcSet = null
2633
) {
2734
$this->path = $path;
2835
$this->url = $url;
36+
$this->srcSet = $srcSet;
2937
}
3038

3139
/**
@@ -44,6 +52,22 @@ public function getUrl(): string
4452
return $this->url;
4553
}
4654

55+
/**
56+
* @return ?string
57+
*/
58+
public function getSrcSet(): ?string
59+
{
60+
return $this->srcSet;
61+
}
62+
63+
/**
64+
* @param ?string
65+
*/
66+
public function setSrcSet(?string $srcSet): void
67+
{
68+
$this->srcSet = $srcSet;
69+
}
70+
4771
/**
4872
* @return string
4973
*/

Image/ImageCollector.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ public function __construct(
4141
}
4242

4343
/**
44-
* @param string $imageUrl
44+
* @param string|array $imageUrl
4545
* @return Image[]
4646
*/
47-
public function collect(string $imageUrl): array
47+
public function collect($imageUrl): array
4848
{
4949
try {
5050
$image = $this->imageFactory->createFromUrl($imageUrl);

Image/ImageFactory.php

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,35 @@ public function createFromPath(string $path): Image
3737
}
3838

3939
/**
40-
* @param string $url
40+
* @param array|string $url
4141
* @return Image
4242
* @throws FileSystemException
4343
*/
44-
public function createFromUrl(string $url): Image
44+
public function createFromUrl($url): Image
45+
{
46+
$urls = is_array($url) ? $url : [$url];
47+
$baseUrl = $this->cleanUrl($urls[0] ?? '');
48+
$srcSet = $this->getSrcSet($urls);
49+
$path = $this->urlConvertor->getFilenameFromUrl($baseUrl);
50+
return $this->objectManager->create(Image::class, ['path' => $path, 'url' => $baseUrl, 'srcSet' => $srcSet]);
51+
}
52+
53+
private function cleanUrl(string $url): string
4554
{
4655
if (strpos($url, 'http') !== false) {
47-
$url = explode('?', $url)[0];
56+
return explode('?', $url)[0];
4857
}
49-
50-
$path = $this->urlConvertor->getFilenameFromUrl($url);
51-
return $this->objectManager->create(Image::class, ['path' => $path, 'url' => $url]);
58+
59+
return $url;
60+
}
61+
62+
private function getSrcSet(array $urls): string
63+
{
64+
$srcSetPieces = [];
65+
foreach ($urls as $key => $url) {
66+
$srcSetPieces[] = $this->cleanUrl($url) . ($key !== 0 ? (' ' . $key) : '');
67+
}
68+
69+
return implode(',', $srcSetPieces);
5270
}
5371
}

Test/Unit/Image/ImageFactoryTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,26 @@ public function testCreateFromUrl()
4242
$this->assertEquals('/foo/bar.jpg', $image->getUrl());
4343
}
4444

45+
public function testCreateFromUrlWithMultipleUrls()
46+
{
47+
$urlConvertor = $this->getUrlConvertor();
48+
$urlConvertor->method('getFilenameFromUrl')->willReturn('/tmp/pub/foo/bar.jpg');
49+
$urlConvertor->method('getUrlFromFilename')->willReturn('/foo/bar.jpg');
50+
$objectManager = $this->getObjectManager();
51+
$objectManager->method('create')->willReturn(
52+
new Image('/tmp/pub/foo/bar.jpg', '/foo/bar.jpg', '/foo/bar.jpg,/baz/qux.jpg 500w')
53+
);
54+
55+
// @phpstan-ignore-next-line
56+
$imageFactory = new ImageFactory($objectManager, $urlConvertor);
57+
$image = $imageFactory->createFromUrl(['/foo/bar.jpg', '500w' => '/baz/qux.jpg']);
58+
59+
$this->assertInstanceOf(Image::class, $image);
60+
$this->assertEquals('/tmp/pub/foo/bar.jpg', $image->getPath());
61+
$this->assertEquals('/foo/bar.jpg', $image->getUrl());
62+
$this->assertEquals('/foo/bar.jpg,/baz/qux.jpg 500w', $image->getSrcSet());
63+
}
64+
4565
private function getObjectManager(): MockObject
4666
{
4767
return $this->getMockBuilder(ObjectManagerInterface::class)

Test/Unit/Image/ImageTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ public function testGetUrl()
2020
$this->assertEquals('/media/foobar.jpg', $image->getUrl());
2121
}
2222

23+
public function testGetSrcSet()
24+
{
25+
$image = new Image('/tmp/pub/foobar.jpg', '/media/foobar.jpg', '/foo/bar.jpg,/baz/qux.jpg 500w');
26+
$this->assertEquals('/foo/bar.jpg,/baz/qux.jpg 500w', $image->getSrcSet());
27+
}
28+
2329
public function testGetMimetype()
2430
{
2531
$image = new Image('/tmp/pub/foobar.gif', 'foobar.gif');

Util/HtmlReplacer.php

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ private function getImageHtmlFromImage(DOMElement $image, string $html): string
122122
return '';
123123
}
124124

125-
$regex = '/<img '.self::MARKER_CODE.'="'.$imageMarker.'"([^>"]*)(?:"[^"]*"[^>"]*)*>/';
125+
$regex = '/<img '.self::MARKER_CODE.'="'.$imageMarker.'"([^\>]+)>/';
126126
if (!preg_match($regex, $html, $imageHtmlMatch)) {
127127
return '';
128128
}
@@ -145,15 +145,35 @@ private function getPictureHtmlFromImage(DOMElement $image, string $html): strin
145145
if (!$this->isAllowedByParentNode($image)) {
146146
return '';
147147
}
148+
149+
$imageSrcSet = $image->getAttribute('srcset');
150+
if ($imageSrcSet) {
151+
$srcSetImages = explode(',', $imageSrcSet);
152+
$imageUrls = [];
153+
foreach ($srcSetImages as $srcSetImage) {
154+
$pieces = explode(' ', trim($srcSetImage));
155+
if (isset($pieces[1])) {
156+
$descriptor = $pieces[1];
157+
$imageUrls[$descriptor] = $pieces[0];
158+
} else {
159+
$descriptor = 0;
160+
$imageUrl = $imageUrls[$descriptor] = $pieces[0];
161+
}
162+
}
163+
$images = $this->imageCollector->collect($imageUrls);
164+
if (!count($images) > 0) {
165+
return '';
166+
}
167+
} else {
168+
$imageUrl = $this->getImageUrlFromElement($image);
169+
if (!$this->isAllowedByImageUrl($imageUrl)) {
170+
return '';
171+
}
148172

149-
$imageUrl = $this->getImageUrlFromElement($image);
150-
if (!$this->isAllowedByImageUrl($imageUrl)) {
151-
return '';
152-
}
153-
154-
$images = $this->imageCollector->collect($imageUrl);
155-
if (!count($images) > 0) {
156-
return '';
173+
$images = $this->imageCollector->collect($imageUrl);
174+
if (!count($images) > 0) {
175+
return '';
176+
}
157177
}
158178

159179
$imageHtml = $this->getImageHtmlFromImage($image, $html);
@@ -280,6 +300,7 @@ private function replaceInlineCssBackgroundImages(string $html): string
280300
private function getImageUrlFromElement(DOMElement $image): string
281301
{
282302
$attributes = $this->getAllowedSrcAttributes();
303+
283304
$imageUrl = '';
284305
foreach ($attributes as $attribute) {
285306
$imageUrl = $image->getAttribute($attribute);
Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php declare(strict_types=1);
22

3-
use Magento\Framework\Escaper;
3+
use Yireo\NextGenImages\Block\Picture;
44
use Yireo\NextGenImages\Block\Picture;
55

66
/** @version 0.5.15 */
@@ -16,22 +16,19 @@ $originalTag = preg_replace('/(\/?)>$/', $lazyLoading.'\1>', $originalTag);
1616
$originalImage = $block->getOriginalImage();
1717
$originalImageType = $block->getOriginalImageType();
1818
$srcAttribute = $block->getSrcAttribute() ?? 'src';
19-
$srcSetAttribute = $srcAttribute.'set'; ?>
20-
21-
<?php if ($block->getDebug()): ?>
22-
<!-- <?= /* @noEscape */ $block->getOriginalTag() ?> -->
23-
<?php endif; ?>
24-
19+
$srcSetAttribute = $srcAttribute.'set';
20+
?>
2521
<picture<?= /* @noEscape */ $class ?>>
2622
<?php if ($block->getDebug()): ?>
2723
<!-- <?= $escaper->escapeHtml($block->getOriginalAttributesAsString()) ?> -->
2824
<?php endif; ?>
25+
2926
<?php foreach ($block->getImages() as $image): ?>
30-
<source type="<?= /* @noEscape */
31-
$image->getMimeType() ?>" <?= /* @noEscape */
32-
$srcSetAttribute ?>="<?= /* @noEscape */
33-
$image->getUrl() ?>" <?= /* @noEscape */
34-
$block->getSourceAttributesAsString() ?> >
27+
<source
28+
type="<?= /* @noEscape */ $image->getMimeType() ?>"
29+
<?= /* @noEscape */ $srcSetAttribute ?>="<?= /* @noEscape */ $image->getSrcSet() ?: $image->getUrl() ?>"
30+
<?= /* @noEscape */ $block->getSourceAttributesAsString() ?>
31+
>
3532
<?php endforeach; ?>
3633
<?= /* @noEscape */ $originalTag ?>
3734
</picture>

0 commit comments

Comments
 (0)