Completed
Push — develop ( 64ad43...c5a4cf )
by Neomerx
03:58
created

LimoncelloCommand.php$0 ➔ addGlobalMiddleware()   A

Complexity

Conditions 1

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
crap 2
1
<?php namespace Limoncello\Commands;
2
3
/**
4
 * Copyright 2015-2018 [email protected]
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use Composer\Command\BaseCommand;
20
use Exception;
21
use Limoncello\Commands\Traits\CommandSerializationTrait;
22
use Limoncello\Commands\Traits\CommandTrait;
23
use Limoncello\Commands\Wrappers\DataArgumentWrapper;
24
use Limoncello\Commands\Wrappers\DataOptionWrapper;
25
use Limoncello\Contracts\Container\ContainerInterface as LimoncelloContainerInterface;
26
use Limoncello\Contracts\Exceptions\ThrowableHandlerInterface;
27
use Symfony\Component\Console\Input\InputInterface;
28
use Symfony\Component\Console\Output\OutputInterface;
29
30
/**
31
 * @package Limoncello\Commands
32
 *
33
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
34
 */
35
class LimoncelloCommand extends BaseCommand
36
{
37
    use CommandTrait, CommandSerializationTrait, ExecuteCommandTrait;
38
39
    /**
40
     * @var string
41
     */
42
    private $description;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
43
44
    /**
45
     * @var string
46
     */
47
    private $help;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
48
49
    /**
50
     * @var array
51
     */
52
    private $arguments;
53
54
    /**
55
     * @var array
56
     */
57
    private $options;
58
59
    /**
60
     * @var callable|array
61
     */
62
    private $callable;
63
64
    /**
65
     * @param string $name
66
     * @param string $description
67
     * @param string $help
68
     * @param array  $arguments
69
     * @param array  $options
70
     * @param array  $callable
71
     */
72 4
    public function __construct(
73
        string $name,
74
        string $description,
75
        string $help,
76
        array $arguments,
77
        array $options,
78
        array $callable
79
    ) {
80 4
        $this->description = $description;
81 4
        $this->help        = $help;
82 4
        $this->arguments   = $arguments;
83 4
        $this->options     = $options;
84 4
        $this->callable    = $callable;
85
86
        // it is important to call the parent constructor after
87
        // data init as it calls `configure` method.
88 4
        parent::__construct($name);
89
    }
90
91
    /**
92
     * @inheritdoc
93
     */
94 4
    public function configure()
95
    {
96 4
        parent::configure();
97
98
        $this
99 4
            ->setDescription($this->description)
100 4
            ->setHelp($this->help);
101
102 4
        foreach ($this->arguments as $data) {
103 3
            $arg = new DataArgumentWrapper($data);
104 3
            $this->addArgument($arg->getName(), $arg->getMode(), $arg->getDescription(), $arg->getDefault());
105
        }
106
107 4
        foreach ($this->options as $data) {
108 3
            $opt = new DataOptionWrapper($data);
109 3
            $this->addOption(
110 3
                $opt->getName(),
111 3
                $opt->getShortcut(),
112 3
                $opt->getMode(),
113 3
                $opt->getDescription(),
114 3
                $opt->getDefault()
115
            );
116
        }
117
    }
118
119
    /** @noinspection PhpMissingParentCallCommonInspection
120
     * @inheritdoc
121
     *
122
     * @throws Exception
123
     *
124
     * @SuppressWarnings(PHPMD.ElseExpression)
125
     */
126 3
    public function execute(InputInterface $input, OutputInterface $output)
127
    {
128 3
        $container = null;
129
        try {
130
            // There is a tiny hack here. We need editable container and we know that at this point
131
            // container still can be edited so we cast it to `LimoncelloContainerInterface`.
132 3
            $container = $this->createContainer($this->getComposer());
0 ignored issues
show
Bug introduced by
It seems like $this->getComposer() can be null; however, createContainer() does not accept null, maybe add an additional type check?

Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code:

/** @return stdClass|null */
function mayReturnNull() { }

function doesNotAcceptNull(stdClass $x) { }

// With potential error.
function withoutCheck() {
    $x = mayReturnNull();
    doesNotAcceptNull($x); // Potential error here.
}

// Safe - Alternative 1
function withCheck1() {
    $x = mayReturnNull();
    if ( ! $x instanceof stdClass) {
        throw new \LogicException('$x must be defined.');
    }
    doesNotAcceptNull($x);
}

// Safe - Alternative 2
function withCheck2() {
    $x = mayReturnNull();
    if ($x instanceof stdClass) {
        doesNotAcceptNull($x);
    }
}
Loading history...
133 2
            assert($container instanceof LimoncelloContainerInterface);
134
135 2
            $this->executeCommand($this->callable, $this->wrapIo($input, $output), $container);
136 2
        } catch (Exception $exception) {
137 2
            if ($container !== null && $container->has(ThrowableHandlerInterface::class) === true) {
138
                /** @var ThrowableHandlerInterface $handler */
139 1
                $handler  = $container->get(ThrowableHandlerInterface::class);
140 1
                $response = $handler->createResponse($exception, $container);
141
142 1
                $output->writeln((string)$response->getBody());
143
            } else {
144 1
                $message = $exception->getMessage();
145 1
                $file    = $exception->getFile();
146 1
                $line    = $exception->getLine();
147 1
                $trace   = $exception->getTraceAsString();
148
149 1
                $output->writeln("$message at $file#$line" . PHP_EOL . $trace);
150
            }
151
152 2
            throw $exception;
153
        }
154
    }
155
}
156