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.
Completed
Pull Request — master (#154)
by joseph
26:39
created

  A

Complexity

Total Complexity 5

Size/Duplication

Total Lines 71
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 71
rs 10
c 0
b 0
f 0
wmc 5
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
     * @SuppressWarnings(PHPMD.StaticAccess)
72
     * @SuppressWarnings(PHPMD.Superglobals)
73
     */
74
    private function getContainerForNamespace(string $namespace): ContainerBuilder
75
    {
76
        if (isset($this->generatedContainerClass[$namespace])) {
77
            return $this->generatedContainerClass[$namespace];
78
        }
79
80
        $containerBuilder = new ContainerBuilder();
81
        $pathToFiles      = $this->copiedWorkDir . '/src/';
82
        $fileLocator      = new FileLocator($pathToFiles);
83
84
        $loader = new class($containerBuilder, $fileLocator, $namespace, $pathToFiles) extends FileLoader
85
        {
86
            /**
87
             * @var string
88
             */
89
            private $namespace;
90
            /**
91
             * @var string
92
             */
93
            private $pathToFiles;
94
95
            public function __construct(
96
                ContainerBuilder $container,
97
                FileLocatorInterface $locator,
98
                string $namespace,
99
                string $pathToFiles
100
            ) {
101
                parent::__construct($container, $locator);
102
                $this->namespace   = $namespace . '\\';
103
                $this->pathToFiles = str_replace('//', '/', $pathToFiles . '/*');
104
            }
105
106
            /**
107
             * Loads a resource.
108
             *
109
             * @param mixed       $resource The resource
110
             * @param string|null $type     The resource type or null if unknown
111
             *
112
             * @throws \Exception If something went wrong
113
             *
114
             */
115
            public function load($resource, $type = null): void
116
            {
117
                $definition = new Definition();
118
119
                $definition->setAutowired(true)->setAutoconfigured(true)->setPublic(true);
120
                $this->registerClasses($definition, $this->namespace, $this->pathToFiles);
121
                $dsmContainer = new Container();
122
                $dsmContainer->addConfiguration($this->container, $this->buildServerConfig());
123
                $this->container->compile();
124
            }
125
126
            /**
127
             * @return array
128
             */
129
            private function buildServerConfig()
130
            {
131
                SimpleEnv::setEnv(Config::getProjectRootDirectory() . '/.env');
132
                $testConfig                                 = $_SERVER;
133
                $testConfig[ConfigInterface::PARAM_DB_NAME] .= '_test';
134
                $testConfig[ConfigInterface::PARAM_DEVMODE] = true;
135
136
                return $testConfig;
137
            }
138
139
            /**
140
             * Returns whether this class supports the given resource.
141
             *
142
             * @param mixed       $resource A resource
143
             * @param string|null $type     The resource type or null if unknown
144
             *
145
             * @return bool True if this class supports the given resource, false otherwise
146
             */
147
            public function supports($resource, $type = null): bool
148
            {
149
                return true;
150
            }
151
152
            public function getContainer(): ContainerBuilder
153
            {
154
                return $this->container;
155
            }
156
        };
157
158
        $loader->load('required by the interface');
159
160
        $this->generatedContainerClass[$namespace] = $loader->getContainer();
161
162
        return $this->generatedContainerClass[$namespace];
163
    }
164
}
165