Completed
Push — master ( 35512d...c04397 )
by Rougin
02:05
created

Application::run()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 16
ccs 0
cts 9
cp 0
rs 9.2
cc 4
eloc 8
nc 8
nop 1
crap 20
1
<?php
2
3
namespace Rougin\Blueprint;
4
5
use Psr\Container\ContainerInterface;
6
use Rougin\Slytherin\Container\Container;
7
use Symfony\Component\Console\Application as Console;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Rougin\Blueprint\Console.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
8
9
/**
10
 * Blueprint Application
11
 *
12
 * @package Blueprint
13
 * @author  Rougin Royce Gutib <[email protected]>
14
 */
15
class Application implements \ArrayAccess
16
{
17
    /**
18
     * @var \Psr\Container\ContainerInterface
19
     */
20
    protected $container;
21
22
    /**
23
     * @var string
24
     */
25
    protected $commands = '';
26
27
    /**
28
     * @var string
29
     */
30
    protected $name = 'Blueprint';
31
32
    /**
33
     * @var string
34
     */
35
    protected $namespace = 'Rougin\Blueprint\Commands';
36
37
    /**
38
     * @var string
39
     */
40
    protected $templates = '';
41
42
    /**
43
     * @var string
44
     */
45
    protected $version = '0.6.0';
46
47
    /**
48
     * Initializes the Blueprint instance.
49
     *
50
     * @param \Psr\Container\ContainerInterface|null $container
51
     */
52 3
    public function __construct(ContainerInterface $container = null)
53
    {
54 3
        $this->container = $container ?: new Container;
55
56 3
        $this->commands = __DIR__ . '/Commands';
57
58 3
        $this->templates = __DIR__ . '/Templates';
59
60 3
        $this->console = new Console($this->name, $this->version);
0 ignored issues
show
Bug introduced by
The property console does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
61 3
    }
62
63
    /**
64
     * Whether or not an offset exists.
65
     *
66
     * @param  mixed $offset
67
     * @return boolean
68
     */
69
    public function offsetExists($offset)
70
    {
71
        $allowed = array('commands', 'namespace', 'templates');
72
73
        if (in_array($offset, $allowed) === false) {
74
            $message = 'Key "' . $offset . '" does not exists!';
75
76
            throw new InvalidArgumentException($message);
77
        }
78
79
        return $this->$offset !== null && $this->$offset !== '';
80
    }
81
82
    /**
83
     * Returns the value at specified offset.
84
     *
85
     * @param  mixed $offset
86
     * @return mixed
87
     */
88
    public function offsetGet($offset)
89
    {
90
        $this->offsetExists();
0 ignored issues
show
Bug introduced by
The call to offsetExists() misses a required argument $offset.

This check looks for function calls that miss required arguments.

Loading history...
91
92
        return $this->$offset;
93
    }
94
95
    /**
96
     * Assigns a value to the specified offset.
97
     *
98
     * @param  mixed $offset
99
     * @param  mixed $value
100
     * @return void
101
     */
102
    public function offsetSet($offset, $value)
103
    {
104
        $this->offsetExists();
0 ignored issues
show
Bug introduced by
The call to offsetExists() misses a required argument $offset.

This check looks for function calls that miss required arguments.

Loading history...
105
106
        $this->$offset = $value;
107
    }
108
109
    /**
110
     * Unsets an offset.
111
     *
112
     * @param  mixed $offset
113
     * @return void
114
     */
115
    public function offsetUnset($offset)
116
    {
117
        $this->offsetExists();
0 ignored issues
show
Bug introduced by
The call to offsetExists() misses a required argument $offset.

This check looks for function calls that miss required arguments.

Loading history...
118
119
        $this->$offset = null;
120
    }
121
122
    /**
123
     * Runs the console instance.
124
     *
125
     * @param  boolean $console
126
     * @return \Symfony\Component\Console\Application
127
     */
128
    public function run($console = false)
129
    {
130
        $commands = $this->commands;
131
132
        is_string($commands) && $commands = $this->classes();
133
134
        foreach ((array) $commands as $command) {
135
            $item = $this->container->get($command);
136
137
            $this->console->add($instance = $item);
138
        }
139
140
        $console === false && $this->console->run();
141
142
        return $this->console;
143
    }
144
145
    /**
146
     * Returns an array of command classes.
147
     *
148
     * @return string[]
149
     */
150
    protected function classes()
151
    {
152
        list($items, $pattern) = array(array(), '/\\.[^.\\s]{3,4}$/');
153
154
        $files = glob($this->commands . '/*.php');
155
156
        $path = strlen($this->commands . DIRECTORY_SEPARATOR);
157
158
        foreach ((array) $files as $file) {
159
            $substring = substr($file, $path);
160
161
            $class = preg_replace($pattern, '', $substring);
162
163
            $items[] = $this->namespace . '\\' . $class;
164
        }
165
166
        return $items;
167
    }
168
169
    /**
170
     * Calls methods from the Console instance.
171
     *
172
     * @param  string $method
173
     * @param  mixed  $parameters
174
     * @return mixed
175
     */
176 3
    public function __call($method, $parameters)
177
    {
178 3
        $instance = array($this->console, $method);
179
180 3
        return call_user_func_array($instance, $parameters);
181
    }
182
}
183