Completed
Push — master ( d3a152...06e516 )
by Franco
01:17
created

CreateDataObjectCommand::isTraditionalSyntax()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace SilverStripe\Porter\Commands;
4
5
use SilverStripe\Porter\Helpers\ValidationHelper;
6
use Symfony\Component\Filesystem\Filesystem;
7
use Symfony\Component\Console\Command\Command;
8
use Symfony\Component\Console\Input\InputOption;
9
use Symfony\Component\Console\Input\InputArgument;
10
use Symfony\Component\Console\Input\InputInterface;
11
use Symfony\Component\Console\Output\OutputInterface;
12
use Symfony\Component\Yaml\Exception\RuntimeException;
13
14
/**
15
 * Class CreateDataObjectCommand
16
 */
17
class CreateDataObjectCommand extends Command
18
{
19
    const ARGUMENTS_NAME = 'name';
20
    const ARGUMENTS_NAMESPACE = 'namespace';
21
    const ARGUMENTS_PATH = 'path';
22
    const OPTIONS_HAS_ONE = 'withHasOne';
23
    const OPTIONS_HAS_MANY = 'withHasMany';
24
    const OPTIONS_MANY_MANY = 'withManyMany';
25
    const OPTIONS_TRADITIONAL_ARRAY = 'withTraditionalArray';
26
27
    /**
28
     * @var string
29
     */
30
    private $name;
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...
31
32
    /**
33
     * @var string
34
     */
35
    private $namespace;
36
37
    /**
38
     * @var string
39
     */
40
    private $modulePath;
41
42
    /**
43
     * @var Filesystem
44
     */
45
    private $fileSystem;
46
47
    /**
48
     * @var string The target frameowkr version
49
     */
50
    private $frameworkVersion = 'ss4';
51
52
    /**
53
     * @var string
54
     */
55
    private $separator = DIRECTORY_SEPARATOR;
56
57
    /**
58
     * Whether or not to use traditional array syntax
59
     * @var bool
60
     */
61
    private $useTraditionalArraySyntax = false;
62
63
    /**
64
     * Configures the command
65
     */
66 View Code Duplication
    protected function configure()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
67
    {
68
        $this->setName('create-dataobject')
69
            ->setDescription('Sets up a new SilverStripe dataobject skeleton at the'
70
                . ' given path.')
71
            ->addArgument(self::ARGUMENTS_NAME, InputArgument::REQUIRED)
72
            ->addArgument(self::ARGUMENTS_PATH, InputArgument::REQUIRED)
73
            ->addArgument(self::ARGUMENTS_NAMESPACE, InputArgument::REQUIRED)
74
            ->addOption(self::OPTIONS_HAS_ONE, null, InputOption::VALUE_NONE)
75
            ->addOption(self::OPTIONS_HAS_MANY, null, InputOption::VALUE_NONE)
76
            ->addOption(self::OPTIONS_MANY_MANY, null, InputOption::VALUE_NONE)
77
            ->addOption(self::OPTIONS_TRADITIONAL_ARRAY, null, InputOption::VALUE_NONE);
78
    }
79
80
    /**
81
     * Executes this command
82
     * @param InputInterface $input
83
     * @param OutputInterface $output
84
     * @return int|null|void
85
     */
86
    protected function execute(InputInterface $input, OutputInterface $output)
87
    {
88
        $this->setArguments($input);
89
        $output->writeln(
90
            "Creating SilverStripe DataObject named {$this->name} "
91
            . "at {$this->modulePath}"
92
        );
93
        $this->preCopyOptions($input);
94
        $this->copySkeleton();
95
        $output->writeln(' - Skeleton created');
96
        $this->postCopyOptions($input);
97
        $output->writeln(' - Options applied');
98
        $output->writeln(' - Done');
99
    }
100
101
    /**
102
     * Sets the argument values to their respective properties
103
     * @param InputInterface $input
104
     * @throws RuntimeException
105
     */
106 View Code Duplication
    protected function setArguments(InputInterface $input)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
107
    {
108
        $this->name = $input->getArgument(self::ARGUMENTS_NAME);
109
        $this->namespace = $input->getArgument(self::ARGUMENTS_NAMESPACE);
110
        $this->modulePath = $input->getArgument(self::ARGUMENTS_PATH);
111
112
        ValidationHelper::validateNamespace($this->namespace);
113
        ValidationHelper::validateModuleName($this->moduleName);
0 ignored issues
show
Bug introduced by
The property moduleName 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...
114
    }
115
116
    /**
117
     * @param InputInterface $input
118
     */
119
    protected function preCopyOptions(InputInterface $input)
120
    {
121
        if ($input->getOption(self::OPTIONS_TRADITIONAL_ARRAY)) {
122
            $this->useTraditionalArraySyntax = true;
123
        }
124
    }
125
126
    /**
127
     * Checks for and actions all actions
128
     * @param InputInterface $input
129
     * @param OutputInterface $output
0 ignored issues
show
Bug introduced by
There is no parameter named $output. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
130
     */
131
    protected function postCopyOptions(InputInterface $input)
132
    {
133
        $source = $this->getSourcePath('options');
134
        $target = $this->getTargetPath();
135
        $uri = function ($folder, $endPoint) {
136
            return "{$folder}{$this->separator}{$endPoint}";
137
        };
138
        if ($input->getOption(self::OPTIONS_HAS_ONE)) {
139
            $this->moduleType = 'silverstripe-module';
0 ignored issues
show
Bug introduced by
The property moduleType 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...
140
        }
141
142
        if ($ss3 = $input->getOption(self::OPTIONS_SS3)) {
0 ignored issues
show
Unused Code introduced by
$ss3 is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
143
            $this->frameworkVersion = 'ss3';
144
        }
145
146 View Code Duplication
        if ($withTravis = $input->getOption(self::OPTIONS_HAS_MANY)) {
0 ignored issues
show
Unused Code introduced by
$withTravis is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
147
            $file = '.travis.yml';
148
            $this->getFilesystem()->copy(
149
                $uri($source, $file),
150
                $uri($target, $file)
151
            );
152
        }
153
154 View Code Duplication
        if ($withCircleCI = $input->getOption(self::OPTIONS_MANY_MANY)) {
0 ignored issues
show
Unused Code introduced by
$withCircleCI is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
155
            $folder = '.circleci';
156
            $this->getFilesystem()->mirror(
157
                $uri($source, $folder),
158
                $uri($target, $folder)
159
            );
160
        }
161
    }
162
163
    /**
164
     * Copies the skeleton to the root directory
165
     */
166
    protected function copySkeleton()
167
    {
168
        $this->getFilesystem()->mirror(
169
            $this->getSourcePath(),
170
            $this->getTargetPath()
171
        );
172
    }
173
174
    /**
175
     * Copies the configured values to the composer.json file
176
     */
177
    protected function setupComposerJson()
178
    {
179
        $path = $this->getTargetPath() . DIRECTORY_SEPARATOR . 'composer.json';
180
        $contents = file_get_contents($path);
181
        $search = [
182
            '$moduleName',
183
            '$moduleType',
184
            '$namespace'
185
        ];
186
        $replace = [
187
            $this->name,
188
            $this->moduleType,
189
            $this->namespace
190
        ];
191
192
        $contents = str_ireplace($search, $replace, $contents);
193
        $this->getFilesystem()->dumpFile($path, $contents);
194
    }
195
196
    /**
197
     * Gets or sets the file system property
198
     * @return Filesystem
199
     */
200
    protected function getFilesystem()
201
    {
202
        if (!$this->fileSystem) {
203
            $this->fileSystem = new Filesystem();
204
        }
205
206
        return $this->fileSystem;
207
    }
208
209
    /**
210
     * Returns the path to the given sub-dir. Defaults to assets skeleton
211
     * @param string $subDir
212
     * @return string
213
     */
214
    protected function getSourcePath($subDir = 'assets')
215
    {
216
        $porterDir = __DIR__;
217
        return "{$porterDir}{$this->separator}{$subDir}{$this->separator}{$this->frameworkVersion}-dataobject";
218
    }
219
220
    /**
221
     * Gets destination path for the module skeleton
222
     * @return string
223
     */
224
    protected function getTargetPath()
225
    {
226
        $folderName = substr($this->name, stripos($this->name, DIRECTORY_SEPARATOR) + 1);
227
        return $this->modulePath . $this->separator . $folderName;
228
    }
229
230
    /**
231
     * @return bool
232
     */
233
    public function isTraditionalSyntax()
234
    {
235
        return $this->useTraditionalArraySyntax;
236
    }
237
238
    /**
239
     * @param bool $traditionalSyntax
240
     * @return CreateDataObjectCommand
241
     */
242
    public function setTraditionalSyntax($traditionalSyntax)
243
    {
244
        $this->useTraditionalArraySyntax = $traditionalSyntax;
245
        return $this;
246
    }
247
}
248