Completed
Push — master ( 7133c6...a8b998 )
by Christian
08:08 queued 04:58
created

AbstractCommand::getDeclaredModuleFiles()   B

Complexity

Conditions 4
Paths 4

Size

Total Lines 27
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 18
c 0
b 0
f 0
nc 4
nop 0
dl 0
loc 27
rs 8.5806
1
<?php
2
3
namespace N98\Magento\Command\Developer\Module\Disableenable;
4
5
use InvalidArgumentException;
6
use N98\Magento\Command\AbstractMagentoCommand;
7
use RuntimeException;
8
use Symfony\Component\Console\Input\InputArgument;
9
use Symfony\Component\Console\Input\InputInterface;
10
use Symfony\Component\Console\Input\InputOption;
11
use Symfony\Component\Console\Output\OutputInterface;
12
13
/**
14
 * Enable disable Magento module(s)
15
 */
16
class AbstractCommand extends AbstractMagentoCommand
17
{
18
    /**
19
     * @var Mage_Core_Model_Config
20
     */
21
    protected $config;
22
23
    /**
24
     * @var string
25
     */
26
    protected $modulesDir;
27
28
    /**
29
     * @var string
30
     */
31
    protected $commandName;
32
33
    /**
34
     * Setup
35
     *
36
     * @return void
37
     */
38
    protected function configure()
39
    {
40
        $this
41
            ->setName('dev:module:' . $this->commandName)
42
            ->addArgument('moduleName', InputArgument::OPTIONAL, 'Name of module to ' . $this->commandName)
43
            ->addOption('codepool', null, InputOption::VALUE_OPTIONAL, 'Name of codePool to ' . $this->commandName)
44
            ->setDescription(ucwords($this->commandName) . ' a module or all modules in codePool');
45
    }
46
47
    /**
48
     * Execute command
49
     *
50
     * @param InputInterface  $input
51
     * @param OutputInterface $output
52
     *
53
     * @return void
54
     *
55
     * @throws InvalidArgumentException
56
     */
57
    protected function execute(InputInterface $input, OutputInterface $output)
58
    {
59
        $this->detectMagento($output, true);
60
        if (false === $this->initMagento()) {
61
            throw new RuntimeException('Magento could not be loaded');
62
        }
63
        $this->config = \Mage::getConfig();
64
        $this->modulesDir = $this->config->getOptions()->getEtcDir() . DS . 'modules' . DS;
65
        if ($codePool = $input->getOption('codepool')) {
66
            $output->writeln('<info>' . ($this->commandName == 'enable' ? 'Enabling' : 'Disabling') .
67
                ' modules in <comment>' . $codePool . '</comment> codePool...</info>');
68
            $this->enableCodePool($codePool, $output);
69
        } elseif ($module = $input->getArgument('moduleName')) {
70
            $this->enableModule($module, $output);
71
        } else {
72
            throw new InvalidArgumentException('No code-pool option nor module-name argument');
73
        }
74
    }
75
76
    /**
77
     * Search a code pool for modules and enable them
78
     *
79
     * @param string $codePool
80
     * @param OutputInterface $output
81
     *
82
     * @return int|void
83
     */
84
    protected function enableCodePool($codePool, OutputInterface $output)
85
    {
86
        $modules = $this->config->getNode('modules')->asArray();
87
        foreach ($modules as $module => $data) {
88
            if (isset($data['codePool']) && $data['codePool'] == $codePool) {
89
                $this->enableModule($module, $output);
90
            }
91
        }
92
    }
93
94
    /**
95
     * Enable a single module
96
     *
97
     * @param string $module
98
     * @param OutputInterface $output
99
     *
100
     * @return int|void
101
     */
102
    protected function enableModule($module, OutputInterface $output)
103
    {
104
        $validDecFile = false;
105
        foreach ($this->getDeclaredModuleFiles() as $decFile) {
106
            $xml = new \Varien_Simplexml_Element(file_get_contents($decFile));
107
            if ($xml->modules->{$module}) {
108
                $validDecFile = $decFile;
109
                break;
110
            }
111
        }
112
113
        if (!$validDecFile) {
114
            $msg = sprintf('<error><comment>%s: </comment>Couldn\'t find declaration file</error>', $module);
115
        } elseif (!is_writable($validDecFile)) {
116
            $msg = sprintf('<error><comment>%s: </comment>Can\'t write to declaration file</error>', $module);
117
        } else {
118
            $setTo = $this->commandName == 'enable' ? 'true' : 'false';
119
            if ((string) $xml->modules->{$module}->active != $setTo) {
120
                $xml->modules->{$module}->active = $setTo;
0 ignored issues
show
Bug introduced by
The variable $xml 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...
121
                if (file_put_contents($validDecFile, $xml->asXML()) !== false) {
122
                    $msg = sprintf('<info><comment>%s: </comment>%sd</info>', $module, $this->commandName);
123
                } else {
124
                    $msg = sprintf(
125
                        '<error><comment>%s: </comment>Failed to update declaration file [%s]</error>', $module, $validDecFile
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 126 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
126
                    );
127
                }
128
            } else {
129
                $msg = sprintf('<info><comment>%s: already %sd</comment></info>', $module, $this->commandName);
130
            }
131
        }
132
133
        $output->writeln($msg);
134
    }
135
136
    /**
137
     * Load module files in the opposite order to core Magento, so that we find the last loaded declaration
138
     * of a module first.
139
     *
140
     * @return array
141
     */
142
    protected function getDeclaredModuleFiles()
143
    {
144
        $collectModuleFiles = array(
145
            'base'   => array(),
146
            'mage'   => array(),
147
            'custom' => array(),
148
        );
149
150
        foreach (glob($this->modulesDir . '*.xml')  as $v) {
151
            $name = explode(DIRECTORY_SEPARATOR, $v);
152
            $name = substr($name[count($name) - 1], 0, -4);
153
154
            if ($name == 'Mage_All') {
155
                $collectModuleFiles['base'][] = $v;
156
            } elseif (substr($name, 0, 5) == 'Mage_') {
157
                $collectModuleFiles['mage'][] = $v;
158
            } else {
159
                $collectModuleFiles['custom'][] = $v;
160
            }
161
        }
162
163
        return array_reverse(array_merge(
164
            $collectModuleFiles['base'],
165
            $collectModuleFiles['mage'],
166
            $collectModuleFiles['custom']
167
        ));
168
    }
169
}
170