GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Pull Request — master (#154)
by joseph
25:46
created

php$0 ➔ getContainerForNamespace()   B

Complexity

Conditions 1

Size

Total Lines 85

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 85
rs 8.3272
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A GetGeneratedCodeContainerTrait.php$0 ➔ load() 0 9 1
A GetGeneratedCodeContainerTrait.php$0 ➔ __construct() 0 9 1
A GetGeneratedCodeContainerTrait.php$0 ➔ supports() 0 3 1
A GetGeneratedCodeContainerTrait.php$0 ➔ getContainer() 0 3 1
A GetGeneratedCodeContainerTrait.php$0 ➔ buildServerConfig() 0 7 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
4
namespace EdmondsCommerce\DoctrineStaticMeta\Tests\Assets;
5
6
use EdmondsCommerce\DoctrineStaticMeta\Config;
7
use EdmondsCommerce\DoctrineStaticMeta\ConfigInterface;
8
use EdmondsCommerce\DoctrineStaticMeta\Container;
9
use EdmondsCommerce\DoctrineStaticMeta\SimpleEnv;
10
use Symfony\Component\Config\FileLocator;
11
use Symfony\Component\Config\FileLocatorInterface;
12
use Symfony\Component\DependencyInjection\ContainerBuilder;
13
use Symfony\Component\DependencyInjection\Definition;
14
use Symfony\Component\DependencyInjection\Loader\FileLoader;
15
16
/**
17
 * During testing you may need to access the generated classes that are created by the test. If they have several
18
 * dependencies, manually creating these can become tedious and ties you test to the current implementation of not just
19
 * your class, but each of the dependencies as well.
20
 *
21
 * Rather than having to do this, or create factories which present similar problems, it is easier to create a
22
 * container
23
 * for the generated code and then access the class that way.
24
 *
25
 * This trait does the following:
26
 *
27
 *  - Creates a new Symfony DI File loader
28
 *  - Autowires and sets as public every class in the generated directory
29
 *  - Adds in the default DSM DI configuration so we have access to those classes as well
30
 *  - Provides a method to fetch a class from the new container.
31
 *
32
 * This functionality is being included within a trait because it is expensive to generate this, so it should only be
33
 * brought in as and when needed
34
 */
35
trait GetGeneratedCodeContainerTrait
36
{
37
    /**
38
     * @var array|ContainerBuilder[]
39
     */
40
    private $generatedContainerClass = [];
41
42
    /**
43
     * Use this to get a generated class from a custom container build just for your test
44
     *
45
     * @param string $className
46
     *
47
     * @return object
48
     * @throws \Exception
49
     */
50
    public function getGeneratedClass(string $className)
51
    {
52
        /* If we don't have these two properties nothing is going to work */
53
        if (!isset($this->copiedWorkDir, $this->copiedRootNamespace)) {
54
            throw new \RuntimeException('Required properties are not set');
55
        }
56
57
        return $this->getContainerForNamespace($this->copiedRootNamespace)->get(trim($className, '\\'));
58
    }
59
60
    /**
61
     * As the code is generated for each and every test, it is unlikely that this will need to be reused. However, if
62
     * you do need access to two different classes in the same test, it would be wasteful to build the container twice.
63
     *
64
     * Therefore we will cache the container based on the generated namespace, meaning that getting a second class in
65
     * the same test should be quick
66
     *
67
     * @param string $namespace
68
     *
69
     * @return ContainerBuilder
70
     * @throws \Exception
71
     */
72
    private function getContainerForNamespace(string $namespace): ContainerBuilder
73
    {
74
        if (isset($this->generatedContainerClass[$namespace])) {
75
            return $this->generatedContainerClass[$namespace];
76
        }
77
78
        $containerBuilder = new ContainerBuilder();
79
        $pathToFiles      = $this->copiedWorkDir . '/src/';
80
        $fileLocator      = new FileLocator($pathToFiles);
81
82
        $loader = new class($containerBuilder, $fileLocator, $namespace, $pathToFiles) extends FileLoader
83
        {
84
            /**
85
             * @var string
86
             */
87
            private $namespace;
88
            /**
89
             * @var string
90
             */
91
            private $pathToFiles;
92
93
            public function __construct(
94
                ContainerBuilder $container,
95
                FileLocatorInterface $locator,
96
                string $namespace,
97
                string $pathToFiles
98
            ) {
99
                parent::__construct($container, $locator);
100
                $this->namespace   = $namespace . '\\';
101
                $this->pathToFiles = str_replace('//', '/', $pathToFiles . '/*');
102
            }
103
104
            /**
105
             * Loads a resource.
106
             *
107
             * @param mixed       $resource The resource
108
             * @param string|null $type     The resource type or null if unknown
109
             *
110
             * @throws \Exception If something went wrong
111
             * @SupressWarnings(PHPMD.Superglobals)
112
             */
113
            public function load($resource, $type = null): void
114
            {
115
                $definition = new Definition();
116
117
                $definition->setAutowired(true)->setAutoconfigured(true)->setPublic(true);
118
                $this->registerClasses($definition, $this->namespace, $this->pathToFiles);
119
                $dsmContainer = new Container();
120
                $dsmContainer->addConfiguration($this->container, $this->buildServerConfig());
121
                $this->container->compile();
122
            }
123
124
            private function buildServerConfig()
125
            {
126
                SimpleEnv::setEnv(Config::getProjectRootDirectory() . '/.env');
127
                $testConfig                                               = $_SERVER;
128
                $testConfig[ConfigInterface::PARAM_DB_NAME]               .= '_test';
129
                $testConfig[ConfigInterface::PARAM_DEVMODE]               = true;
130
                return $testConfig;
131
            }
132
133
            /**
134
             * Returns whether this class supports the given resource.
135
             *
136
             * @param mixed       $resource A resource
137
             * @param string|null $type     The resource type or null if unknown
138
             *
139
             * @return bool True if this class supports the given resource, false otherwise
140
             */
141
            public function supports($resource, $type = null): bool
142
            {
143
                return true;
144
            }
145
146
            public function getContainer(): ContainerBuilder
147
            {
148
                return $this->container;
149
            }
150
        };
151
152
        $loader->load('required by the interface');
153
154
        $this->generatedContainerClass[$namespace] = $loader->getContainer();
155
156
        return $this->generatedContainerClass[$namespace];
157
    }
158
}
159