CommandFactory   A
last analyzed

Complexity

Total Complexity 12

Size/Duplication

Total Lines 94
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 12
c 1
b 0
f 0
lcom 1
cbo 1
dl 0
loc 94
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 5 1
A loadCommands() 0 10 3
A filterSlickModules() 0 11 3
A getCommandClasses() 0 8 2
A getClasses() 0 15 3
1
<?php
2
3
/**
4
 * This file is part of slick/console package
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Slick\Console;
11
12
use Symfony\Component\Console\Application;
13
use Symfony\Component\Console\Command\Command;
14
15
/**
16
 * Console Command Factory
17
 * 
18
 * @package Slick\Console
19
 * @author  Filipe Silva <[email protected]>
20
 */
21
class CommandFactory
22
{
23
    /**
24
     * @var Application
25
     */
26
    protected $application;
27
28
    /**
29
     * @var array
30
     */
31
    protected $psr4Data;
32
33
    /**
34
     * CommandFactory constructor
35
     * 
36
     * @param Application $application
37
     * @param array       $psr4Data
38
     */
39
    public function __construct(Application $application, array $psr4Data = [])
40
    {
41
        $this->application = $application;
42
        $this->psr4Data = $psr4Data;
43
    }
44
45
    /**
46
     * Load all slick commands
47
     */
48
    public function loadCommands()
49
    {
50
        $slickModules = $this->filterSlickModules();
51
        $classes = $this->getCommandClasses($slickModules);
52
        foreach ($classes as $class) {
53
            if (is_subclass_of($class, Command::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Symfony\Component\Console\Command\Command::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
54
                $this->application->add(new $class());
55
            }
56
        }
57
    }
58
59
    /**
60
     * Retrieves all Slick modules installed from composer
61
     * 
62
     * @return array
63
     */
64
    protected function filterSlickModules()
65
    {
66
        $iterator = new \ArrayIterator($this->psr4Data);
67
        $modules = [];
68
        foreach ($iterator as $nameSpace => $path) {
69
            if (preg_match('/^Slick\\\[a-z_]*\\\$/i', $nameSpace)) {
70
                $modules[$nameSpace] = reset($path);
71
            }
72
        }
73
        return $modules;
74
    }
75
76
    /**
77
     * Get user defined classes in "Console\Command" name space of each module
78
     * 
79
     * @param array $modules
80
     * @return array
81
     */
82
    protected function getCommandClasses(array $modules)
83
    {
84
        $classes = [];
85
        foreach ($modules as $nameSpace => $path) {
86
            $classes = array_merge($classes, $this->getClasses($nameSpace, $path));
87
        }
88
        return $classes;
89
    }
90
91
    /**
92
     * Get classes that implements the Command interface
93
     * 
94
     * @param string $namespace
95
     * @param string $path
96
     * 
97
     * @return array
98
     */
99
    protected function getClasses($namespace, $path)
100
    {
101
        $classes = [];
102
        $path = "$path/Console/Command";
103
        if (!is_dir($path)) {
104
            return $classes;
105
        }
106
107
        $dir = new \DirectoryIterator($path);
108
        $classFiles = new \RegexIterator($dir, '/[a-z_]*\.php/i');
109
        foreach ($classFiles as $file) {
110
            $classes[] = str_replace('.php', '', "{$namespace}Console\\Command\\{$file}");
111
        }
112
        return $classes;
113
    }
114
}