Completed
Push — master ( 00a792...8d2ef3 )
by Craig
05:04
created

ZikulaPatternGenerationStrategy::getModUrlString()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Zikula package.
7
 *
8
 * Copyright Zikula - https://ziku.la/
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 Zikula\RoutesModule\Translation;
15
16
use JMS\I18nRoutingBundle\Router\PatternGenerationStrategyInterface;
17
use Symfony\Component\Routing\Route;
18
use Symfony\Component\Routing\RouteCollection;
19
use Symfony\Component\Translation\TranslatorBagInterface;
20
use Symfony\Contracts\Translation\TranslatorInterface;
21
use Translation\Extractor\Annotation\Ignore;
22
use Zikula\Bundle\CoreBundle\HttpKernel\ZikulaHttpKernelInterface;
23
24
/**
25
 * This strategy duplicates \JMS\I18nRoutingBundle\Router\DefaultPatternGenerationStrategy
26
 * adding only the Zikula module prefix as requested
27
 */
28
class ZikulaPatternGenerationStrategy implements PatternGenerationStrategyInterface
29
{
30
    public const STRATEGY_PREFIX = 'prefix';
31
32
    public const STRATEGY_PREFIX_EXCEPT_DEFAULT = 'prefix_except_default';
33
34
    /**
35
     * @var string
36
     */
37
    private $strategy;
38
39
    /**
40
     * @var TranslatorInterface
41
     */
42
    private $translator;
43
44
    /**
45
     * @var string
46
     */
47
    private $translationDomain;
48
49
    /**
50
     * @var array
51
     */
52
    private $locales;
53
54
    /**
55
     * @var string
56
     */
57
    private $cacheDir;
58
59
    /**
60
     * @var string
61
     */
62
    private $defaultLocale;
63
64
    /**
65
     * @var array
66
     */
67
    private $urlMap = [];
68
69
    public function __construct(
70
        string $strategy,
71
        TranslatorInterface $translator,
72
        array $locales,
73
        string $cacheDir,
74
        string $translationDomain = 'routes',
75
        string $defaultLocale = 'en'
76
    ) {
77
        $this->strategy = $strategy;
78
        $this->translator = $translator;
79
        $this->translationDomain = $translationDomain;
80
        $this->locales = $locales;
81
        $this->cacheDir = $cacheDir;
82
        $this->defaultLocale = $defaultLocale;
83
    }
84
85
    public function generateI18nPatterns($routeName, Route $route)
86
    {
87
        $patterns = [];
88
        foreach ($route->getOption('i18n_locales') ?: $this->locales as $locale) {
89
            // Check if translation exists in the translation catalogue
90
            if ($this->translator instanceof TranslatorBagInterface) {
91
                // Check if route is translated.
92
                if (!$this->translator->getCatalogue($locale)->has($routeName, $this->translationDomain)) {
93
                    // No translation found.
94
                    $i18nPattern = $route->getPath();
95
                } else {
96
                    // Get translation.
97
                    $i18nPattern = $this->translator->trans(/** @Ignore */$routeName, [], $this->translationDomain, $locale);
98
                }
99
            } else {
100
                // if no translation exists, we use the current pattern
101
                if ($routeName === $i18nPattern = $this->translator->trans(/** @Ignore */$routeName, [], $this->translationDomain, $locale)) {
102
                    $i18nPattern = $route->getPath();
103
                }
104
            }
105
106
            ///////////////////////////////////////
107
            // Begin customizations
108
109
            // prefix with zikula module url if requested
110
            if ($route->hasDefault('_zkModule')) {
111
                $module = $route->getDefault('_zkModule');
112
                $zkNoBundlePrefix = $route->getOption('zkNoBundlePrefix');
113
                if (!isset($zkNoBundlePrefix) || !$zkNoBundlePrefix) {
114
                    $untranslatedPrefix = $this->getUrlString($module);
115
                    if ($this->translator->getCatalogue($locale)->has($untranslatedPrefix, strtolower($module))) {
0 ignored issues
show
Bug introduced by
The method getCatalogue() does not exist on Symfony\Contracts\Translation\TranslatorInterface. It seems like you code against a sub-type of Symfony\Contracts\Translation\TranslatorInterface such as Symfony\Component\Translation\Translator or Symfony\Component\Transl...DataCollectorTranslator or Symfony\Component\Translation\LoggingTranslator. ( Ignorable by Annotation )

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

115
                    if ($this->translator->/** @scrutinizer ignore-call */ getCatalogue($locale)->has($untranslatedPrefix, strtolower($module))) {
Loading history...
116
                        $prefix = $this->translator->trans(/** @Ignore */$untranslatedPrefix, [], strtolower($module), $locale);
117
                    } else {
118
                        $prefix = $untranslatedPrefix;
119
                    }
120
                    $i18nPattern = '/' . $prefix . $i18nPattern;
121
                }
122
            }
123
124
            // End customizations
125
            ///////////////////////////////////////
126
127
            // prefix with locale if requested
128
            if (self::STRATEGY_PREFIX === $this->strategy
129
                || (self::STRATEGY_PREFIX_EXCEPT_DEFAULT === $this->strategy && $this->defaultLocale !== $locale)) {
130
                $i18nPattern = '/' . $locale . $i18nPattern;
131
                if (null !== $route->getOption('i18n_prefix')) {
132
                    $i18nPattern = $route->getOption('i18n_prefix') . $i18nPattern;
133
                }
134
            }
135
136
            $patterns[$i18nPattern][] = $locale;
137
        }
138
139
        return $patterns;
140
    }
141
142
    public function addResources(RouteCollection $i18nCollection)
143
    {
144
        foreach ($this->locales as $locale) {
145
            $metadata = $this->cacheDir . '/translations/catalogue.' . $locale . '.php.meta';
146
            if (!file_exists($metadata)) {
147
                continue;
148
            }
149
            foreach (unserialize(file_get_contents($metadata)) as $resource) {
150
                $i18nCollection->addResource($resource);
151
            }
152
        }
153
    }
154
155
    /**
156
     * Customized method to cache the url string for modules.
157
     */
158
    private function getUrlString(string $extensionName): string
159
    {
160
        if (!isset($this->urlMap[$extensionName])) {
161
            /** @var ZikulaHttpKernelInterface $kernel */
162
            $kernel = $GLOBALS['kernel'];
163
            $extension = $kernel->getBundle($extensionName);
164
            // get untranslated url from metaData.
165
            $this->urlMap[$extensionName] = $extension->getMetaData()->getUrl(false);
0 ignored issues
show
Bug introduced by
The method getMetaData() does not exist on Symfony\Component\HttpKe...\Bundle\BundleInterface. It seems like you code against a sub-type of Symfony\Component\HttpKe...\Bundle\BundleInterface such as Zikula\ExtensionsModule\AbstractExtension. ( Ignorable by Annotation )

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

165
            $this->urlMap[$extensionName] = $extension->/** @scrutinizer ignore-call */ getMetaData()->getUrl(false);
Loading history...
166
        }
167
168
        return $this->urlMap[$extensionName];
169
    }
170
}
171