Passed
Push — main ( 87655a...3ce0a2 )
by Oscar
02:40
created

HtmlCompressRuntime::cleanValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 2
rs 10
1
<?php
2
3
/*
4
 * This file is part of ocubom/twig-html-extension
5
 *
6
 * © Oscar Cubo Medina <https://ocubom.github.io>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Ocubom\Twig\Extension;
13
14
use Ocubom\Twig\Extension\Exception\InvalidArgumentException;
15
use Symfony\Bundle\WebProfilerBundle\WebProfilerBundle;
1 ignored issue
show
Bug introduced by
The type Symfony\Bundle\WebProfilerBundle\WebProfilerBundle was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Twig\Environment;
17
use Twig\Extension\RuntimeExtensionInterface;
18
use WyriHaximus\HtmlCompress\Factory;
19
use WyriHaximus\HtmlCompress\HtmlCompressorInterface;
20
21
class HtmlCompressRuntime implements RuntimeExtensionInterface
22
{
23
    // Factory compression levels
24
    public const COMPRESSOR_NONE = 0;
25
    public const COMPRESSOR_FASTEST = 1;
26
    public const COMPRESSOR_NORMAL = 2;
27
    public const COMPRESSOR_SMALLEST = 3;
28
29
    private const FACTORIES = [
30
        // By COMPRESSOR_*
31
        null,
32
        [Factory::class, 'constructfastest'],
33
        [Factory::class, 'construct'],
34
        [Factory::class, 'constructsmallest'],
35
        // By sort name
36
        '' => null,
37
        'none' => null,
38
        'fastest' => [Factory::class, 'constructfastest'],
39
        'normal' => [Factory::class, 'construct'],
40
        'smallest' => [Factory::class, 'constructsmallest'],
41
    ];
42
43
    private bool $force;
44
45
    private ?HtmlCompressorInterface $compressor = null;
46
47
    /**
48
     * Constructor.
49
     *
50
     * @param bool                                        $force      Always apply compression
51
     * @param HtmlCompressorInterface|callable|int|string $compressor The compressor level, a compressor instance or factory callable
52
     */
53 8
    public function __construct(bool $force = false, $compressor = self::COMPRESSOR_SMALLEST)
54
    {
55 8
        $this->force = $force;
56
57 8
        if ($compressor instanceof HtmlCompressorInterface) {
58 1
            $this->compressor = $compressor;
59
        } else {
60
            try {
61 7
                $factory = is_callable($compressor) ? $compressor : self::createFactory($compressor);
1 ignored issue
show
Bug introduced by
It seems like $compressor can also be of type callable; however, parameter $compressor of Ocubom\Twig\Extension\Ht...untime::createFactory() does only seem to accept integer|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
                $factory = is_callable($compressor) ? $compressor : self::createFactory(/** @scrutinizer ignore-type */ $compressor);
Loading history...
62 7
                $this->compressor = $factory();
63 1
            } catch (\Throwable $exc) {
64 1
                throw new InvalidArgumentException(
65 1
                    sprintf(
66
                        'Unable to build "%s" HTML compressor ',
67 1
                        is_scalar($compressor) ? $compressor : 'callable',
68
                    ),
69
                    0,
70
                    $exc
71
                );
72
            }
73
        }
74
    }
75
76 3
    public function __invoke(Environment $twig, string $html, bool $force = false): string
77
    {
78 3
        if (null !== $this->compressor && (!$twig->isDebug() || $this->force || $force)) {
79
            // Compress
80 2
            $html = $this->compressor->compress($html);
81
82
            // Add end body tag to allow profiler inject its code
83 2
            if ($twig->isDebug() && class_exists(WebProfilerBundle::class)) {
84
                $html .= '</body>'; // @codeCoverageIgnore
85
            }
86
        }
87
88 3
        return $html;
89
    }
90
91
    /**
92
     * @param int|string $compressor
93
     */
94 6
    private static function createFactory($compressor): callable
95
    {
96 6
        $key = is_string($compressor) ? self::cleanValue($compressor) : $compressor;
97 6
        if (array_key_exists($key, self::FACTORIES)) {
98 5
            return self::FACTORIES[$key] ?? function () {
99 2
                return null;
100
            };
101
        }
102
103 1
        return function () use ($key): HtmlCompressorInterface {
104 1
            $factory = [Factory::class, 'construct'.$key];
105
106 1
            return $factory();
107
        };
108
    }
109
110 3
    private static function cleanValue(string $name): string
111
    {
112 3
        $value = strtolower($name);
113
114 3
        if (str_starts_with($value, 'construct')) {
115 1
            $value = substr($value, 9);
116
        }
117
118 3
        return $value;
119
    }
120
}
121