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

liip / LiipImagineBundle / 10701363663

04 Sep 2024 12:11PM UTC coverage: 81.688% (-0.06%) from 81.746%
10701363663

push

github

web-flow
Merge pull request #1610 from liip/cs-fix

apply latest cs fixer

67 of 84 new or added lines in 42 files covered. (79.76%)

2 existing lines in 1 file now uncovered.

2275 of 2785 relevant lines covered (81.69%)

103.1 hits per line

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

94.12
/Controller/ImagineController.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\Controller;
13

14
use Imagine\Exception\RuntimeException;
15
use Liip\ImagineBundle\Config\Controller\ControllerConfig;
16
use Liip\ImagineBundle\Exception\Binary\Loader\NotLoadableException;
17
use Liip\ImagineBundle\Exception\Imagine\Filter\NonExistingFilterException;
18
use Liip\ImagineBundle\Imagine\Cache\Helper\PathHelper;
19
use Liip\ImagineBundle\Imagine\Cache\SignerInterface;
20
use Liip\ImagineBundle\Imagine\Data\DataManager;
21
use Liip\ImagineBundle\Service\FilterService;
22
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
23
use Symfony\Component\HttpFoundation\RedirectResponse;
24
use Symfony\Component\HttpFoundation\Request;
25
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
26
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
27
use Symfony\Component\HttpKernel\Kernel;
28

29
class ImagineController
30
{
31
    /**
32
     * @var FilterService
33
     */
34
    private $filterService;
35

36
    /**
37
     * @var DataManager
38
     */
39
    private $dataManager;
40

41
    /**
42
     * @var SignerInterface
43
     */
44
    private $signer;
45

46
    /**
47
     * @var ControllerConfig
48
     */
49
    private $controllerConfig;
50

51
    public function __construct(
52
        FilterService $filterService,
53
        DataManager $dataManager,
54
        SignerInterface $signer,
55
        ?ControllerConfig $controllerConfig = null
56
    ) {
57
        $this->filterService = $filterService;
325✔
58
        $this->dataManager = $dataManager;
325✔
59
        $this->signer = $signer;
325✔
60

61
        if (null === $controllerConfig) {
325✔
62
            @trigger_error(\sprintf(
13✔
63
                'Instantiating "%s" without a forth argument of type "%s" is deprecated since 2.2.0 and will be required in 3.0.', self::class, ControllerConfig::class
13✔
64
            ), E_USER_DEPRECATED);
13✔
65
        }
66

67
        $this->controllerConfig = $controllerConfig ?? new ControllerConfig(301);
325✔
68
    }
175✔
69

70
    /**
71
     * This action applies a given filter to a given image, saves the image and redirects the browser to the stored
72
     * image.
73
     *
74
     * The resulting image is cached so subsequent requests will redirect to the cached image instead applying the
75
     * filter and storing the image again.
76
     *
77
     * @param string $path
78
     * @param string $filter
79
     *
80
     * @throws RuntimeException
81
     * @throws NotFoundHttpException
82
     *
83
     * @return RedirectResponse
84
     */
85
    public function filterAction(Request $request, $path, $filter)
86
    {
87
        $path = PathHelper::urlPathToFilePath($path);
221✔
88
        $resolver = $request->get('resolver');
221✔
89

90
        return $this->createRedirectResponse(function () use ($path, $filter, $resolver, $request) {
102✔
91
            return $this->filterService->getUrlOfFilteredImage(
221✔
92
                $path,
221✔
93
                $filter,
187✔
94
                $resolver,
187✔
95
                $this->isWebpSupported($request)
221✔
96
            );
102✔
97
        }, $path, $filter);
221✔
98
    }
99

100
    /**
101
     * This action applies a given filter -merged with additional runtime filters- to a given image, saves the image and
102
     * redirects the browser to the stored image.
103
     *
104
     * The resulting image is cached so subsequent requests will redirect to the cached image instead applying the
105
     * filter and storing the image again.
106
     *
107
     * @param string $hash
108
     * @param string $path
109
     * @param string $filter
110
     *
111
     * @throws RuntimeException
112
     * @throws BadRequestHttpException
113
     * @throws NotFoundHttpException
114
     *
115
     * @return RedirectResponse
116
     */
117
    public function filterRuntimeAction(Request $request, $hash, $path, $filter)
118
    {
119
        $resolver = $request->get('resolver');
143✔
120
        $path = PathHelper::urlPathToFilePath($path);
143✔
121
        $runtimeConfig = $this->getFiltersBc($request);
143✔
122

123
        if (true !== $this->signer->check($hash, $path, $runtimeConfig)) {
130✔
124
            throw new BadRequestHttpException(\sprintf('Signed url does not pass the sign check for path "%s" and filter "%s" and runtime config %s', $path, $filter, json_encode($runtimeConfig)));
13✔
125
        }
126

127
        return $this->createRedirectResponse(function () use ($path, $filter, $runtimeConfig, $resolver, $request) {
54✔
128
            return $this->filterService->getUrlOfFilteredImageWithRuntimeFilters(
117✔
129
                $path,
117✔
130
                $filter,
99✔
131
                $runtimeConfig,
99✔
132
                $resolver,
99✔
133
                $this->isWebpSupported($request)
117✔
134
            );
54✔
135
        }, $path, $filter, $hash);
117✔
136
    }
137

138
    private function getFiltersBc(Request $request): array
139
    {
140
        if (version_compare(Kernel::VERSION, '5.1', '>=')) {
143✔
141
            try {
142
                return $request->query->all('filters');
99✔
143
            } catch (BadRequestException $e) {
9✔
144
                // for strict BC - BadRequestException seems more suited to this situation.
145
                // remove the try-catch in version 3
146
                throw new NotFoundHttpException(\sprintf('Filters must be an array. Value was "%s"', $request->query->get('filters')));
9✔
147
            }
148
        }
149

150
        $runtimeConfig = $request->query->get('filters', []);
44✔
151

152
        if (!\is_array($runtimeConfig)) {
44✔
153
            throw new NotFoundHttpException(\sprintf('Filters must be an array. Value was "%s"', $runtimeConfig));
4✔
154
        }
155

156
        return $runtimeConfig;
40✔
157
    }
158

159
    private function createRedirectResponse(\Closure $url, string $path, string $filter, ?string $hash = null): RedirectResponse
160
    {
161
        try {
162
            return new RedirectResponse($url(), $this->controllerConfig->getRedirectResponseCode());
260✔
163
        } catch (NotLoadableException $exception) {
26✔
164
            if (null !== $this->dataManager->getDefaultImageUrl($filter)) {
13✔
165
                return new RedirectResponse($this->dataManager->getDefaultImageUrl($filter));
×
166
            }
167

168
            throw new NotFoundHttpException(\sprintf('Source image for path "%s" could not be found', $path), $exception);
13✔
169
        } catch (NonExistingFilterException $exception) {
13✔
170
            throw new NotFoundHttpException(\sprintf('Requested non-existing filter "%s"', $filter), $exception);
13✔
171
        } catch (RuntimeException $exception) {
×
NEW
172
            throw new \RuntimeException(vsprintf('Unable to create image for path "%s" and filter "%s". Message was "%s"', [$hash ? \sprintf('%s/%s', $hash, $path) : $path, $filter, $exception->getMessage()]), 0, $exception);
×
173
        }
174
    }
175

176
    private function isWebpSupported(Request $request): bool
177
    {
178
        return false !== mb_stripos($request->headers->get('accept', ''), 'image/webp');
260✔
179
    }
180
}
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

© 2025 Coveralls, Inc