LibraryLoader   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 172
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 8
Bugs 0 Features 0
Metric Value
eloc 44
c 8
b 0
f 0
dl 0
loc 172
ccs 0
cts 48
cp 0
rs 10
wmc 20

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getCustomConfigurationDir() 0 3 1
A getContainer() 0 3 1
A getVendorDir() 0 3 1
A __construct() 0 3 1
B load() 0 51 7
A getCustomConfigurationPublicDir() 0 3 1
B loadConfiguration() 0 43 8
1
<?php
2
3
/**
4
 * TechDivision\Import\Cli\Configuration\LibraryLoader
5
 *
6
 * PHP version 7
7
 *
8
 * @author    Tim Wagner <[email protected]>
9
 * @copyright 2016 TechDivision GmbH <[email protected]>
10
 * @license   https://opensource.org/licenses/MIT
11
 * @link      https://github.com/techdivision/import-cli-simple
12
 * @link      http://www.techdivision.com
13
 */
14
15
namespace TechDivision\Import\Cli\Configuration;
16
17
use Symfony\Component\Config\FileLocator;
18
use Symfony\Component\Config\Loader\LoaderInterface;
19
use Symfony\Component\DependencyInjection\ContainerInterface;
20
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
21
use TechDivision\Import\Configuration\ConfigurationInterface;
22
use TechDivision\Import\Cli\Utils\DependencyInjectionKeys;
23
24
/**
25
 * The library loader implementation.
26
 *
27
 * @author    Tim Wagner <[email protected]>
28
 * @copyright 2016 TechDivision GmbH <[email protected]>
29
 * @license   https://opensource.org/licenses/MIT
30
 * @link      https://github.com/techdivision/import-cli-simple
31
 * @link      http://www.techdivision.com
32
 */
33
class LibraryLoader
34
{
35
36
    /**
37
     * The container instance.
38
     *
39
     * @var \Symfony\Component\DependencyInjection\ContainerInterface
40
     */
41
    protected $container;
42
43
    /**
44
     * Initializes the configuration loader.
45
     *
46
     * @param \Symfony\Component\DependencyInjection\ContainerInterface $container The container instance
47
     */
48
    public function __construct(ContainerInterface $container)
49
    {
50
        $this->container = $container;
51
    }
52
53
    /**
54
     * Return's the DI container instance.
55
     *
56
     * @return \Symfony\Component\DependencyInjection\ContainerInterface The DI container instance
57
     */
58
    protected function getContainer()
59
    {
60
        return $this->container;
61
    }
62
63
    /**
64
     * Return's the absolute path to the actual vendor directory.
65
     *
66
     * @return string The absolute path to the actual vendor directory
67
     */
68
    protected function getVendorDir()
69
    {
70
        return $this->getContainer()->getParameter(DependencyInjectionKeys::CONFIGURATION_VENDOR_DIR);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getContain...NFIGURATION_VENDOR_DIR) also could return the type array|boolean which is incompatible with the documented return type string.
Loading history...
71
    }
72
73
    /**
74
     * Return's the relative path to the custom configuration directory.
75
     *
76
     * @return string The relative path to the custom configuration directory
77
     */
78
    protected function getCustomConfigurationDir()
79
    {
80
        return $this->getContainer()->getParameter(DependencyInjectionKeys::APPLICATION_CUSTOM_CONFIGURATION_DIR);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getContain...STOM_CONFIGURATION_DIR) also could return the type array|boolean which is incompatible with the documented return type string.
Loading history...
81
    }
82
83
    /**
84
     * Return's the relative path to the custom configuration public directory.
85
     *
86
     * @return string The relative path to the custom configuration public directory
87
     */
88
    protected function getCustomConfigurationPublicDir()
89
    {
90
        return $this->getContainer()->getParameter(DependencyInjectionKeys::APPLICATION_CUSTOM_CONFIGURATION_PUBLIC_DIR);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getContain...NFIGURATION_PUBLIC_DIR) also could return the type array|boolean which is incompatible with the documented return type string.
Loading history...
91
    }
92
93
    /**
94
     * Load's the external libraries registered in the passed configuration.
95
     *
96
     * @param \TechDivision\Import\Configuration\ConfigurationInterface $configuration The configuration instance
97
     *
98
     * @return void
99
     */
100
    public function load(ConfigurationInterface $configuration)
