Completed
Push — dev ( ffd4b5...6f78cf )
by Marc
02:13
created

Manager::getComposerPackages()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
rs 9.4285
cc 3
eloc 9
nc 2
nop 0
1
<?php namespace Mascame\Artificer\Extension;
2
3
use Illuminate\Support\Facades\App;
4
use Illuminate\Support\Str;
5
use Mascame\Artificer\Widgets\CKeditor;
6
use Mascame\Artificer\Widgets\DateTimepicker;
7
use Mascame\Extender\Booter\BooterInterface;
8
use Mascame\Extender\Event\EventInterface;
9
use Mascame\Extender\Installer\InstallerInterface;
10
use Symfony\Component\CssSelector\XPath\Extension\AbstractExtension;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Mascame\Artificer\Extension\AbstractExtension.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
11
use Symfony\Component\HttpFoundation\File\File;
12
13
class Manager extends \Mascame\Extender\Manager {
14
15
    /**
16
     * @var \Mascame\Artificer\Plugin\Manager|\Mascame\Artificer\Widget\Manager
17
     */
18
    protected $manager;
19
20
    /**
21
     * @var string
22
     */
23
    protected $type = 'extension';
24
25
    /**
26
     * Composer packages
27
     *
28
     * @var array
29
     */
30
    protected $composerPackages = [];
31
32
    protected static $packages = [];
33
34
    /**
35
     * @param InstallerInterface $installer
36
     * @param BooterInterface|null $booter
37
     * @param EventInterface|null $eventDispatcher
38
     * @throws \Exception
39
     */
40
    public function __construct(
41
        InstallerInterface $installer,
42
        BooterInterface $booter = null,
43
        EventInterface $eventDispatcher = null
44
    )
45
    {
46
        parent::__construct($installer, $booter, $eventDispatcher);
47
48
        $this->composerPackages = $this->getComposerPackages();
49
    }
50
51
    public function getPackages() {
52
        return self::$packages;
53
    }
54
55
    /**
56
     * @param $package
57
     * @param array|string $plugins
58
     * @return bool
59
     * @throws \Exception
60
     */
61
    public function add($package, $plugins)
62
    {
63
        if (! $this->isValidPackageName($package)) {
64
            throw new \Exception('Extension namespace is mandatory and must be compliant to "vendor/package". Provided: ' . $package);
65
        }
66
67
        // Convert to array
68
        if (! is_array($plugins)) $plugins = [$plugins];
69
70
        // Get package info
71
        if (! isset(self::$packages[$package])) {
72
            self::$packages[$package] = new \stdClass();
73
74
            if (isset($this->composerPackages[$package])) {
75
                $packageData = $this->composerPackages[$package];
76
            } else {
77
                $packageData = [
78
                    'name' => $package,
79
                    'version' => 'none',
80
                    'description' => null,
81
                    'authors' => [
82
                        [
83
                            'name' => 'Anonymous',
84
                            'email' => '[email protected]'
85
                        ]
86
                    ]
87
                ];
88
            }
89
90
            self::$packages[$package] = (object) $packageData;
91
        }
92
93
        foreach ($plugins as $pluginName) {
94
            // Group the extensions provided under the package namespace
95
            self::$packages[$package]->provides[$this->type][] = $pluginName;
96
97
            parent::add($pluginName, function() use ($pluginName, $package) {
98
99
                /**
100
                 * First we try to resolve the plugin within the App Container
101
                 */
102
                try {
103
                    $plugin = app($pluginName);
104
                } catch (\ReflectionException $e) {
105
                    $plugin = new $pluginName;
106
                }
107
108
                $plugin->package = $package;
109
110
                return $plugin;
111
            });
112
        }
113
114
        return true;
115
    }
116
    
117
    /**
118
     * vendor/name
119
     *
120
     * @param $name
121
     * @return bool
122
     */
123
    protected function isValidPackageName($name) {
124
        $regex = "/^[\\w-]+\\/[\\w-]+$/";
125
126
        preg_match($regex, $name, $matches);
127
128
        return (count($matches) > 0);
129
    }
130
131
    /**
132
     * @return array
133
     */
134
    protected function getComposerPackages() {
135
        $installedPackagesFile = config('admin.vendorPath') . '/composer/installed.json';
136
        $packagesWithName = [];
137
        
138
        if (\File::exists($installedPackagesFile)) {
139
            $packages = json_decode(\File::get($installedPackagesFile), true);
140
141
            $packagesWithName = [];
142
143
            foreach ($packages as $package) {
144
                $packagesWithName[$package['name']] = $package;
145
            }
146
        }
147
        
148
        return $packagesWithName;
149
    }
150
151
    /**
152
     * @param $namespace
153
     * @return mixed
154
     * @throws \Exception
155
     */
156
    public function getVersion($namespace) {
157
        if (isset(self::$packages[$namespace])) {
158
            return self::$packages[$namespace]['version'];
159
        }
160
161
        throw new \Exception('Package with namespace "' . $namespace . '" not found (Should be an existent composer package).');
162
    }
163
}
164