ModuleUpgrader   F
last analyzed

Complexity

Total Complexity 79

Size/Duplication

Total Lines 484
Duplicated Lines 0 %

Importance

Changes 40
Bugs 8 Features 0
Metric Value
wmc 79
eloc 258
c 40
b 8
f 0
dl 0
loc 484
rs 2.08

15 Methods

Rating   Name   Duplication   Size   Complexity  
A getLastMethodRun() 0 3 1
A applyRecipe() 0 18 5
A loadCustomVariablesForTasks() 0 13 4
A loadNextStepInstructions() 0 17 5
A execMe() 0 26 3
C run() 0 80 12
A loadGlobalVariables() 0 16 2
A colourPrint() 0 3 1
C workoutPackageFolderName() 0 50 12
A printVarsForModule() 0 5 1
A testLocationFromRootDir() 0 3 1
F loadVarsForModule() 0 91 11
C workOutMethodsToRun() 0 48 12
A vendorModuleLocation() 0 3 1
B shouldWeRunIt() 0 26 8

How to fix   Complexity   

Complex Class

Complex classes like ModuleUpgrader often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ModuleUpgrader, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Sunnysideup\UpgradeToSilverstripe4;
4
5
use Sunnysideup\PHP2CommandLine\PHP2CommandLineSingleton;
6
use Sunnysideup\UpgradeToSilverstripe4\Traits\Creator;
7
8
class ModuleUpgrader extends ModuleUpgraderBaseWithVariables
9
{
10
    use Creator;
11
12
    ###############################
13
    # USEFUL COMMANDS
14
    ###############################
15
16
    /**
17
     * Executes given operations on the PHP2CommandLineSingleton instance
18
     * Documentation for this can be found in the PHP2CommandLineSingleton module
19
     *
20
     * @param  string  $newDir                  root dir for ommand
21
     * @param  string  $command                 actual command
22
     * @param  string  $comment                 comment
23
     * @param  boolean $alwaysRun               run even if you are just preparing a real run. Default FALSE
24
     *
25
     * @return array
26
     */
27
    public function execMe(
28
        string $newDir,
29
        string $command,
30
        string $comment,
31
        ?bool $alwaysRun = false,
32
        ?string $keyNotesLogFileLocation = '',
33
        ?bool $verbose = true
34
    ) {
35
        if ($keyNotesLogFileLocation) {
36
            $this->commandLineExec
37
                ->setMakeKeyNotes(true)
0 ignored issues
show
Bug introduced by
The method setMakeKeyNotes() does not exist on null. ( Ignorable by Annotation )

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

37
                ->/** @scrutinizer ignore-call */ 
38
                  setMakeKeyNotes(true)

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
38
                ->setKeyNotesFileLocation($keyNotesLogFileLocation);
39
        } else {
40
            $this->commandLineExec
41
                ->setMakeKeyNotes(false);
42
        }
43
        $this->commandLineExec->setErrorMessage('');
44
        if ($this->getBreakOnAllErrors()) {
45
            $this->commandLineExec->setErrorMessage('
46
------------------------------------------------------------------------
47
To continue, please use the following parameter: startFrom=' . $this->currentlyRunning . '
48
e.g. php runme.php startFrom=' . $this->currentlyRunning . '
49
------------------------------------------------------------------------
50
            ');
51
        }
52
        return $this->commandLineExec->execMe($newDir, $command, $comment, $alwaysRun, $verbose);
53
    }
54
55
    /**
56
     * Executes given operations on the PHP2CommandLineSingleton instance
57
     * Documentation for this can be found in the PHP2CommandLineSingleton module
58
     */
59
    public function colourPrint($mixedVar, string $colour = 'dark_gray', $newLineCount = 1)
60
    {
61
        return $this->commandLineExec->colourPrint($mixedVar, $colour, $newLineCount);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->commandLineExec->...$colour, $newLineCount) targeting Sunnysideup\PHP2CommandL...ingleton::colourPrint() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
62
    }
63
64
    ###############################
65
    # RUN
66
    ###############################
67
68
    /**
69
     * Starts the command line output and prints some opening information to the output
70
     * also initalises various environment variables
71
     */
72
    public function run()
73
    {
74
        $this->applyRecipe();
75
        $this->colourPrint(
76
            '===================== START ======================',
77
            'white',
78
            5
79
        );
80
        $this->loadNextStepInstructions();
81
        $this->loadGlobalVariables();
82
        $this->loadCustomVariablesForTasks();
83
        foreach ($this->arrayOfModules as $moduleDetails) {
84
            $hasRun = false;
85
            $nextStep = '';
86
            $this->loadVarsForModule($moduleDetails);
87
            $this->workOutMethodsToRun();
88
            $this->printVarsForModule($moduleDetails);
89
            foreach ($this->listOfTasks as $fauxClassName => $params) {
90
                //get class without number
91
                $properClass = current(explode('-', $fauxClassName));
92
                $nameSpacesArray = explode('\\', $properClass);
93
                $shortClassCode = end($nameSpacesArray);
94
                if (! class_exists($properClass)) {
95
                    $properClass = $this->defaultNamespaceForTasks . '\\' . $properClass;
96
                }
97
                if (class_exists($properClass)) {
98
                    $runItNow = $this->shouldWeRunIt((string) $fauxClassName);
99
                    $params['taskName'] = $shortClassCode;
100
                    $obj = $properClass::create($this, $params);
101
                    $taskName = $obj->getTaskName();
102
                    if ($taskName) {
103
                        $params['taskName'] = $taskName;
104
                    }
105
                    if ($hasRun && ! $nextStep) {
106
                        $nextStep = $params['taskName'];
107
                    }
108
                    if ($runItNow) {
109
                        $this->currentlyRunning = $fauxClassName;
110
                        $this->colourPrint('# --------------------', 'yellow', 3);
111
                        $this->colourPrint('# ' . $obj->getTitle() . ' (' . $params['taskName'] . ')', 'yellow');
112
                        $this->colourPrint('# --------------------', 'yellow');
113
                        $this->colourPrint('# ' . $obj->getDescriptionNice(), 'light_green');
114
                        $this->colourPrint('# --------------------', 'light_green');
115
                        $obj->run();
116
                        if ($this->runInteractively) {
117
                            $hasRun = true;
118
                            if ($this->outOfOrderTask === false) {
119
                                $this->getSessionManager()->setSessionValue('Completed', $fauxClassName);
120
                            }
121
                        }
122
                    } else {
123
                        if (! $this->runInteractively) {
124
                            $this->colourPrint('# --------------------', 'yellow', 3);
125
                            $this->colourPrint('# ' . $obj->getTitle() . ' (' . $params['taskName'] . ')', 'yellow');
126
                            $this->colourPrint('# --------------------', 'yellow');
127
                            $this->colourPrint('# skipped', 'yellow');
128
                            $this->colourPrint('# --------------------', 'yellow');
129
                        }
130
                    }
131
                    $obj = $properClass::deleteTask($params);
0 ignored issues
show
Unused Code introduced by
The assignment to $obj is dead and can be removed.
Loading history...
132
                } else {
133
                    user_error(
134
                        $properClass . ' could not be found as class.
135
                        You can add namespacing to include your own classes.',
136
                        E_USER_ERROR
137
                    );
138
                }
139
            }
140
            $this->colourPrint(
141
                '===================== END =======================',
142
                'white',
143
                5
144
            );
145
            $this->colourPrint(
146
                'Next: ' . $nextStep,
147
                'yellow',
148
                5
149
            );
150
        }
151
        $this->endPHP2CommandLine();
152
    }
153
154
    public function applyRecipe(?string $recipeName = null)
155
    {
156
        if ($recipeName === null) {
157
            $recipeName = $this->getRecipe();
0 ignored issues
show
Bug introduced by
The method getRecipe() does not exist on Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

157
            /** @scrutinizer ignore-call */ 
158
            $recipeName = $this->getRecipe();
Loading history...
158
        }
159
        if ($recipeName) {
160
            if (isset($this->availableRecipes[$recipeName])) {
161
                $recipeClass = $this->availableRecipes[$recipeName];
162
                $obj = new $recipeClass();
163
                $vars = $obj->getVariables();
164
                foreach ($vars as $variable => $value) {
165
                    $methodSet = 'set' . ucwords($variable);
166
                    $this->{$methodSet}($value);
167
                }
168
            } else {
169
                user_error(
170
                    'Recipe ' . $recipeName . ' not available.
171
                    Available Recipes are: ' . print_r($this->getAvailableRecipes(), 1)
0 ignored issues
show
Bug introduced by
Are you sure print_r($this->getAvailableRecipes(), 1) of type string|true can be used in concatenation? ( Ignorable by Annotation )

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

171
                    Available Recipes are: ' . /** @scrutinizer ignore-type */ print_r($this->getAvailableRecipes(), 1)
Loading history...
Bug introduced by
The method getAvailableRecipes() does not exist on Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

171
                    Available Recipes are: ' . print_r($this->/** @scrutinizer ignore-call */ getAvailableRecipes(), 1)
Loading history...
172
                );
173
            }
174
        }
175
    }
176
177
    public function getLastMethodRun(): string
178
    {
179
        return $this->getSessionManager()->getSessionValue('Completed');
180
    }
181
182
    protected function loadNextStepInstructions()
183
    {
184
        $this->restartSession = $this->getCommandLineOrArgumentAsBoolean('restart');
185
        $this->runLastOneAgain = $this->getCommandLineOrArgumentAsBoolean('again');
186
        if ($this->getCommandLineOrArgumentAsString('startFrom')) {
187
            $this->startFrom = $this->getCommandLineOrArgumentAsString('startFrom');
188
            if ($this->runInteractively) {
189
                $this->onlyRun = $this->getCommandLineOrArgumentAsString('startFrom');
190
            }
191
        }
192
        if ($this->getCommandLineOrArgumentAsString('endWith')) {
193
            $this->endWith = $this->getCommandLineOrArgumentAsString('endWith');
194
        }
195
        if ($this->getCommandLineOrArgumentAsString('task')) {
196
            $this->runInteractively = true;
197
            $this->onlyRun = $this->getCommandLineOrArgumentAsString('task');
198
            $this->outOfOrderTask = true;
199
        }
200
    }
201
202
    protected function loadGlobalVariables()
203
    {
204
        $attempt = $this->aboveWebRootDirLocation;
205
        $this->aboveWebRootDirLocation = $this->checkIfPathExistsAndCleanItUp(
206
            $this->aboveWebRootDirLocation
207
        );
208
        if (! $this->aboveWebRootDirLocation) {
209
            die('You need the following directory for this application to work: ' . $attempt);
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
210
        }
211
        $this->webRootDirLocation = $this->checkIfPathExistsAndCleanItUp(
212
            $this->aboveWebRootDirLocation . '/' . $this->webRootName,
213
            true
214
        );
215
        $this->themeDirLocation = $this->checkIfPathExistsAndCleanItUp(
216
            $this->webRootDirLocation . '/themes',
217
            true
218
        );
219
    }
220
221
    protected function loadCustomVariablesForTasks()
222
    {
223
        foreach ($this->customVariablesForTasks as $taskName => $variableAndValue) {
224
            foreach ($variableAndValue as $variableName => $variableValue) {
225
                $key = $this->positionForTask($taskName);
226
                if ($key !== false) {
227
                    $this->listOfTasks[$taskName][$variableName] = $variableValue;
228
                } else {
229
                    user_error(
230
                        'Could not find ' . $taskName . '.
231
                        Choose from ' . implode(', ', array_keys($this->listOfTasks))
232
                    );
233
                    die('----');
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
234
                }
235
            }
236
        }
237
    }
238
239
    /**
240
     * Loads in and sets all the meta data for a module from the inputed array
241
     * @param array $moduleDetails
242
     */
243
    protected function loadVarsForModule($moduleDetails)
244
    {
245
        //Is Module Upgrade
246
        //do this first as a lot of other functions rely on it ...
247
        $this->isModuleUpgrade = isset($moduleDetails['IsModuleUpgrade']) ? (bool) $moduleDetails['IsModuleUpgrade'] : true;
248
        $this->isOnPackagist = isset($moduleDetails['isOnPackagist']) ? (bool) $moduleDetails['isOnPackagist'] : false;
249
250
        //VendorName
251
        $this->vendorName = $moduleDetails['VendorName'];
252
253
        //VendorNamespace
254
        if (isset($moduleDetails['VendorNamespace'])) {
255
            $this->vendorNamespace = $moduleDetails['VendorNamespace'];
256
        } else {
257
            $this->vendorNamespace = $this->cleanCamelCase($this->vendorName);
258
        }
259
260
        //PackageName
261
        $this->packageName = $moduleDetails['PackageName'];
262
263
        //PackageNamespace
264
        if (isset($moduleDetails['PackageNamespace'])) {
265
            $this->packageNamespace = $moduleDetails['PackageNamespace'];
266
        } else {
267
            $this->packageNamespace = $this->cleanCamelCase($this->packageName);
268
        }
269
270
        if (isset($moduleDetails['GitLink'])) {
271
            $this->gitLink = $moduleDetails['GitLink'];
272
        } else {
273
            $this->gitLink = '[email protected]:' . $this->vendorName . '/silverstripe-' . $this->packageName . '.git';
274
            $this->gitLink = str_replace('silverstripe-silverstripe-', 'silverstripe-', $this->gitLink);
275
        }
276
        //see: https://stackoverflow.com/questions/5573334/remove-a-part-of-a-string-but-only-when-it-is-at-the-end-of-the-string
277
        $gitLinkWithoutExtension = preg_replace('/' . preg_quote('.git', '/') . '$/', '', $this->gitLink);
278
        $this->gitLinkAsHTTPS = str_replace(
279
            '[email protected]:',
280
            'https://github.com/',
281
            $gitLinkWithoutExtension
282
        );
283
        $this->gitLinkAsRawHTTPS = str_replace(
284
            '[email protected]:',
285
            'https://raw.githubusercontent.com/',
286
            $gitLinkWithoutExtension
287
        );
288
        $this->gitLinkAsHTTPS = str_replace(
289
            '[email protected]:',
290
            'https://bitbucket.org/',
291
            $gitLinkWithoutExtension
292
        );
293
        $this->gitLinkAsRawHTTPS = str_replace(
294
            '[email protected]:',
295
            'https://bitbucket.org/',
296
            $gitLinkWithoutExtension
297
        );
298
        if (stripos($this->gitLinkAsRawHTTPS, 'bitbucket') > 0) {
299
            $this->gitLinkAsRawHTTPS .= '/raw';
300
        }
301
302
        //Origin Composer FileLocation
303
        $this->originComposerFileLocation = $moduleDetails['OriginComposerFileLocation'] ?? '';
304
305
        $this->workoutPackageFolderName($moduleDetails);
306
307
        //ss4 location
308
        if (isset($moduleDetails['VendorAndPackageFolderNameForInstall'])) {
309
            $this->vendorAndPackageFolderNameForInstall = $moduleDetails['VendorAndPackageFolderNameForInstall'];
310
        } else {
311
            $this->vendorAndPackageFolderNameForInstall = strtolower($this->vendorName . '/' . $this->packageName);
312
        }
313
314
        //UpgradeAsFork
315
        $this->upgradeAsFork = empty($moduleDetails['UpgradeAsFork']) ? false : true;
316
317
        //NameOfBranchForBaseCode
318
        $this->nameOfBranchForBaseCode = $moduleDetails['NameOfBranchForBaseCode'] ?? $this->nameOfBranchForBaseCode;
319
320
        //LogFileLocation
321
        $this->logFileLocation = '';
322
        if ($this->logFolderDirLocation) {
323
            $this->logFileLocation =
324
                $this->logFolderDirLocation . '/' . $this->packageName .
325
                '-upgrade-log-' . date('Y-m-d') .
326
                '.txt';
327
            $this->commandLineExec->setLogFileLocation($this->logFileLocation);
328
        } else {
329
            $this->commandLineExec->setLogFileLocation('');
330
        }
331
332
        if ($this->restartSession) {
333
            $this->getSessionManager()->deleteSession();
334
        }
335
    }
336
337
    protected function vendorModuleLocation(): string
338
    {
339
        return $this->webRootDirLocation . '/vendor/' . $this->vendorName . '/' . $this->packageName;
340
    }
341
342
    protected function workoutPackageFolderName(array $moduleDetails): string
343
    {
344
        $this->packageFolderNameForInstall = trim($this->packageFolderNameForInstall);
345
        if ($this->packageFolderNameForInstall && $this->testExistenceFromRoot($this->packageFolderNameForInstall)) {
0 ignored issues
show
Bug introduced by
The method testExistenceFromRoot() does not exist on Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

345
        if ($this->packageFolderNameForInstall && $this->/** @scrutinizer ignore-call */ testExistenceFromRoot($this->packageFolderNameForInstall)) {
Loading history...
346
            //do nothing
347
        } else {
348
            $packageFolderNameForInstall = $this->getSessionManager()->getSessionValue(
349
                'PackageFolderNameForInstall'
350
            );
351
            if ($packageFolderNameForInstall) {
352
                $this->packageFolderNameForInstall = $packageFolderNameForInstall;
353
            } else {
354
                if (isset($moduleDetails['PackageFolderNameForInstall'])) {
355
                    $this->packageFolderNameForInstall = $moduleDetails['PackageFolderNameForInstall'];
356
                } else {
357
                    if (! $this->originComposerFileLocation) {
358
                        $this->originComposerFileLocation = $this->gitLinkAsRawHTTPS . '/' . $this->getNameOfBranchForBaseCode() . '/composer.json';
0 ignored issues
show
Bug introduced by
Are you sure $this->getNameOfBranchForBaseCode() of type Sunnysideup\UpgradeToSil...duleUpgrader|mixed|null can be used in concatenation? ( Ignorable by Annotation )

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

358
                        $this->originComposerFileLocation = $this->gitLinkAsRawHTTPS . '/' . /** @scrutinizer ignore-type */ $this->getNameOfBranchForBaseCode() . '/composer.json';
Loading history...
Bug introduced by
The method getNameOfBranchForBaseCode() does not exist on Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

358
                        $this->originComposerFileLocation = $this->gitLinkAsRawHTTPS . '/' . $this->/** @scrutinizer ignore-call */ getNameOfBranchForBaseCode() . '/composer.json';
Loading history...
359
                    }
360
                    if ($this->URLExists($this->originComposerFileLocation)) {
361
                        $json = file_get_contents($this->originComposerFileLocation);
362
                        $array = json_decode($json, true);
363
                        if (isset($array['extra']['installer-name'])) {
364
                            $this->packageFolderNameForInstall = $array['extra']['installer-name'];
365
                        }
366
                    }
367
                }
368
            }
369
        }
370
        if (! $this->testLocationFromRootDir($this->packageFolderNameForInstall)) {
371
            $this->packageFolderNameForInstall = $this->getPackageFolderNameBasic(false);
372
            if (! $this->testLocationFromRootDir($this->packageFolderNameForInstall)) {
373
                $this->packageFolderNameForInstall = $this->getPackageFolderNameBasic(true);
374
            }
375
        }
376
        if ($this->testLocationFromRootDir($this->packageFolderNameForInstall)) {
377
            $this->getSessionManager()->setSessionValue(
378
                'PackageFolderNameForInstall',
379
                $this->packageFolderNameForInstall
380
            );
381
        } else {
382
            // user_error('
383
            //     Could not find: '.$this->webRootDirLocation . '/' .$this->packageFolderNameForInstall.'
384
            //     Composer File Used: '.$this->originComposerFileLocation .',
385
            //     Session Value: '.$packageFolderNameForInstall
386
            // );
387
        }
388
        if (! $this->packageFolderNameForInstall) {
389
            $this->packageFolderNameForInstall = $this->getPackageName();
0 ignored issues
show
Bug introduced by
The method getPackageName() does not exist on Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

389
            /** @scrutinizer ignore-call */ 
390
            $this->packageFolderNameForInstall = $this->getPackageName();
Loading history...
Documentation Bug introduced by
It seems like $this->getPackageName() can also be of type Sunnysideup\UpgradeToSilverstripe4\ModuleUpgrader. However, the property $packageFolderNameForInstall is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
390
        }
391
        return $this->packageFolderNameForInstall;
392
    }
393
394
    protected function testLocationFromRootDir(string $dir): bool
395
    {
396
        return (bool) file_exists($this->webRootDirLocation . '/' . $dir);
397
    }
398
399
    protected function printVarsForModule(array $moduleDetails)
400
    {
401
        $obj = new ModuleUpgraderInfo();
402
403
        return $obj->printVarsForModule($this, $moduleDetails);
0 ignored issues
show
Bug introduced by
Are you sure the usage of $obj->printVarsForModule($this, $moduleDetails) targeting Sunnysideup\UpgradeToSil...o::printVarsForModule() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
404
    }
405
406
    /**
407
     * work out the current one to run!
408
     * @return string
409
     */
410
    protected function workOutMethodsToRun()
411
    {
412
        if ($this->runInteractively) {
413
            if ($this->startFrom || $this->endWith) {
414
                user_error('In interactive mode you can not set StartFrom / EndWith / OnlyRun.');
415
            }
416
            if ($this->onlyRun) {
417
            } else {
418
                $lastMethod = $this->getLastMethodRun();
419
                if ($lastMethod) {
420
                    $this->verbose = false;
421
                    $arrayKeys = array_keys($this->listOfTasks);
422
                    $found = false;
423
                    foreach ($arrayKeys as $index => $key) {
424
                        if ($key === $lastMethod) {
425
                            $found = true;
426
                            if ($this->runLastOneAgain) {
427
                                $this->onlyRun = $arrayKeys[$index] ?? 'could not find the task to run again';
428
                            } else {
429
                                if (isset($arrayKeys[$index + 1])) {
430
                                    if (isset($this->listOfTasks[$arrayKeys[$index + 1]])) {
431
                                        $this->onlyRun = $arrayKeys[$index + 1];
432
                                    } else {
433
                                        user_error('Can not find next task: ' . $arrayKeys[$index + 1]);
434
                                    }
435
                                } else {
436
                                    $this->getSessionManager()->deleteSession();
437
                                    die('
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
438
==========================================
439
Session has completed.
440
==========================================
441
                                    ');
442
                                }
443
                            }
444
                        }
445
                    }
446
                    if (! $found) {
447
                        user_error('Did not find next step.');
448
                    }
449
                } else {
450
                    $this->verbose = true;
451
                    reset($this->listOfTasks);
452
                    $this->onlyRun = key($this->listOfTasks);
453
                }
454
            }
455
        }
456
457
        return $this->onlyRun;
458
    }
459
460
    /**
461
     * start the method ...
462
     * - should we run it?
463
     *
464
     * @param  string $name whatever is listed in the listOfTasks
465
     */
466
    protected function shouldWeRunIt(string $name): bool
467
    {
468
        $runMe = true;
469
        if ($this->onlyRun) {
470
            return $name === $this->onlyRun ? true : false;
471
        }
472
        if ($this->lastMethodHasBeenRun) {
473
            $runMe = false;
474
        } else {
475
            if ($this->startFrom) {
476
                $runMe = false;
477
                if ($name === $this->startFrom) {
478
                    $this->startFrom = '';
479
                    $runMe = true;
480
                }
481
            }
482
            if ($this->endWith) {
483
                if ($name === $this->endWith) {
484
                    $this->lastMethodHasBeenRun = true;
485
                }
486
            }
487
        }
488
489
        //here we call the PHP2CommandLine
490
491
        return $runMe;
492
    }
493
}
494