101
    {
102
103
        // load the DI container, vendor and custom configuration
104
        // directory as well as the Magento version
105
        $container = $this->getContainer();
106
        $vendorDir = $this->getVendorDir();
107
        $magentoVersion = $configuration->getMagentoVersion();
108
        $customConfigurationDir = $this->getCustomConfigurationDir();
109
110
        // initialize the default loader and load the DI configuration for the this library
111
        $defaultLoader = new XmlFileLoader($container, new FileLocator($vendorDir));
112
113
        // load the DI configuration for all the extension libraries
114
        foreach ($configuration->getExtensionLibraries() as $library) {
115
            $this->loadConfiguration($defaultLoader, $magentoVersion, sprintf('%s/%s', $vendorDir, $library));
116
        }
117
118
        // register autoloaders for additional vendor directories
119
        $customLoader = new XmlFileLoader($container, new FileLocator());
120
        foreach ($configuration->getAdditionalVendorDirs() as $additionalVendorDir) {
121
            // try to load the vendor directory's auto loader, if available. Otherwise we assume
122
            // that the vendor directory uses an autoloader that has already been loaded, e. g. in
123
            // case of Magento which has app/code registered as vendor directory what we want to use
124
            if (file_exists($autoLoader = $additionalVendorDir->getVendorDir() . '/autoload.php')) {
125
                require $autoLoader;
126
            }
127
128
            // try to load the DI configuration for the configured extension libraries
129
            foreach ($additionalVendorDir->getLibraries() as $library) {
130
                // concatenate the directory for the library
131
                $libDir = sprintf('%s/%s', $additionalVendorDir->getVendorDir(), $library);
132
                // prepend the installation directory, if the vendor is relative to it
133
                if ($additionalVendorDir->isRelative()) {
134
                    $libDir = sprintf('%s/%s', $configuration->getInstallationDir(), $libDir);
135
                }
136
137
                // create the canonicalized absolute pathname and try to load the configuration
138
                if ($libraryDir = realpath($libDir)) {
139
                    $this->loadConfiguration($customLoader, $magentoVersion, $libraryDir);
140
                } else {
141
                    throw new \Exception(sprintf('Can\'t find find library directory "%s"', $libDir));
142
                }
143
            }
144
        }
145
146
        // initialize the project specific configuration loader for the DI configuration
147
        $projectLoader = new XmlFileLoader($container, new FileLocator(getcwd()));
148
149
        // finally load the project specific custom library configuration which overwrites the default one
150
        $this->loadConfiguration($projectLoader, $magentoVersion, $customConfigurationDir);
151
    }
152
153
    /**
154
     * Loads the version specific Symfony DI configuration.
155
     *
156
     * @param \Symfony\Component\Config\Loader\LoaderInterface $loader         The Symfony DI loader instance
157
     * @param string                                           $magentoVersion The Magento Version to load the configuration for
158
     * @param string                                           $libraryDir     The library directory
159
     *
160
     * @return boolean TRUE if the configuration file has been loaded, else FALSE
161
     */
162
    protected function loadConfiguration(LoaderInterface $loader, $magentoVersion, $libraryDir)
163
    {
164
165
        // load the default Symfony Di configuration
166
        if (file_exists($diConfiguration = sprintf('%s/symfony/Resources/config/services.xml', $libraryDir))) {
167
            // load the DI configuration
168
            $loader->load($diConfiguration);
169
            // initialize the array for the directories with the
170
            // available versions that'll override the defaults
171
            $versions = array();
172
            // load the directories that equals the versions custom configuration files are available for
173
            $iterator = new \DirectoryIterator(sprintf('%s/symfony/Resources/config', $libraryDir));
174
            // iterate over the subdirectories
175
            while ($iterator->valid()) {
176
                // query whether or not we've a directory, if yes we
177
                // assume it'll contain additional version information
178
                if ($iterator->isDir() && !$iterator->isDot()) {
179
                    $versions[] = $iterator->current()->getPathname();
180
                }
181
                // continue reading the directry content
182
                $iterator->next();
183
            }
184
185
            // sort the directories descending by their version
186
            usort($versions, 'version_compare');
187
            krsort($versions);
188
189
            // override DI configuration with version specifc data
190
            foreach ($versions as $version) {
191
                if (version_compare(basename($version), $magentoVersion, '<=')) {
192
                    if (file_exists($diConfiguration = sprintf('%s/services.xml', $version))) {
193
                        // load the version specific DI configuration
194
                        $loader->load($diConfiguration);
195
                    }
196
                }
197
            }
198
199
            // return TRUE if the configuration has been loaded
200
            return true;
201
        }
202
203
        // return FALSE if the configuration file has NOT been available
204
        return false;
205
    }
206
}
207