Completed
Pull Request — master (#2737)
by Jeroen
10:25
created

KunstmaanAdminExtension::prepend()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 24
CRAP Score 4.001

Importance

Changes 0
Metric Value
dl 0
loc 35
ccs 24
cts 25
cp 0.96
rs 9.36
c 0
b 0
f 0
cc 4
nc 4
nop 1
crap 4.001
1
<?php
2
3
namespace Kunstmaan\AdminBundle\DependencyInjection;
4
5
use FOS\UserBundle\Form\Type\ResettingFormType;
6
use InvalidArgumentException;
7
use Kunstmaan\AdminBundle\Helper\Menu\MenuAdaptorInterface;
8
use Symfony\Component\Config\FileLocator;
9
use Symfony\Component\DependencyInjection\ContainerBuilder;
10
use Symfony\Component\DependencyInjection\Definition;
11
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
12
use Symfony\Component\DependencyInjection\Loader;
13
use Symfony\Component\DependencyInjection\Reference;
14
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
15
16
/**
17
 * This is the class that loads and manages your bundle configuration
18
 *
19
 * To learn more see {@link http://symfony.com/doc/current/cookbook/bundles/extension.html}
20
 */
21
class KunstmaanAdminExtension extends Extension implements PrependExtensionInterface
22
{
23
    /**
24
     * Loads a specific configuration.
25
     *
26
     * @param array            $configs   An array of configuration values
27
     * @param ContainerBuilder $container A ContainerBuilder instance
28
     *
29
     * @throws InvalidArgumentException When provided tag is not defined in this extension
30
     */
31 14
    public function load(array $configs, ContainerBuilder $container)
32
    {
33 14
        $container->setParameter('version_checker.url', 'https://cms.kunstmaan.be/version-check');
34 14
        $container->setParameter('version_checker.timeframe', 60 * 60 * 24);
35 14
        $container->setParameter('version_checker.enabled', true);
36
37 14
        $configuration = new Configuration();
38 14
        $config = $this->processConfiguration($configuration, $configs);
39
40 14
        if (\array_key_exists('dashboard_route', $config)) {
41 1
            $container->setParameter('kunstmaan_admin.dashboard_route', $config['dashboard_route']);
42
        }
43 14
        if (\array_key_exists('admin_password', $config)) {
44 1
            $container->setParameter('kunstmaan_admin.admin_password', $config['admin_password']);
45
        }
46 14
        if (\array_key_exists('enable_new_cms_authentication', $config)) {
47 14
            $enableCustomLogin = $config['enable_new_cms_authentication'];
48 14
            if (!$enableCustomLogin) {
49 14
                @trigger_error('Not setting "enable_new_cms_authentication" to true in the KunstmaanAdminBundle is deprecated as of 5.8, it will always be true in 6.0.', \E_USER_DEPRECATED);
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...
50
            }
51 14
            $container->setParameter('kunstmaan_admin.enable_new_cms_authentication', $enableCustomLogin);
52
        }
53 14
        $container->setParameter('kunstmaan_admin.admin_locales', $config['admin_locales']);
54 14
        $container->setParameter('kunstmaan_admin.default_admin_locale', $config['default_admin_locale']);
55
56 14
        $container->setParameter('kunstmaan_admin.session_security.ip_check', $config['session_security']['ip_check']);
57 14
        $container->setParameter('kunstmaan_admin.session_security.user_agent_check', $config['session_security']['user_agent_check']);
58
59 14
        $container->setParameter('kunstmaan_admin.admin_prefix', $this->normalizeUrlSlice($config['admin_prefix']));
60
61 14
        $container->setParameter('kunstmaan_admin.admin_exception_excludes', $config['admin_exception_excludes']);
62
63 14
        $container->setParameter('kunstmaan_admin.google_signin.enabled', $config['google_signin']['enabled']);
64 14
        $container->setParameter('kunstmaan_admin.google_signin.client_id', $config['google_signin']['client_id']);
65 14
        $container->setParameter('kunstmaan_admin.google_signin.client_secret', $config['google_signin']['client_secret']);
66 14
        $container->setParameter('kunstmaan_admin.google_signin.hosted_domains', $config['google_signin']['hosted_domains']);
67
68 14
        $container->setParameter('kunstmaan_admin.password_restrictions.min_digits', $config['password_restrictions']['min_digits']);
69 14
        $container->setParameter('kunstmaan_admin.password_restrictions.min_uppercase', $config['password_restrictions']['min_uppercase']);
70 14
        $container->setParameter('kunstmaan_admin.password_restrictions.min_special_characters', $config['password_restrictions']['min_special_characters']);
71 14
        $container->setParameter('kunstmaan_admin.password_restrictions.min_length', $config['password_restrictions']['min_length']);
72 14
        $container->setParameter('kunstmaan_admin.password_restrictions.max_length', $config['password_restrictions']['max_length']);
73 14
        $container->setParameter('kunstmaan_admin.enable_toolbar_helper', $config['enable_toolbar_helper']);
74 14
        $container->setParameter('kunstmaan_admin.toolbar_firewall_names', !empty($config['provider_keys']) ? $config['provider_keys'] : $config['toolbar_firewall_names']);
75 14
        $container->setParameter('kunstmaan_admin.admin_firewall_name', $config['admin_firewall_name']);
76 14
        $container->setParameter('kunstmaan_admin.user_class', $config['admin_user_class']);
77 14
        $container->setParameter('kunstmaan_admin.group_class', $config['admin_group_class']);
78
79 14
        $container->registerForAutoconfiguration(MenuAdaptorInterface::class)
80 14
            ->addTag('kunstmaan_admin.menu.adaptor');
81
82 14
        $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
83 14
        $loader->load('services.yml');
84 14
        $loader->load('commands.yml');
85
86 14
        if (!empty($config['enable_console_exception_listener']) && $config['enable_console_exception_listener']) {
87 14
            $loader->load('console_listener.yml');
88
        }
89
90 14
        if (0 !== \count($config['menu_items'])) {
91 1
            $this->addSimpleMenuAdaptor($container, $config['menu_items']);
92
        }
93
94 14
        $mailerAddress = $container->getDefinition('kunstmaan_admin.mailer.default_sender');
95 14
        $mailerAddress->setArgument('$address', $config['mail_from_address']);
96 14
        $mailerAddress->setArgument('$name', $config['mail_from_name']);
97
98 14
        $this->addWebsiteTitleParameter($container, $config);
99 14
        $this->addMultiLanguageParameter($container, $config);
100 14
        $this->addRequiredLocalesParameter($container, $config);
101 14
        $this->addDefaultLocaleParameter($container, $config);
102 14
    }
103
104 14
    public function prepend(ContainerBuilder $container)
105
    {
106 14
        $fosUserOriginalConfig = $container->getExtensionConfig('fos_user');
107 14
        if (!isset($fosUserOriginalConfig[0]['db_driver'])) {
108 14
            $fosUserConfig['db_driver'] = 'orm'; // other valid values are 'mongodb', 'couchdb'
0 ignored issues
show
Coding Style Comprehensibility introduced by
$fosUserConfig was never initialized. Although not strictly required by PHP, it is generally a good practice to add $fosUserConfig = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
109
        }
110 14
        $fosUserConfig['from_email']['address'] = '[email protected]';
0 ignored issues
show
Bug introduced by
The variable $fosUserConfig does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
111 14
        $fosUserConfig['from_email']['sender_name'] = 'KunstmaanCMS';
112 14
        $fosUserConfig['firewall_name'] = 'main';
113 14
        $fosUserConfig['user_class'] = 'Kunstmaan\AdminBundle\Entity\User';
114 14
        $fosUserConfig['group']['group_class'] = 'Kunstmaan\AdminBundle\Entity\Group';
115 14
        $fosUserConfig['resetting']['token_ttl'] = 86400;
116
        // Use this node only if you don't want the global email address for the resetting email
117 14
        $fosUserConfig['resetting']['email']['from_email']['address'] = '[email protected]';
118 14
        $fosUserConfig['resetting']['email']['from_email']['sender_name'] = 'KunstmaanCMS';
119 14
        $fosUserConfig['resetting']['email']['template'] = '@FOSUser/Resetting/email.txt.twig';
120 14
        $fosUserConfig['resetting']['form']['type'] = ResettingFormType::class;
121 14
        $fosUserConfig['resetting']['form']['name'] = 'fos_user_resetting_form';
122 14
        $fosUserConfig['resetting']['form']['validation_groups'] = ['ResetPassword'];
123
124 14
        $fosUserConfig['service']['mailer'] = 'fos_user.mailer.twig_swift';
125 14
        $container->prependExtensionConfig('fos_user', $fosUserConfig);
126
127
        // Manually register the KunstmaanAdminBundle folder as a FosUser override for symfony 4.
128 14
        if ($container->hasParameter('kernel.project_dir') && file_exists($container->getParameter('kernel.project_dir').'/templates/bundles/KunstmaanAdminBundle')) {
129
            $twigConfig['paths'][] = ['value' => '%kernel.project_dir%/templates/bundles/KunstmaanAdminBundle', 'namespace' => 'FOSUser'];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$twigConfig was never initialized. Although not strictly required by PHP, it is generally a good practice to add $twigConfig = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
130
        }
131 14
        $twigConfig['paths'][] = ['value' => \dirname(__DIR__).'/Resources/views', 'namespace' => 'FOSUser'];
0 ignored issues
show
Bug introduced by
The variable $twigConfig does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
132 14
        $container->prependExtensionConfig('twig', $twigConfig);
133
134
        // NEXT_MAJOR: Remove templating dependency
135
136 14
        $configs = $container->getExtensionConfig($this->getAlias());
137 14
        $this->processConfiguration(new Configuration(), $configs);
138 14
    }
139
140
    /**
141
     * {@inheritdoc}
142
     */
143 15
    public function getNamespace()
144
    {
145 15
        return 'http://bundles.kunstmaan.be/schema/dic/admin';
146
    }
147
148
    /**
149
     * {@inheritdoc}
150
     */
151
    public function getXsdValidationBasePath()
152
    {
153
        return __DIR__.'/../Resources/config/schema';
154
    }
155
156 1
    private function addSimpleMenuAdaptor(ContainerBuilder $container, array $menuItems)
157
    {
158 1
        $definition = new Definition('Kunstmaan\AdminBundle\Helper\Menu\SimpleMenuAdaptor', [
159 1
            new Reference('security.authorization_checker'),
160 1
            $menuItems,
161
        ]);
162 1
        $definition->addTag('kunstmaan_admin.menu.adaptor');
163
164 1
        $container->setDefinition('kunstmaan_admin.menu.adaptor.simple', $definition);
165 1
    }
166
167
    /**
168
     * @param string $urlSlice
169
     *
170
     * @return string
171
     */
172 14
    protected function normalizeUrlSlice($urlSlice)
173
    {
174
        /* Get rid of exotic characters that would break the url */
175 14
        $urlSlice = filter_var($urlSlice, FILTER_SANITIZE_URL);
176
177
        /* Remove leading and trailing slashes */
178 14
        $urlSlice = trim($urlSlice, '/');
179
180
        /* Make sure our $urlSlice is literally used in our regex */
181 14
        $urlSlice = preg_quote($urlSlice);
182
183 14
        return $urlSlice;
184
    }
185
186 14 View Code Duplication
    private function addWebsiteTitleParameter(ContainerBuilder $container, array $config)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
187
    {
188 14
        $websiteTitle = $config['website_title'];
189 14
        if (null === $config['website_title']) {
190 2
            @trigger_error('Not providing a value for the "kunstmaan_admin.website_title" config is deprecated since KunstmaanAdminBundle 5.2, this config value will be required in KunstmaanAdminBundle 6.0.', E_USER_DEPRECATED);
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...
191
192 2
            $websiteTitle = $container->hasParameter('websitetitle') ? $container->getParameter('websitetitle') : '';
193
        }
194
195 14
        $container->setParameter('kunstmaan_admin.website_title', $websiteTitle);
196 14
    }
197
198 14 View Code Duplication
    private function addMultiLanguageParameter(ContainerBuilder $container, array $config)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
199
    {
200 14
        $multilanguage = $config['multi_language'];
201 14
        if (null === $multilanguage) {
202 2
            @trigger_error('Not providing a value for the "kunstmaan_admin.multi_language" config is deprecated since KunstmaanAdminBundle 5.2, this config value will be required in KunstmaanAdminBundle 6.0.', E_USER_DEPRECATED);
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...
203
204 2
            $multilanguage = $container->hasParameter('multilanguage') ? $container->getParameter('multilanguage') : '';
205
        }
206
207 14
        $container->setParameter('kunstmaan_admin.multi_language', $multilanguage);
208 14
    }
209
210 14 View Code Duplication
    private function addRequiredLocalesParameter(ContainerBuilder $container, array $config)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
211
    {
212 14
        $requiredLocales = $config['required_locales'];
213 14
        if (null === $config['required_locales']) {
214 2
            @trigger_error('Not providing a value for the "kunstmaan_admin.required_locales" config is deprecated since KunstmaanAdminBundle 5.2, this config value will be required in KunstmaanAdminBundle 6.0.', E_USER_DEPRECATED);
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...
215
216 2
            $requiredLocales = $container->hasParameter('requiredlocales') ? $container->getParameter('requiredlocales') : '';
217
        }
218
219 14
        $container->setParameter('kunstmaan_admin.required_locales', $requiredLocales);
220 14
        $container->setParameter('requiredlocales', $requiredLocales); //Keep old parameter for to keep BC with routing config
221 14
    }
222
223 14 View Code Duplication
    private function addDefaultLocaleParameter(ContainerBuilder $container, array $config)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
224
    {
225 14
        $defaultLocale = $config['default_locale'];
226 14
        if (null === $config['default_locale']) {
227 2
            @trigger_error('Not providing a value for the "kunstmaan_admin.default_locale" config is deprecated since KunstmaanAdminBundle 5.2, this config value will be required in KunstmaanAdminBundle 6.0.', E_USER_DEPRECATED);
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...
228
229 2
            $defaultLocale = $container->hasParameter('defaultlocale') ? $container->getParameter('defaultlocale') : '';
230
        }
231
232 14
        $container->setParameter('kunstmaan_admin.default_locale', $defaultLocale);
233 14
    }
234
}
235