Completed
Push — master ( 48cc3d...5640fa )
by Craig
12:32 queued 05:19
created

ZikulaPatternGenerationStrategy::getModUrlString()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 23
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 12
c 0
b 0
f 0
nc 5
nop 1
dl 0
loc 23
rs 8.7972
1
<?php
2
3
/*
4
 * This file is part of the Zikula package.
5
 *
6
 * Copyright Zikula Foundation - http://zikula.org/
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 Zikula\RoutesModule\Translation;
13
14
use JMS\I18nRoutingBundle\Router\PatternGenerationStrategyInterface;
15
use Symfony\Component\Routing\Route;
16
use Symfony\Component\Routing\RouteCollection;
17
use Symfony\Component\Translation\TranslatorBagInterface;
18
use Symfony\Component\Translation\TranslatorInterface;
19
20
/**
21
 * This strategy duplicates \JMS\I18nRoutingBundle\Router\DefaultPatternGenerationStrategy
22
 * adding only the Zikula module prefix as requested
23
 */
24
class ZikulaPatternGenerationStrategy implements PatternGenerationStrategyInterface
25
{
26
    const STRATEGY_PREFIX = 'prefix';
27
    const STRATEGY_PREFIX_EXCEPT_DEFAULT = 'prefix_except_default';
28
    const STRATEGY_CUSTOM = 'custom';
29
30
    private $strategy;
31
32
    private $translator;
33
34
    private $translationDomain;
35
36
    private $locales;
37
38
    private $cacheDir;
39
40
    private $defaultLocale;
41
42
    private $modUrlMap = [];
43
44
    public function __construct($strategy, TranslatorInterface $translator, array $locales, $cacheDir, $translationDomain = 'routes', $defaultLocale = 'en')
45
    {
46
        $this->strategy = $strategy;
47
        $this->translator = $translator;
48
        $this->translationDomain = $translationDomain;
49
        $this->locales = $locales;
50
        $this->cacheDir = $cacheDir;
51
        $this->defaultLocale = $defaultLocale;
52
    }
53
54
    /**
55
     * @inheritDoc
56
     */
57
    public function generateI18nPatterns($routeName, Route $route)
58
    {
59
        $patterns = [];
60
        foreach ($route->getOption('i18n_locales') ?: $this->locales as $locale) {
61
            // Check if translation exists in the translation catalogue
62
            if ($this->translator instanceof TranslatorBagInterface) {
1 ignored issue
show
Bug introduced by
The class Symfony\Component\Transl...\TranslatorBagInterface does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
63
                // Check if route is translated.
64
                if (!$this->translator->getCatalogue($locale)->has($routeName, $this->translationDomain)) {
65
                    // No translation found.
66
                    $i18nPattern = $route->getPath();
67
                } else {
68
                    // Get translation.
69
                    $i18nPattern = $this->translator->trans(/** @Ignore */$routeName, [], $this->translationDomain, $locale);
70
                }
71
            } else {
72
                // if no translation exists, we use the current pattern
73
                if ($routeName === $i18nPattern = $this->translator->trans(/** @Ignore */$routeName, [], $this->translationDomain, $locale)) {
74
                    $i18nPattern = $route->getPath();
75
                }
76
            }
77
78
            ///////////////////////////////////////
79
            // Begin customizations
80
81
            // prefix with zikula module url if requested
82
            if ($route->hasDefault('_zkModule')) {
83
                $module = $route->getDefault('_zkModule');
84
                $zkNoBundlePrefix = $route->getOption('zkNoBundlePrefix');
85
                if (!isset($zkNoBundlePrefix) || !$zkNoBundlePrefix) {
86
                    $untranslatedPrefix = $this->getModUrlString($module);
87
                    if ($this->translator->getCatalogue($locale)->has($untranslatedPrefix, strtolower($module))) {
88
                        $prefix = $this->translator->trans(/** @Ignore */$untranslatedPrefix, [], strtolower($module), $locale);
89
                    } else {
90
                        $prefix = $untranslatedPrefix;
91
                    }
92
                    $i18nPattern = '/' . $prefix . $i18nPattern;
93
                }
94
            }
95
96
            // End customizations
97
            ///////////////////////////////////////
98
99
            // prefix with locale if requested
100
            if (self::STRATEGY_PREFIX === $this->strategy
101
                || (self::STRATEGY_PREFIX_EXCEPT_DEFAULT === $this->strategy && $this->defaultLocale !== $locale)) {
102
                $i18nPattern = '/' . $locale . $i18nPattern;
103
                if (null !== $route->getOption('i18n_prefix')) {
104
                    $i18nPattern = $route->getOption('i18n_prefix').$i18nPattern;
105
                }
106
            }
107
108
            $patterns[$i18nPattern][] = $locale;
109
        }
110
111
        return $patterns;
112
    }
113
114
    /**
115
     * @inheritDoc
116
     */
117
    public function addResources(RouteCollection $i18nCollection)
118
    {
119
        foreach ($this->locales as $locale) {
120
            if (file_exists($metadata = $this->cacheDir . '/translations/catalogue.' . $locale . '.php.meta')) {
121
                foreach (unserialize(file_get_contents($metadata)) as $resource) {
122
                    $i18nCollection->addResource($resource);
123
                }
124
            }
125
        }
126
    }
127
128
    /**
129
     * Customized method to cache the url string for modules.
130
     *
131
     * @param $moduleName
132
     * @return string
133
     */
134
    private function getModUrlString($moduleName)
0 ignored issues
show
Coding Style introduced by
getModUrlString uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
135
    {
136
        if (!isset($this->modUrlMap[$moduleName])) {
137
            /** @var \ZikulaKernel $kernel */
138
            $kernel = $GLOBALS['kernel'];
139
            $module = $kernel->getModule($moduleName);
140
            // First get untranslated url from metaData.
141
            $url = $module->getMetaData()->getUrl(false);
142
            if (empty($url)) {
143
                // @todo remove in 2.0
144
                try {
145
                    // MetaData will be empty for extensions not Spec-2.0. Try to get from modinfo.
146
                    // this calls the DB which is not available during install.
147
                    $modInfo = \ModUtil::getInfoFromName($moduleName);
148
                    $url = $modInfo['url'];
149
                } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
150
                }
151
            }
152
            $this->modUrlMap[$moduleName] = $url;
153
        }
154
155
        return $this->modUrlMap[$moduleName];
156
    }
157
}
158