Completed
Push — 1.1 ( 17428c...7dea68 )
by David
10:20
created

DiscoveryPlugin::beforeDumpAutoload()   B

Complexity

Conditions 2
Paths 2

Size

Total Lines 33
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 33
rs 8.8571
c 0
b 0
f 0
cc 2
eloc 18
nc 2
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace TheCodingMachine\Discovery;
6
7
use Composer\Composer;
8
use Composer\EventDispatcher\EventSubscriberInterface;
9
use Composer\Factory;
10
use Composer\IO\IOInterface;
11
use Composer\Package\PackageInterface;
12
use Composer\Plugin\PluginInterface;
13
use Composer\Script\Event;
14
use Composer\Script\ScriptEvents;
15
use Seld\JsonLint\JsonParser;
16
use Seld\JsonLint\ParsingException;
17
use Symfony\Component\Filesystem\Filesystem;
18
use TheCodingMachine\Discovery\Utils\JsonException;
19
20
class DiscoveryPlugin implements PluginInterface, EventSubscriberInterface
21
{
22
    /**
23
     * @var Composer
24
     */
25
    protected $composer;
26
    protected $io;
27
28
    /**
29
     * Apply plugin modifications to Composer.
30
     *
31
     * @param Composer    $composer
32
     * @param IOInterface $io
33
     */
34
    public function activate(Composer $composer, IOInterface $io)
35
    {
36
        $this->composer = $composer;
37
        $this->io = $io;
38
    }
39
40
    public static function getSubscribedEvents()
41
    {
42
        return [
43
            ScriptEvents::PRE_AUTOLOAD_DUMP => 'beforeDumpAutoload',
44
        ];
45
    }
46
47
    /**
48
     * @return AssetsBuilder
49
     */
50
    private function getAssetsBuilder() : AssetsBuilder
51
    {
52
        $installationManager = $this->composer->getInstallationManager();
53
        $rootDir = dirname(Factory::getComposerFile());
54
        return new AssetsBuilder($installationManager, $this->io, $rootDir);
55
    }
56
57
    public function beforeDumpAutoload(Event $event)
0 ignored issues
show
Unused Code introduced by
The parameter $event is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
58
    {
59
        // Plugin has been uninstalled
60
        if (!file_exists(__FILE__)) {
61
            return;
62
        }
63
64
        $fileSystem = new Filesystem();
65
66
        $discoveryPackages = $this->getDiscoveryPackages();
67
        $assetTypes = $this->getAssetsBuilder()->buildAssetTypes($discoveryPackages);
68
69
        // Let's get an array of values, indexed by asset type (to store in the discovery_values.php file)
70
        $values = array_map(function (AssetType $assetType) {
71
            return $assetType->getValues();
72
        }, $assetTypes);
73
74
        $fileSystem->dumpFile('.discovery/discovery_values.php', '<?php
75
return '.var_export($values, true).";\n");
76
77
        // Let's get an array of assetTypes, indexed by asset type (to store in the discovery_asset_types.php file)
78
        $assetTypes = array_map(function (AssetType $assetType) {
79
            return $assetType->jsonSerialize();
80
        }, $assetTypes);
81
82
        $fileSystem->dumpFile('.discovery/discovery_asset_types.php', '<?php
83
return '.var_export($assetTypes, true).";\n");
84
85
        // Let's copy the Discovery class in the .discovery directory. This is needed because otherwise, we have no way to "find" the .discovery directory easily.
86
        $fileSystem->dumpFile('.discovery/Discovery.php', file_get_contents(__DIR__.'/Discovery.php.tpl'));
87
88
        $this->registerClassInAutoloader();
89
    }
90
91
    /**
92
     * Returns the list of packages containing a "discovery.json" file in the root directory.
93
     *
94
     * Packages are ordered by dependencies.
95
     *
96
     * @return PackageInterface[]
97
     */
98
    private function getDiscoveryPackages()
99
    {
100
        $localRepos = $this->composer->getRepositoryManager()->getLocalRepository();
101
        $unorderedPackagesList = $localRepos->getPackages();
102
103
        $orderedPackageList = PackagesOrderer::reorderPackages($unorderedPackagesList);
104
105
        return array_filter($orderedPackageList, function (PackageInterface $package) {
106
            $installationManager = $this->composer->getInstallationManager();
107
108
            $packageInstallPath = $installationManager->getInstallPath($package);
109
110
            return file_exists($packageInstallPath.'/discovery.json');
111
        });
112
    }
113
114
115
116
    /**
117
     * This registers the generated TheCodingMachine\Discovery class in the autoloader.
118
     */
119
    private function registerClassInAutoloader()
120
    {
121
        // Let's dynamically add a Discovery file to the autoloader
122
        $discoveryFile = '.discovery/Discovery.php';
123
        $autoload = $this->composer->getPackage()->getAutoload();
124
        $autoload['classmap'][] = $discoveryFile;
125
        $this->composer->getPackage()->setAutoload($autoload);
126
    }
127
}
128