GenerateClasses::execute()   D
last analyzed

Complexity

Conditions 14
Paths 86

Size

Total Lines 89
Code Lines 53

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
dl 0
loc 89
rs 4.9516
c 2
b 0
f 0
cc 14
eloc 53
nc 86
nop 2

How to fix   Long Method    Complexity   

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
 * This file is part of the Drest package.
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 *
8
 * @author Lee Davis
9
 * @copyright Copyright (c) Lee Davis <@leedavis81>
10
 * @link https://github.com/leedavis81/drest/blob/master/LICENSE
11
 * @license http://opensource.org/licenses/MIT The MIT X License (MIT)
12
 */
13
namespace Drest\Tools\Console\Command;
14
15
use Drest\ClassGenerator;
16
use Guzzle\Http\Client;
17
use Guzzle\Http\Message\RequestInterface;
18
use Symfony\Component\Console\Command\Command;
19
use Symfony\Component\Console\Input\InputArgument;
20
use Symfony\Component\Console\Input\InputInterface;
21
use Symfony\Component\Console\Input\InputOption;
22
use Symfony\Component\Console\Output\OutputInterface;
23
use Symfony\Component\Console;
24
25
/**
26
 * Check Drest definitions
27
 */
28
class GenerateClasses extends Command
29
{
30
    /**
31
     * @see Console\Command\Command
32
     */
33
    protected function configure()
34
    {
35
        $this
36
            ->setName('classes:generate')
37
            ->setDescription('Generate client classes to interact with a Drest endpoint.')
38
            ->setDefinition(
39
                [
40
                    new InputArgument(
41
                        'endpoint', InputArgument::REQUIRED, 'The location of the drest API endpoint.'
42
                    ),
43
                    new InputOption(
44
                        'dest-path', null, InputOption::VALUE_OPTIONAL,
45
                        'The path to generate your client classes too. If not provided classes are put in the execution path.'
46
                    ),
47
                    new InputOption(
48
                        'namespace', null, InputOption::VALUE_OPTIONAL,
49
                        'The namespace you would like applied to the classes. This would be prepended to any existing namespaces the classes have'
50
                    )
51
                ]
52
            )
53
            ->setHelp(
54
                <<<EOT
55
                Generate the classes required to interact with a Drest API endpoint.
56
Example usage:
57
58
        classes:generate http://api.endpoint.com --dest-path "{/home/me/classes}"
59
EOT
60
            );
61
    }
62
63
    /**
64
     * @see Console\Command\Command
65
     * @param InputInterface $input
66
     * @param OutputInterface $output
67
     * @throws \Exception
68
     * @return void
69
     */
70
    protected function execute(InputInterface $input, OutputInterface $output)
71
    {
72
        $endpoint = $input->getArgument('endpoint');
73
74
        if (($endpoint = filter_var($endpoint, FILTER_VALIDATE_URL)) === false) {
75
            throw new \Exception('Invalid endpoint URI provided');
76
        }
77
78
        $client = new Client($endpoint);
79
        $request = $client->createRequest(
80
            RequestInterface::OPTIONS,
81
            null,
82
            [ClassGenerator::HEADER_PARAM => 'true']
83
        );
84
85
        $response = $client->send($request);
86
        if (!$response->isSuccessful()) {
87
            throw new \Exception('Invalid response from provided endpoint.');
88
        }
89
90
        // Process destination directory
91
        if (($path = $input->getOption('dest-path')) === null) {
92
            $path = getcwd();
93
        }
94
        if (!is_dir($path)) {
95
            mkdir($path, 0755, true);
96
        }
97
98
        $path = realpath($path);
99
        if (!file_exists($path)) {
100
            throw new \Exception('Destination path doesn\'t exist and couldn\'t be created');
101
        } else {
102
            if (!is_writable($path)) {
103
                throw new \Exception('Cannot write to destination path');
104
            }
105
        }
106
107
        $classes = unserialize($response->getBody(true));
108
        if (!is_array($classes)) {
109
            throw new \Exception('Unexpected response from HTTP endpoint. Array of class objects was expected');
110
        }
111
        $classes = array_filter(
112
            $classes,
113
            function ($item) {
114
                return (get_class($item) == 'Zend\Code\Generator\ClassGenerator');
115
            }
116
        );
117
        if (sizeof($classes) === 0) {
118
            throw new \Exception('No classes to be generated');
119
        }
120
121
        $output->write(
122
            PHP_EOL . sprintf('Generating client classes....') . PHP_EOL
123
        );
124
125
        $clientNamespace = trim($input->getOption('namespace'), '\\');
126
        foreach ($classes as $class) {
127
            /* @var \Zend\Code\Generator\ClassGenerator $class */
128
            $dir = $path;
129
            $namespace = $class->getNamespaceName();
130
131
            if (!empty($namespace)) {
132
                $dir .= DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, trim($namespace, '\\'));
133
            }
134
            if (!is_dir($dir)) {
135
                mkdir($dir, 0755, true);
136
            }
137
            $classPath = $dir . DIRECTORY_SEPARATOR . $class->getName() . '.php';
138
139
            // Prepend any client supplied namespace
140
            if (!is_null($clientNamespace)) {
141
                $class->setNamespaceName($clientNamespace . '\\' . $class->getNamespaceName());
142
            }
143
144
            $handle = @fopen($classPath, 'w');
145
            if (!is_resource($handle)) {
146
                throw new \Exception('Unable to create a file handle for client class ' . $classPath);
147
            }
148
            fwrite($handle, "<?php\n" . $class->generate());
149
            fclose($handle);
150
            $output->write(
151
                sprintf('Successfully wrote client class "<info>%s</info>"', $classPath) . PHP_EOL
152
            );
153
        }
154
155
        $output->write(
156
            PHP_EOL . sprintf('Client classes have been successfully generated at "<info>%s</info>"', $path) . PHP_EOL
157
        );
158
    }
159
}
160