ImplementCommand::confirmInterfaceGeneration()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 0
1
<?php
2
3
/**
4
 * This file is part of the phpspec-behavior package.
5
 * (c) 2017 Timo Michna <timomichna/yahoo.de>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Tidal\PhpSpec\BehaviorExtension\Console\Command;
12
13
use Symfony\Component\Console\Output\OutputInterface;
14
use Symfony\Component\Console\Input\{
15
    InputArgument,
16
    InputOption,
17
    InputInterface
18
};
19
20
use Tidal\PhpSpec\ConsoleExtension\Command\GenericInlineConfigCommand;
21
use Tidal\PhpSpec\ConsoleExtension\Contract\Command\ConfiguratorInterface;
22
use Tidal\PhpSpec\ConsoleExtension\Contract\Command\InlineConfigCommandInterface;
23
use Tidal\PhpSpec\ConsoleExtension\Contract\Command\ConfigInterface as Config;
24
25
use Tidal\PhpSpec\BehaviorExtension\Behavior\Console\Command\{
26
    UsesInterfaceTrait,
27
    UsesBehaviorTrait,
28
    CommandTrait
29
};
30
31
use PhpSpec\Locator\ResourceManager;
32
use PhpSpec\CodeGenerator\GeneratorManager;
33
use Tidal\PhpSpec\ConsoleExtension\Contract\WriterInterface;
34
35
/**
36
 * class Tidal\PhpSpec\Behavior\Command\ImplementCommand
37
 */
38
class ImplementCommand extends GenericInlineConfigCommand implements InlineConfigCommandInterface
39
{
40
    use
41
        UsesInterfaceTrait,
42
        UsesBehaviorTrait,
43
        CommandTrait;
44
45
    /**
46
     * CONFIG
47
     */
48
    public const NAME = 'behavior:implement';
49
    public const DESCRIPTION = 'Creates a Trait from a given Interface';
50
    public const HIDDEN = false;
51
    public const USAGES = [ '@todo' ];
52
    public const HELP = <<<EOF
53
The <info>%command.name%</info> command creates an trait from a given interface:
54
  <info>php %command.full_name% ClassName MethodName</info>
55
Will generate an example in the ClassNameSpec.
56
EOF;
57
58
    public const ARGUMENTS = [
59
        self::INTERFACE_INPUT => [
60
            Config::MODE_KEY => InputArgument::REQUIRED,
61
            Config::DESCRIPTION_KEY => 'Interface to create behavior for'
62
        ],
63
        self::TRAIT_INPUT => [
64
            Config::MODE_KEY => InputArgument::OPTIONAL,
65
            Config::DESCRIPTION_KEY => 'Custom trait class name'
66
        ]
67
    ];
68
69
    public const OPTIONS = [
70
        self::FORCE_KEY => [
71
            Config::MODE_KEY => InputOption::VALUE_NONE,
72
            Config::DESCRIPTION_KEY => 'Force creation of Trait without asking for confirmation',
73
            Config::SHORTCUT_KEY => 'f'
74
        ],
75
        self::QUITE_KEY => [
76
            Config::MODE_KEY => InputOption::VALUE_NONE,
77
            Config::DESCRIPTION_KEY => 'Force creation of Trait without asking for confirmation'
78
        ]
79
    ];
80
81
    protected const INTERFACE_CONFIRMATION_QUESTION = 'Interface %s? does not exist. Do you want to generate it?';
82
    protected const TRAIT_CONFIRMATION_QUESTION = 'Do you want to generate a Trait for Interface %s?';
83
84
    protected const INTERFACE_INPUT = 'interface';
85
    protected const TRAIT_INPUT = 'trait';
86
87
    protected const FORCE_KEY = 'force';
88
    protected const QUITE_KEY = 'quite';
89
    protected const INTERFACE_KEY = 'interface';
90
91
    protected const RESOURCE_MANAGER_ID = 'locator.resource_manager';
92
    protected const GENERATOR_MANAGER_ID = 'code_generator';
93
94
    /**
95
     * @var string
96
     */
97
    protected $interfaceName;
98
99
    public function __construct(WriterInterface $writer, ConfiguratorInterface $configurator, $config = [])
100
    {
101
        $config['name'] = self::NAME;
102
        parent::__construct($writer, $configurator, $config);
103
    }
104
105
    /**
106
     * @param InputInterface $input
107
     * @param OutputInterface $output
108
     *
109
     * @return int|null
110
     */
111
    protected function execute(InputInterface $input, OutputInterface $output)
112
    {
113
        $this->setPuts($input, $output);
114
115
        $this->configureContainer();
116
117
        $this->ensureInterfaceExists();
118
119
        return 0;
120
    }
121
122
    /**
123
     * @return bool
124
     */
125
    private function confirmInterfaceGeneration()
126
    {
127
        if ((bool)$this->getInput()->getOption(self::FORCE_KEY)) {
128
            return true;
129
        }
130
131
        return $this->getWriter()->confirm(
132
            self::INTERFACE_CONFIRMATION_QUESTION,
133
            [
134
                $this->getInput()->getArgument(self::INTERFACE_INPUT)
135
            ]
136
        );
137
    }
138
139
    /**
140
     * @return object|ResourceManager
141
     */
142
    protected function retrieveResourceManager()
143
    {
144
        return $this->getContainer()->get(self::RESOURCE_MANAGER_ID);
145
    }
146
147
    /**
148
     * @return object|GeneratorManager
149
     */
150
    protected function retrieveGeneratorManager()
151
    {
152
        return $this->getContainer()->get(self::GENERATOR_MANAGER_ID);
153
    }
154
155
    protected function ensureInterfaceExists()
156
    {
157
        if (!$this->validateInterfaceInput() && $this->confirmInterfaceGeneration()) {
158
            $this->createInterface();
159
        }
160
    }
161
162
    protected function createInterface()
163
    {
164
        $this->retrieveGeneratorManager()->generate(
165
            $this->retrieveResourceManager()->createResource(
166
                $this->getInterfaceName()
167
            ),
168
            self::INTERFACE_KEY
169
        );
170
    }
171
172
    protected function getInterfaceInput(InputInterface $input)
173
    {
174
        return $input->getArgument(self::INTERFACE_INPUT);
175
    }
176
177
    protected function validateInterfaceInput()
178
    {
179
        return $this->validateInterface(
180
            $this->getInterfaceInput(
181
                $this->getInput()
182
            )
183
        );
184
    }
185
186
    /**
187
     * @param string $interfaceName
188
     */
189
    protected function setInterfaceName(string $interfaceName)
190
    {
191
        $this->interfaceName = $interfaceName;
192
    }
193
194
    /**
195
     * @return string
196
     */
197
    protected function getInterfaceName(): string
198
    {
199
        return isset($this->interfaceName)
200
            ? $this->interfaceName
201
            : $this->interfaceName = $this->getInput()
202
                ->getArgument(self::INTERFACE_INPUT);
203
    }
204
}
205
206