Completed
Push — master ( 536f20...20484c )
by Andrii
02:09
created

Plugin::getVendorDir()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/*
4
 * Composer plugin for bower/npm assets
5
 *
6
 * @link      https://github.com/hiqdev/composer-asset-plugin
7
 * @package   composer-asset-plugin
8
 * @license   BSD-3-Clause
9
 * @copyright Copyright (c) 2015, HiQDev (http://hiqdev.com/)
10
 */
11
12
namespace hiqdev\composerassetplugin;
13
14
use Composer\Composer;
15
use Composer\EventDispatcher\EventSubscriberInterface;
16
use Composer\IO\IOInterface;
17
use Composer\Json\JsonFile;
18
use Composer\Plugin\PluginInterface;
19
use Composer\Script\Event;
20
use Composer\Script\ScriptEvents;
21
22
/**
23
 * Plugin class.
24
 *
25
 * @author Andrii Vasyliev <[email protected]>
26
 */
27
class Plugin implements PluginInterface, EventSubscriberInterface
28
{
29
    public $file = 'composer-asset-plugin.lock';
30
31
    /**
32
     * @var Composer
33
     */
34
    protected $composer;
35
36
    /**
37
     * @var IOInterface
38
     */
39
    public $io;
40
41
    /**
42
     * List of package managers instances.
43
     * Initialized at activate.
44
     * @var array
45
     */
46
    protected $managers = ['bower', 'npm'];
47
48
    protected $packages;
49
50
    /**
51
     * Initializes the plugin object with passed $composer and $io.
52
     * Also initializes package managers.
53
     *
54
     * @param Composer $composer
55
     * @param IOInterface $io
56
     */
57
    public function activate(Composer $composer, IOInterface $io)
58
    {
59
        $this->composer = $composer;
60
        $this->io = $io;
61
        foreach ($this->managers as $m) {
62
            $class = 'hiqdev\composerassetplugin\\' . ucfirst($m);
63
            $managers[$m] = new $class($this);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$managers was never initialized. Although not strictly required by PHP, it is generally a good practice to add $managers = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
64
        }
65
        $this->managers = $managers;
0 ignored issues
show
Bug introduced by
The variable $managers does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
66
    }
67
68
    /**
69
     * Returns list of events the plugin wants to listen.
70
     *
71
     * @return array list of events
72
     */
73
    public static function getSubscribedEvents()
74
    {
75
        return [
76
            ScriptEvents::POST_INSTALL_CMD => [
77
                ['onPostInstall', 0],
78
            ],
79
            ScriptEvents::POST_UPDATE_CMD => [
80
                ['onPostUpdate', 0],
81
            ],
82
        ];
83
    }
84
85
    /**
86
     * Perform install. Called by composer after install.
87
     * @param Event $event
88
     */
89
    public function onPostInstall(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...
90
    {
91
        $lockFile = new JsonFile($this->file);
92
        if ($lockFile->exists()) {
93
            $this->loadPackages($lockFile);
94
        } else {
95
            $this->scanPackages();
96
        }
97
        $this->runAction('install');
98
    }
99
100
    /**
101
     * Perform update. Called by composer after update.
102
     * @param Event $event
103
     */
104
    public function onPostUpdate(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...
105
    {
106
        $this->scanPackages();
107
        $this->runAction('update');
108
    }
109
110
    public function setPackages(array $packages)
111
    {
112
        $this->packages = $packages;
113
    }
114
115
    public function getPackages()
116
    {
117
        if ($this->packages === null) {
118
            $this->packages = $this->composer->getRepositoryManager()->getLocalRepository()->getCanonicalPackages();
119
        }
120
121
        return $this->packages;
122
    }
123
124
    /**
125
     * Scan packages from the composer object.
126
     */
127
    protected function scanPackages()
128
    {
129
        foreach ($this->getPackages() as $package) {
130
            if ($package instanceof \Composer\Package\CompletePackage) {
131
                foreach ($this->managers as $m) {
132
                    $m->scanPackage($package);
133
                }
134
            }
135
        }
136
    }
137
138
    /**
139
     * Load packages from given lock file.
140
     * @param JsonFile $lockFile
141
     */
142
    protected function loadPackages(JsonFile $lockFile)
143
    {
144
        $lock = $lockFile->read();
145
        foreach ($this->managers as $name => $m) {
146
            $m->setConfig($lock[$name]);
147
        }
148
    }
149
150
    /**
151
     * Install packages after loading/scanning.
152
     * @param string $action
153
     */
154
    protected function runAction($action)
155
    {
156
        chdir($this->getVendorDir());
157
        foreach ($this->managers as $m) {
158
            $m->runAction($action);
159
        }
160
    }
161
162
    /**
163
     * Get path to vendor dir from composer.
164
     * @return string
165
     */
166
    public function getVendorDir()
167
    {
168
        return $this->composer->getConfig()->get('vendor-dir');
169
    }
170
}
171