SilverstripeApplication   A
last analyzed

Complexity

Total Complexity 14

Size/Duplication

Total Lines 125
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Importance

Changes 7
Bugs 2 Features 1
Metric Value
wmc 14
c 7
b 2
f 1
lcom 1
cbo 8
dl 0
loc 125
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 16 1
A run() 0 4 1
A call() 0 14 1
A output() 0 4 2
A getDefaultInputDefinition() 0 8 1
A getEnvironmentOption() 0 6 1
A loadCommands() 0 10 2
B addCommandOrSilentlyFail() 0 9 5
1
<?php
2
3
use Symfony\Component\Console\Application as SymfonyApplication;
4
use Symfony\Component\Console\Input\ArrayInput;
5
use Symfony\Component\Console\Input\InputInterface;
6
use Symfony\Component\Console\Input\InputOption;
7
use Symfony\Component\Console\Output\BufferedOutput;
8
use Symfony\Component\Console\Output\OutputInterface;
9
10
/**
11
 * Class Application.
12
 *
13
 * Shameless copy/paste from Taylor Otwell's Laravel
14
 */
15
class SilverstripeApplication extends SymfonyApplication
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
16
{
17
    /**
18
     * The output from the previous command.
19
     *
20
     * @var \Symfony\Component\Console\Output\BufferedOutput
21
     */
22
    protected $lastOutput;
23
24
    public function __construct()
25
    {
26
        $name = 'Silverstripe Console';
27
28
        $version = '1';
29
30
        parent::__construct($name, $version);
31
32
        $this->loadCommands();
33
34
        $this->add($default = new DefaultCommand());
35
        $this->setDefaultCommand($default->getName());
36
37
        $this->setAutoExit(false);
38
        $this->setCatchExceptions(true);
39
    }
40
41
    public function run(InputInterface $input = null, OutputInterface $output = null)
42
    {
43
        return parent::run($input, $output);
44
    }
45
46
    /**
47
     * Run an Silverstripe console command by name.
48
     *
49
     * @param string $command
50
     * @param array  $parameters
51
     *
52
     * @return int
0 ignored issues
show
Documentation introduced by
Should the return type not be null|integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
53
     */
54
    public function call($command, array $parameters = [])
55
    {
56
        $parameters = array_merge((array) $command, $parameters);
57
58
        $this->lastOutput = new BufferedOutput();
59
60
        $this->setCatchExceptions(false);
61
62
        $result = $this->run(new ArrayInput($parameters), $this->lastOutput);
63
64
        $this->setCatchExceptions(true);
65
66
        return $result;
67
    }
68
69
    /**
70
     * Get the output for the last run command.
71
     *
72
     * @return string
73
     */
74
    public function output()
75
    {
76
        return $this->lastOutput ? $this->lastOutput->fetch() : '';
77
    }
78
79
    /**
80
     * Get the default input definitions for the applications.
81
     *
82
     * This is used to add the --env option to every available command.
83
     *
84
     * @return \Symfony\Component\Console\Input\InputDefinition
85
     */
86
    protected function getDefaultInputDefinition()
87
    {
88
        $definition = parent::getDefaultInputDefinition();
89
90
        $definition->addOption($this->getEnvironmentOption());
91
92
        return $definition;
93
    }
94
95
    /**
96
     * Get the global environment option for the definition.
97
     *
98
     * @return \Symfony\Component\Console\Input\InputOption
99
     */
100
    protected function getEnvironmentOption()
101
    {
102
        $message = 'The environment the command should run under.';
103
104
        return new InputOption('--env', null, InputOption::VALUE_OPTIONAL, $message);
105
    }
106
107
    /**
108
     * Load all available commands into the console application.
109
     */
110
    protected function loadCommands()
111
    {
112
        // somehow ClassInfo::subclassesFor('SilverstripeCommand'); does not work
113
        $classes = SS_ClassLoader::instance()->getManifest()->getClasses();
114
115
        /* @var SilverstripeCommand $command */
116
        foreach ($classes as $class => $path) {
117
            $this->addCommandOrSilentlyFail($class, $path);
118
        }
119
    }
120
121
    /**
122
     * When developing and renaming or removing a Command, the manifest is not always updated.
123
     *
124
     * We don't want file_not_found or class_does_not_exists error for commands,
125
     * because that prevente running commands like cache:clear etc.
126
     *
127
     * @param string $class
128
     * @param string $path
129
     */
130
    protected function addCommandOrSilentlyFail($class, $path)
131
    {
132
        if (is_file($path) && class_exists($class)) {
133
            $reflection = new ReflectionClass($class);
134
            if (!$reflection->isAbstract() && $reflection->isSubclassOf('SilverstripeCommand')) {
135
                $this->add(new $class());
136
            }
137
        }
138
    }
139
}
140