Completed
Pull Request — 3.x (#6145)
by Wojciech
03:08
created

StringExtension::twigTruncateFilter()   B

Complexity

Conditions 8
Paths 8

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
rs 8.2114
c 0
b 0
f 0
cc 8
nc 8
nop 5
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\AdminBundle\Twig\Extension;
15
16
use Symfony\Component\String\UnicodeString as SymfonyUnicodeString;
17
use Twig\Environment;
18
use Twig\Extension\AbstractExtension;
19
use Twig\Extensions\TextExtension;
20
use Twig\TwigFilter;
21
22
/**
23
 * NEXT_MAJOR: Remove this class.
24
 *
25
 * Decorates `Twig\Extra\String\StringExtension` in order to provide the `$cut`
26
 * argument for `Symfony\Component\String\UnicodeString::truncate()`.
27
 * This class must be removed when the component ships this feature.
28
 *
29
 * @internal
30
 *
31
 * @see https://github.com/symfony/symfony/pull/35649
32
 *
33
 * @author Javier Spagnoletti <[email protected]>
34
 */
35
final class StringExtension extends AbstractExtension
36
{
37
    /**
38
     * @var TextExtension
39
     */
40
    private $legacyExtension;
41
42
    /**
43
     * @var bool
44
     */
45
    private $legacy;
46
47
    public function __construct(?TextExtension $legacyExtension = null, bool $legacy = true)
48
    {
49
        $this->legacyExtension = $legacyExtension;
50
        $this->legacy = $legacy;
51
    }
52
53
    /**
54
     * @return TwigFilter[]
55
     */
56
    public function getFilters(): array
57
    {
58
        return [
59
            new TwigFilter('sonata_truncate', [$this, 'deprecatedTruncate'], ['needs_environment' => true]),
60
        ];
61
    }
62
63
    /**
64
     * @return SymfonyUnicodeString|string
65
     */
66
    public function deprecatedTruncate(Environment $env, ?string $text, int $length = 30, bool $preserve = false, string $ellipsis = '...')
67
    {
68
        @trigger_error(
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
69
            'The "sonata_truncate" twig filter is deprecated'
70
            .' since sonata-project/admin-bundle 3.69 and will be removed in 4.0. Use "u.truncate" instead.',
71
            E_USER_DEPRECATED
72
        );
73
74
        if (false === $this->legacy) {
75
            return $this->legacyTruncteWithUnicodeString($text, $length, $preserve, $ellipsis);
76
        }
77
78
        if (null !== $this->legacyExtension) {
79
            return twig_truncate_filter($env, $text, $length, $preserve, $ellipsis);
0 ignored issues
show
Compatibility introduced by
$env of type object<Twig\Environment> is not a sub-type of object<Twig_Environment>. It seems like you assume a child class of the class Twig\Environment to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
80
        }
81
82
        return $this->twigTruncateFilter($env, $text, $length, $preserve, $ellipsis);
83
    }
84
85
    public function legacyTruncteWithUnicodeString(?string $text, int $length = 30, bool $preserve = false, string $ellipsis = '...'): SymfonyUnicodeString
86
    {
87
        return (new SymfonyUnicodeString($text ?? ''))->truncate($length, $ellipsis, $preserve);
88
    }
89
90
    private function twigTruncateFilter(Environment $env, ?string $value, int $length = 30, bool $preserve = false, $separator = '...')
91
    {
92
        if (\function_exists('mb_get_info')) {
93
            if (mb_strlen($value, $env->getCharset()) > $length) {
94
                if ($preserve) {
95
                    // If breakpoint is on the last word, return the value without separator.
96
                    if (false === ($breakpoint = mb_strpos($value, ' ', $length, $env->getCharset()))) {
97
                        return $value;
98
                    }
99
100
                    $length = $breakpoint;
101
                }
102
103
                return rtrim(mb_substr($value, 0, $length, $env->getCharset())).$separator;
104
            }
105
        } else {
106
            if (\strlen($value) > $length) {
107
                if ($preserve) {
108
                    if (false !== ($breakpoint = strpos($value, ' ', $length))) {
109
                        $length = $breakpoint;
110
                    }
111
                }
112
113
                return rtrim(substr($value, 0, $length)).$separator;
114
            }
115
        }
116
117
        return $value;
118
    }
119
}
120