GenerateTask::run()   B
last analyzed

Complexity

Conditions 9
Paths 32

Size

Total Lines 66

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 66
rs 7.1862
c 0
b 0
f 0
cc 9
nc 32
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Robo\Task\Development;
4
5
use Robo\Task\BaseTask;
6
use Robo\Result;
7
8
/**
9
 * Generate a Robo Task that is a wrapper around an existing class.
10
 *
11
 * ``` php
12
 * <?php
13
 * $this->taskGenerateTask('Symfony\Component\Filesystem\Filesystem', 'FilesystemStack')
14
 *   ->run();
15
 * ```
16
 */
17
class GenerateTask extends BaseTask
18
{
19
    /**
20
     * @var string
21
     */
22
    protected $className;
23
24
    /**
25
     * @var string
26
     */
27
    protected $wrapperClassName;
28
29
    /**
30
     * @param string $className
31
     * @param string $wrapperClassName
32
     */
33
    public function __construct($className, $wrapperClassName = '')
34
    {
35
        $this->className = $className;
36
        $this->wrapperClassName = $wrapperClassName;
37
    }
38
39
    /**
40
     * {@inheritdoc}
41
     */
42
    public function run()
43
    {
44
        $delegate = new \ReflectionClass($this->className);
45
        $replacements = [];
46
47
        $leadingCommentChars = " * ";
48
        $methodDescriptions = [];
49
        $methodImplementations = [];
50
        $immediateMethods = [];
51
        foreach ($delegate->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
52
            $methodName = $method->name;
53
            $getter = preg_match('/^(get|has|is)/', $methodName);
54
            $setter = preg_match('/^(set|unset)/', $methodName);
55
            $argPrototypeList = [];
56
            $argNameList = [];
57
            $needsImplementation = false;
58
            foreach ($method->getParameters() as $arg) {
59
                $argDescription = '$' . $arg->name;
60
                $argNameList[] = $argDescription;
61
                if ($arg->isOptional()) {
62
                    $argDescription = $argDescription . ' = ' . str_replace("\n", "", var_export($arg->getDefaultValue(), true));
63
                    // We will create wrapper methods for any method that
64
                    // has default parameters.
65
                    $needsImplementation = true;
66
                }
67
                $argPrototypeList[] = $argDescription;
68
            }
69
            $argPrototypeString = implode(', ', $argPrototypeList);
70
            $argNameListString = implode(', ', $argNameList);
71
72
            if ($methodName[0] != '_') {
73
                $methodDescriptions[] = "@method $methodName($argPrototypeString)";
74
75
                if ($getter) {
76
                    $immediateMethods[] = "    public function $methodName($argPrototypeString)\n    {\n        return \$this->delegate->$methodName($argNameListString);\n    }";
77
                } elseif ($setter) {
78
                    $immediateMethods[] = "    public function $methodName($argPrototypeString)\n    {\n        \$this->delegate->$methodName($argNameListString);\n        return \$this;\n    }";
79
                } elseif ($needsImplementation) {
80
                    // Include an implementation for the wrapper method if necessary
81
                    $methodImplementations[] = "    protected function _$methodName($argPrototypeString)\n    {\n        \$this->delegate->$methodName($argNameListString);\n    }";
82
                }
83
            }
84
        }
85
86
        $classNameParts = explode('\\', $this->className);
87
        $delegate = array_pop($classNameParts);
88
        $delegateNamespace = implode('\\', $classNameParts);
89
90
        if (empty($this->wrapperClassName)) {
91
            $this->wrapperClassName = $delegate;
92
        }
93
94
        $replacements['{delegateNamespace}'] = $delegateNamespace;
95
        $replacements['{delegate}'] = $delegate;
96
        $replacements['{wrapperClassName}'] = $this->wrapperClassName;
97
        $replacements['{taskname}'] = "task$delegate";
98
        $replacements['{methodList}'] = $leadingCommentChars . implode("\n$leadingCommentChars", $methodDescriptions);
99
        $replacements['{immediateMethods}'] = "\n\n" . implode("\n\n", $immediateMethods);
100
        $replacements['{methodImplementations}'] = "\n\n" . implode("\n\n", $methodImplementations);
101
102
        $template = file_get_contents(__DIR__ . '/../../../data/Task/Development/GeneratedWrapper.tmpl');
103
        $template = str_replace(array_keys($replacements), array_values($replacements), $template);
104
105
        // Returning data in the $message will cause it to be printed.
106
        return Result::success($this, $template);
107
    }
108
}
109