Completed
Branch master (ef5230)
by Timo
02:24
created

ImplementCommand   A

Complexity

Total Complexity 11

Size/Duplication

Total Lines 131
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
wmc 11
lcom 1
cbo 7
dl 0
loc 131
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
C execute() 0 27 7
A confirmInterfaceGeneration() 0 9 1
A confirmTraitGeneration() 0 10 1
A retrieveResourceManager() 0 4 1
A retrieveCodeGenerator() 0 4 1
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\InlineConfigCommandInterface;
22
23
use Tidal\PhpSpec\BehaviorExtension\Behavior\Container\HasContainerTrait;
24
use Tidal\PhpSpec\BehaviorExtension\Behavior\Console\Command\{
25
    UsesInterfaceTrait,
26
    UsesBehaviorTrait
27
};
28
29
use PhpSpec\Locator\ResourceManager;
30
use PhpSpec\CodeGenerator\Generator\Generator;
31
32
/**
33
 * class Tidal\PhpSpec\Behavior\Command\ImplementCommand
34
 */
35
class ImplementCommand extends GenericInlineConfigCommand implements InlineConfigCommandInterface
36
{
37
    use
38
        UsesInterfaceTrait,
39
        UsesBehaviorTrait,
40
        HasContainerTrait;
41
42
    /**
43
     * CONFIG
44
     */
45
    public const NAME = 'behavior:implement';
46
    public const DESCRIPTION = 'Creates a Trait from a given Interface';
47
    public const HIDDEN = false;
48
    public const USAGES = [ '@todo' ];
49
    public const HELP = <<<EOF
50
The <info>%command.name%</info> command creates an trait from a given interface:
51
  <info>php %command.full_name% ClassName MethodName</info>
52
Will generate an example in the ClassNameSpec.
53
EOF;
54
55
    public const ARGUMENTS = [
56
        self::INTERFACE_INPUT => [
57
            self::MODE_KEY => InputArgument::REQUIRED,
58
            self::DESCRIPTION_KEY => 'Interface to create behavior for'
59
        ],
60
        self::TRAIT_INPUT => [
61
            self::MODE_KEY => InputArgument::OPTIONAL,
62
            self::DESCRIPTION_KEY => 'Custom trait class name'
63
        ]
64
    ];
65
66
    public const OPTIONS = [
67
        self::FORCE_KEY => [
68
            self::MODE_KEY => InputOption::VALUE_NONE,
69
            self::DESCRIPTION_KEY => 'Force creation of Trait without asking for confirmation'
70
        ]
71
    ];
72
73
    protected const INTERFACE_CONFIRMATION_QUESTION = 'Interface %s? does not exist. Do you want to generate it?';
74
    protected const TRAIT_CONFIRMATION_QUESTION = 'Do you want to generate a Trait for Interface %s?';
75
76
    protected const INTERFACE_INPUT = 'interface';
77
    protected const TRAIT_INPUT = 'trait';
78
79
    protected const MODE_KEY = 'mode';
80
    protected const DESCRIPTION_KEY = 'description';
81
    protected const FORCE_KEY = 'force';
82
83
    protected const RESOURCE_MANAGER_ID = 'locator.resource_manager';
84
    protected const CODE_GENERATOR_ID = 'code_generator';
85
86
    /**
87
     * @param \Symfony\Component\Console\Input\InputInterface $input
88
     * @param OutputInterface $output
89
     *
90
     * @return int|null
91
     */
92
    protected function execute(InputInterface $input, OutputInterface $output)
93
    {
94
        if (method_exists($this->getContainer(), 'configure')) {
95
            $this->getContainer()->configure();
96
        }
97
98
        $interfaceName = $input->getArgument(self::INTERFACE_INPUT);
99
100
        if (!$this->validateInterface($interfaceName) && $this->confirmInterfaceGeneration($interfaceName)) {
101
            $this->retrieveCodeGenerator()->generate(
102
                $this->retrieveResourceManager()->createResource($interfaceName),
103
                ['interface']
104
            );
105
        }
106
107
        $traitName = $input->getArgument(self::TRAIT_INPUT);
108
109
        if (!$this->validateTrait($traitName) && !$input->getOption(self::FORCE_KEY)) {
110
            return 0;
111
        }
112
113
        if (!$this->confirmTraitGeneration($interfaceName, $traitName)) {
114
            return 0;
115
        }
116
117
        return 0;
118
    }
119
120
    /**
121
     * @param string $interfaceName
122
     * @return bool
123
     */
124
    private function confirmInterfaceGeneration(string $interfaceName)
125
    {
126
        return $this->getWriter()->confirm(
127
            self::INTERFACE_CONFIRMATION_QUESTION,
128
            [
129
                $interfaceName
130
            ]
131
        );
132
    }
133
134
    /**
135
     * @param string $interfaceName
136
     * @param null|string $traitName
137
     * @return bool
138
     */
139
    private function confirmTraitGeneration(string $interfaceName, ? string $traitName)
140
    {
141
        return $this->getWriter()->confirm(
142
            self::TRAIT_CONFIRMATION_QUESTION,
143
            [
144
                $interfaceName,
145
                $traitName
146
            ]
147
        );
148
    }
149
150
    /**
151
     * @return object|ResourceManager
152
     */
153
    protected function retrieveResourceManager()
154
    {
155
        return $this->getContainer()->get(self::RESOURCE_MANAGER_ID);
156
    }
157
158
    /**
159
     * @return object|Generator
160
     */
161
    protected function retrieveCodeGenerator()
162
    {
163
        return $this->getContainer()->get(self::CODE_GENERATOR_ID);
164
    }
165
}
166
167