• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

liip / LiipImagineBundle / 9579859728

19 Jun 2024 09:47AM UTC coverage: 80.313% (-0.2%) from 80.511%
9579859728

push

github

web-flow
Merge pull request #1598 from liip/2-to-3

2 to 3

43 of 57 new or added lines in 2 files covered. (75.44%)

1 existing line in 1 file now uncovered.

1795 of 2235 relevant lines covered (80.31%)

77.47 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.08
/src/Templating/LazyFilterRuntime.php
1
<?php
2

3
/*
4
 * This file is part of the `liip/LiipImagineBundle` project.
5
 *
6
 * (c) https://github.com/liip/LiipImagineBundle/graphs/contributors
7
 *
8
 * For the full copyright and license information, please view the LICENSE.md
9
 * file that was distributed with this source code.
10
 */
11

12
namespace Liip\ImagineBundle\Templating;
13

14
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
15
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
16
use Twig\Extension\RuntimeExtensionInterface;
17

18
final class LazyFilterRuntime implements RuntimeExtensionInterface
19
{
20
    private CacheManager $cache;
21

22
    /**
23
     * Optional version to remove from the asset filename and re-append to the URL.
24
     */
25
    private ?string $assetVersion;
26

27
    /**
28
     * @var array<string, string>|null
29
     */
30
    private $jsonManifest;
31

32
    /**
33
     * @var array<string, string>|null
34
     */
35
    private $jsonManifestLookup;
36

37
    /**
38
     * @param array<string, string>|null $jsonManifest
39
     */
40
    public function __construct(CacheManager $cache, ?string $assetVersion = null, ?array $jsonManifest = null)
41
    {
42
        $this->cache = $cache;
153✔
43
        $this->assetVersion = $assetVersion;
153✔
44
        $this->jsonManifest = $jsonManifest;
153✔
45
        $this->jsonManifestLookup = $jsonManifest ? array_flip($jsonManifest) : null;
153✔
46
    }
47

48
    /**
49
     * Gets the browser path for the image and filter to apply.
50
     */
51
    public function filter(string $path, string $filter, array $config = [], ?string $resolver = null, int $referenceType = UrlGeneratorInterface::ABSOLUTE_URL): string
52
    {
53
        $path = $this->cleanPath($path);
135✔
54
        $resolvedPath = $this->cache->getBrowserPath($path, $filter, $config, $resolver, $referenceType);
135✔
55

56
        return $this->appendAssetVersion($resolvedPath, $path);
135✔
57
    }
58

59
    /**
60
     * Gets the cache path for the image and filter to apply.
61
     *
62
     * This does not check whether the cached image exists or not.
63
     */
64
    public function filterCache(string $path, string $filter, array $config = [], ?string $resolver = null): string
65
    {
66
        $path = $this->cleanPath($path);
18✔
67
        if (\count($config)) {
18✔
68
            $path = $this->cache->getRuntimePath($path, $config);
9✔
69
        }
70
        $resolvedPath = $this->cache->resolve($path, $filter, $resolver);
18✔
71

72
        return $this->appendAssetVersion($resolvedPath, $path);
18✔
73
    }
74

75
    private function cleanPath(string $path): string
76
    {
77
        if (!$this->assetVersion && !$this->jsonManifest) {
153✔
78
            return $path;
63✔
79
        }
80

81
        if ($this->assetVersion) {
90✔
82
            $start = mb_strrpos($path, $this->assetVersion);
18✔
83
            if (mb_strlen($path) - mb_strlen($this->assetVersion) === $start) {
18✔
84
                return rtrim(mb_substr($path, 0, $start), '?');
9✔
85
            }
86
        }
87

88
        if ($this->jsonManifest) {
81✔
89
            if (\array_key_exists($path, $this->jsonManifestLookup)) {
72✔
90
                return $this->jsonManifestLookup[$path];
72✔
91
            }
92
        }
93

94
        return $path;
9✔
95
    }
96

97
    private function appendAssetVersion(string $resolvedPath, string $path): string
98
    {
99
        if (!$this->assetVersion && !$this->jsonManifest) {
153✔
100
            return $resolvedPath;
63✔
101
        }
102

103
        if ($this->assetVersion) {
90✔
104
            $separator = false !== mb_strpos($resolvedPath, '?') ? '&' : '?';
18✔
105

106
            return $resolvedPath.$separator.$this->assetVersion;
18✔
107
        }
108

109
        if (\array_key_exists($path, $this->jsonManifest)) {
72✔
110
            $prefixedSlash = 0 !== mb_strpos($path, '/') && 0 === mb_strpos($this->jsonManifest[$path], '/');
72✔
111
            $versionedPath = $prefixedSlash ? mb_substr($this->jsonManifest[$path], 1) : $this->jsonManifest[$path];
72✔
112

113
            $originalExt = pathinfo($path, PATHINFO_EXTENSION);
72✔
114
            $resolvedExt = pathinfo($resolvedPath, PATHINFO_EXTENSION);
72✔
115

116
            if ($originalExt !== $resolvedExt) {
72✔
117
                $path = str_replace('.'.$originalExt, '.'.$resolvedExt, $path);
36✔
118
                $versionedPath = str_replace('.'.$originalExt, '.'.$resolvedExt, $versionedPath);
36✔
119
            }
120

121
            $versioning = $this->captureVersion(pathinfo($path, PATHINFO_BASENAME), pathinfo($versionedPath, PATHINFO_BASENAME));
72✔
122
            $resolvedFilename = pathinfo($resolvedPath, PATHINFO_BASENAME);
72✔
123
            $resolvedDir = pathinfo($resolvedPath, PATHINFO_DIRNAME);
72✔
124
            $resolvedPath = $resolvedDir.'/'.$this->insertVersion($resolvedFilename, $versioning['version'], $versioning['position']);
72✔
125
        }
126

127
        return $resolvedPath;
72✔
128
    }
129

130
    /**
131
     * Capture the versioning string from the versioned filename
132
     *
133
     * @return array{version: string, position: int}
134
     */
135
    private function captureVersion(string $originalFilename, string $versionedFilename): array
136
    {
137
        $originalLength = mb_strlen($originalFilename);
72✔
138
        $versionedLength = mb_strlen($versionedFilename);
72✔
139

140
        for ($i = 0; $i < $originalLength && $i < $versionedLength; ++$i) {
72✔
141
            if ($originalFilename[$i] !== $versionedFilename[$i]) {
72✔
142
                break;
36✔
143
            }
144
        }
145

146
        $version = mb_substr($versionedFilename, $i, $versionedLength - $originalLength);
72✔
147

148
        return ['version' => $version, 'position' => $i];
72✔
149
    }
150

151
    /**
152
     * Insert the version string into our resolved filename
153
     */
154
    private function insertVersion(string $resolvedFilename, string $version, int $position): string
155
    {
156
        if ($position < 0 || $position > mb_strlen($resolvedFilename)) {
72✔
NEW
157
            return $resolvedFilename;
×
158
        }
159

160
        $firstPart = mb_substr($resolvedFilename, 0, $position);
72✔
161
        $secondPart = mb_substr($resolvedFilename, $position);
72✔
162

163
        return $firstPart.$version.$secondPart;
72✔
164
    }
165
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc