RepositoryMakeCommand::getOptions()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 3
c 1
b 0
f 1
nc 1
nop 0
dl 0
loc 5
rs 10
1
<?php
2
3
namespace Zebrainsteam\LaravelRepos\Console;
4
5
use Illuminate\Support\Facades\Artisan;
6
use Illuminate\Support\Str;
7
use Symfony\Component\Console\Input\InputOption;
8
9
class RepositoryMakeCommand extends GeneratorCommand
10
{
11
    /**
12
     * The console command name.
13
     *
14
     * @var string
15
     */
16
    protected $name = 'make:repository';
17
18
    /**
19
     * The console command name.
20
     *
21
     * @var string
22
     */
23
    protected $signature = 'make:repository {name} {--w|with-interface} {interface?} {--i|from-interface}';
24
25
    /**
26
     * @var string
27
     */
28
    protected $stub;
29
30
    /**
31
     * @var string
32
     */
33
    protected $defaultNamespacePrefix = 'Repositories';
34
35
    /**
36
     * @var string
37
     */
38
    protected $interfaceClassName = null;
39
40
    /**
41
     * The console command description.
42
     *
43
     * @var string
44
     */
45
    protected $description = 'Create a new repository';
46
47
    /**
48
     * The type of class being generated.
49
     *
50
     * @var string
51
     */
52
    protected $type = 'Repository';
53
54
    /**
55
     * The Composer instance.
56
     *
57
     * @var \Illuminate\Support\Composer
58
     */
59
    protected $composer;
60
61
    /**
62
     * Execute the console command.
63
     *
64
     * @return bool|null
65
     *
66
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
67
     */
68
    public function handle()
69
    {
70
        $name = $this->getNameInput();
71
        $interfaceName = $this->argument('interface');
72
        $withInterface = $this->option('with-interface');
73
        $fromInterface = $this->option('from-interface');
74
75
        if (!empty($withInterface)) {
76
            // create repository from abstract class by implementing interface
77
            $this->stub = '/stubs/repository-from-abstract-with-interface.stub';
78
            $this->createInterface($name, $interfaceName);
0 ignored issues
show
Bug introduced by
It seems like $interfaceName can also be of type string[]; however, parameter $interfaceName of Zebrainsteam\LaravelRepo...mand::createInterface() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

78
            $this->createInterface($name, /** @scrutinizer ignore-type */ $interfaceName);
Loading history...
79
        } elseif (!empty($fromInterface)) {
80
            // create repository by implementing interface
81
            $this->stub = '/stubs/repository-from-interface.stub';
82
            $this->createInterface($name, $interfaceName);
83
        } else {
84
            // create repository from abstract class
85
            $this->stub = '/stubs/repository-from-abstract.stub';
86
        }
87
88
        parent::handle();
89
    }
90
91
    /**
92
     * Get the stub file for the generator.
93
     *
94
     * @return string
95
     */
96
    protected function getStub()
97
    {
98
        return __DIR__.$this->stub;
99
    }
100
101
    /**
102
     * Get the console command options.
103
     *
104
     * @return array
105
     */
106
    protected function getOptions()
107
    {
108
        return [
109
            ['from-interface', 'i', InputOption::VALUE_NONE, 'Generate a repository via interface inheritance'],
110
            ['with-interface', 'w', InputOption::VALUE_NONE, 'Generate an interface and inherited repository'],
111
        ];
112
    }
113
114
    /**
115
     * Parse the interface class name and format according to the root namespace.
116
     *
117
     * @param $name
118
     * @return string
119
     */
120
    protected function qualifyInterfaceClass($name)
121
    {
122
        $interfaceName = $name;
123
        $name = ltrim($name, '\\/');
124
125
        $rootNamespace = $this->rootNamespace();
126
127
        if (Str::startsWith($name, $rootNamespace)) {
128
            return $name;
129
        }
130
131
        $name = str_replace('/', '\\', $name);
132
133
        return $this->qualifyClass(
134
            $this->getInterfaceNamespace(trim($rootNamespace, '\\'),  $interfaceName).'\\'.$name
135
        );
136
    }
137
138
    /**
139
     * Get namespace for interface class.
140
     *
141
     * @param $rootNamespace
142
     * @param $interfaceName
143
     * @return string
144
     */
145
    protected function getInterfaceNamespace($rootNamespace, $interfaceName)
146
    {
147
        $interfaceNamespace = $rootNamespace;
148
        if ($interfaceName[0] != '/') {
149
            $interfaceNamespace .= '\Contracts\Repository';
150
        }
151
152
        return $interfaceNamespace;
153
    }
154
155
    /**
156
     * Create interface for new repository
157
     *
158
     * @param string $repositoryName
159
     * @param string|null $interfaceName
160
     * @return int
161
     */
162
    protected function createInterface(string $repositoryName, $interfaceName)
163
    {
164
        if (empty($interfaceName)) {
165
            $interfaceName = $repositoryName . 'Contract';
166
        }
167
        $this->interfaceClassName = $this->qualifyInterfaceClass($interfaceName);
168
        return Artisan::call('make:repository-interface', [
169
            'name' => $interfaceName
170
        ]);
171
    }
172
173
    /**
174
     * Build the class with the given name.
175
     *
176
     * @param string $name
177
     * @return string
178
     * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException
179
     */
180
    protected function buildClass($name)
181
    {
182
        if (!empty($this->interfaceClassName)) {
183
            $replace = $this->buildInterfaceReplacements();
184
185
            return str_replace(
186
                array_keys($replace), array_values($replace), parent::buildClass($name)
187
            );
188
        } else {
189
            return parent::buildClass($name);
190
        }
191
    }
192
193
    /**
194
     * Build the replacements for interface.
195
     *
196
     * @return null[]|string[]
197
     */
198
    protected function buildInterfaceReplacements()
199
    {
200
        return [
201
            '{{ interface }}' => $this->interfaceClassName,
202
            '{{interface}}' => $this->interfaceClassName,
203
        ];
204
    }
205
}
206