Completed
Push — 1.0 ( de4310...f8542e )
by Rob
12s
created

FileSystemLoaderFactory   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 8
dl 0
loc 161
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 8 1
A getName() 0 4 1
B addConfiguration() 0 42 1
B resolveDataRoots() 0 16 5
A getBundleResourcePaths() 0 12 2
A getBundlePathsUsingMetadata() 0 6 1
A getBundlePathsUsingNamedObj() 0 16 3
A createLocatorReference() 0 10 2
1
<?php
2
3
/*
4
 * This file is part of the `liip/LiipImagineBundle` project.
5
 *
6
 * (c) https://github.com/liip/LiipImagineBundle/graphs/contributors
7
 *
8
 * For the full copyright and license information, please view the LICENSE.md
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Liip\ImagineBundle\DependencyInjection\Factory\Loader;
13
14
use Liip\ImagineBundle\Exception\InvalidArgumentException;
15
use Liip\ImagineBundle\Utility\Framework\SymfonyFramework;
16
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
17
use Symfony\Component\DependencyInjection\ContainerBuilder;
18
use Symfony\Component\DependencyInjection\ContainerInterface;
19
use Symfony\Component\DependencyInjection\Reference;
20
21
class FileSystemLoaderFactory extends AbstractLoaderFactory
22
{
23
    /**
24
     * {@inheritdoc}
25
     */
26
    public function create(ContainerBuilder $container, $loaderName, array $config)
27
    {
28
        $definition = $this->getChildLoaderDefinition();
29
        $definition->replaceArgument(2, $this->resolveDataRoots($config['data_root'], $config['bundle_resources'], $container));
30
        $definition->replaceArgument(3, $this->createLocatorReference($config['locator']));
31
32
        return $this->setTaggedLoaderDefinition($loaderName, $definition, $container);
33
    }
34
35
    /**
36
     * {@inheritdoc}
37
     */
38
    public function getName()
39
    {
40
        return 'filesystem';
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function addConfiguration(ArrayNodeDefinition $builder)
47
    {
48
        $builder
49
            ->children()
50
                ->enumNode('locator')
51
                    ->values(array('filesystem', 'filesystem_insecure'))
52
                    ->info('Using the "filesystem_insecure" locator is not recommended due to a less secure resolver mechanism, but is provided for those using heavily symlinked projects.')
53
                    ->defaultValue('filesystem')
54
                ->end()
55
                ->arrayNode('data_root')
56
                    ->beforeNormalization()
57
                    ->ifString()
58
                        ->then(function ($value) { return array($value); })
59
                    ->end()
60
                    ->treatNullLike(array())
61
                    ->treatFalseLike(array())
62
                    ->defaultValue(array('%kernel.root_dir%/../web'))
63
                    ->prototype('scalar')
64
                        ->cannotBeEmpty()
65
                    ->end()
66
                ->end()
67
                ->arrayNode('bundle_resources')
68
                    ->addDefaultsIfNotSet()
69
                    ->children()
70
                        ->booleanNode('enabled')
71
                            ->defaultFalse()
72
                        ->end()
73
                        ->enumNode('access_control_type')
74
                            ->values(array('blacklist', 'whitelist'))
75
                            ->info('Sets the access control method applied to bundle names in "access_control_list" into a blacklist or whitelist.')
76
                            ->defaultValue('blacklist')
77
                        ->end()
78
                        ->arrayNode('access_control_list')
79
                            ->defaultValue(array())
80
                            ->prototype('scalar')
81
                                ->cannotBeEmpty()
82
                            ->end()
83
                        ->end()
84
                    ->end()
85
                ->end()
86
            ->end();
87
    }
88
89
90
    /*
91
     * @param string[]         $staticPaths
92
     * @param array            $config
93
     * @param ContainerBuilder $container
94
     *
95
     * @return string[]
96
     */
97
    private function resolveDataRoots(array $staticPaths, array $config, ContainerBuilder $container)
98
    {
99
        if (false === $config['enabled']) {
100
            return $staticPaths;
101
        }
102
103
        $resourcePaths = array();
104
105
        foreach ($this->getBundleResourcePaths($container) as $name => $path) {
106
            if (('whitelist' === $config['access_control_type']) === in_array($name, $config['access_control_list']) && is_dir($path)) {
107
                $resourcePaths[$name] = $path;
108
            }
109
        }
110
111
        return array_merge($staticPaths, $resourcePaths);
112
    }
113
114
    /**
115
     * @param ContainerBuilder $container
116
     *
117
     * @return string[]
118
     */
119
    private function getBundleResourcePaths(ContainerBuilder $container)
120
    {
121
        if ($container->hasParameter('kernel.bundles_metadata')) {
122
            $paths = $this->getBundlePathsUsingMetadata($container->getParameter('kernel.bundles_metadata'));
123
        } else {
124
            $paths = $this->getBundlePathsUsingNamedObj($container->getParameter('kernel.bundles'));
125
        }
126
127
        return array_map(function ($path) {
128
            return $path.DIRECTORY_SEPARATOR.'Resources'.DIRECTORY_SEPARATOR.'public';
129
        }, $paths);
130
    }
131
132
    /**
133
     * @param array[] $metadata
134
     *
135
     * @return string[]
136
     */
137
    private function getBundlePathsUsingMetadata(array $metadata)
138
    {
139
        return array_combine(array_keys($metadata), array_map(function ($data) {
140
            return $data['path'];
141
        }, $metadata));
142
    }
143
144
    /**
145
     * @param string[] $classes
146
     *
147
     * @return string[]
148
     */
149
    private function getBundlePathsUsingNamedObj(array $classes)
150
    {
151
        $paths = array();
152
153
        foreach ($classes as $c) {
154
            try {
155
                $r = new \ReflectionClass($c);
156
            } catch (\ReflectionException $exception) {
157
                throw new InvalidArgumentException(sprintf('Unable to resolve bundle "%s" while auto-registering bundle resource paths.', $c), null, $exception);
158
            }
159
160
            $paths[$r->getShortName()] = dirname($r->getFileName());
161
        }
162
163
        return $paths;
164
    }
165
166
    /**
167
     * @param string $reference
168
     *
169
     * @return Reference
170
     */
171
    private function createLocatorReference($reference)
172
    {
173
        $name = sprintf('liip_imagine.binary.locator.%s', $reference);
174
175
        if (SymfonyFramework::hasDefinitionSharing()) {
176
            return new Reference($name);
177
        }
178
179
        return new Reference($name, ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false);
0 ignored issues
show
Unused Code introduced by
The call to Reference::__construct() has too many arguments starting with false.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
180
    }
181
}
182