Completed
Push — master ( 6697a1...5bda87 )
by Arman
20s queued 15s
created

OpenApiCommand::exec()   B

Complexity

Conditions 7
Paths 12

Size

Total Lines 37
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 19
nc 12
nop 0
dl 0
loc 37
rs 8.8333
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Quantum PHP Framework
5
 *
6
 * An open source software development framework for PHP
7
 *
8
 * @package Quantum
9
 * @author Arman Ag. <[email protected]>
10
 * @copyright Copyright (c) 2018 Softberg LLC (https://softberg.org)
11
 * @link http://quantum.softberg.org/
12
 * @since 2.8.0
13
 */
14
15
namespace Quantum\Console\Commands;
16
17
use Quantum\Libraries\Storage\FileSystem;
18
use Quantum\Router\ModuleLoader;
19
use Quantum\Console\QtCommand;
20
use Quantum\Di\Di;
21
22
/**
23
 * Class OpenApiUiAssetsCommand
24
 * @package Quantum\Console\Commands
25
 */
26
class OpenApiCommand extends QtCommand
27
{
28
29
    /**
30
     * File System
31
     * @var \Quantum\Libraries\Storage\FileSystem
32
     */
33
    protected $fs;
34
35
    /**
36
     * Command name
37
     * @var string
38
     */
39
    protected $name = 'install:openapi';
40
41
    /**
42
     * Command description
43
     * @var string
44
     */
45
    protected $description = 'Generates files for OpenApi UI';
46
47
    /**
48
     * Command arguments
49
     * @var string[][]
50
     */
51
    protected $args = [
52
        ['module', 'required', 'The module name'],
53
    ];
54
55
    /**
56
     * Command help text
57
     * @var string
58
     */
59
    protected $help = 'The command will publish OpenApi UI resources';
60
61
    /**
62
     * Path to public debug bar resources
63
     * @var string 
64
     */
65
    private $publicOpenApiFolderPath = 'public/assets/OpenApiUi';
66
67
    /**
68
     * Path to vendor debug bar resources
69
     * @var string 
70
     */
71
    private $vendorOpenApiFolderPath = 'vendor/swagger-api/swagger-ui/dist';
72
73
    /**
74
     * Exclude File Names
75
     * @var array
76
     */
77
    private $excludeFileNames = ['index.html', 'swagger-initializer.js', 'favicon-16x16.png', 'favicon-32x32.png'];
78
79
    /**
80
     * Executes the command and publishes the debug bar assets
81
     */
82
    public function exec()
83
    {
84
        ModuleLoader::loadModulesRoutes();
85
86
        $this->fs = Di::get(FileSystem::class);
87
88
        $module = $this->getArgument('module');
89
90
        $modulePath = modules_dir() . DS . $module;
91
92
        $routes = $modulePath . DS . 'Config' . DS . 'routes.php';
93
94
        if (!$this->fs->exists(assets_dir() . DS . 'OpenApiUi' . DS . 'index.css')) {
95
            $this->copyResources();
96
        }
97
98
        if (!$this->fs->isDirectory($modulePath)) {
99
            $this->error('The module `' . ucfirst($module) . '` not found');
100
            return;
101
        }
102
103
        if (route_group_exists('openapi', $module) && $this->fs->exists($modulePath . DS . 'Resources' . DS . 'openApi' . DS . 'spec.json')) {
104
            $this->error('The Open API sepcifications already installed for `' . ucfirst($module) . '` module');
105
            return;
106
        }
107
108
        if (!route_group_exists('openapi', $module)) {
109
            $this->fs->put($routes, str_replace('return function ($route) {', $this->openapiRoutes($module), $this->fs->get($routes)));
110
        }
111
112
        if (!$this->fs->isDirectory($modulePath . DS . 'Resources' . DS . 'openapi')) {
113
            $this->fs->makeDirectory($modulePath . DS . 'Resources' . DS . 'openapi');
114
        }
115
116
        $this->generateOpenapiSpecification($module);
117
118
        $this->info('OpenApi recources successfully published');
119
    }
120
121
    /**
122
     * Copies OpenApi Resources
123
     */
124
    private function copyResources()
125
    {
126
        $dir = opendir($this->vendorOpenApiFolderPath);
127
128
        if (is_resource($dir)) {
129
            while (($file = readdir($dir))) {
130
                if (($file != '.') && ($file != '..') && !in_array($file, $this->excludeFileNames)) {
131
                    copy($this->vendorOpenApiFolderPath . DS . $file, $this->publicOpenApiFolderPath . DS . $file);
132
                }
133
            }
134
135
            closedir($dir);
136
        }
137
    }
138
139
    /**
140
     * Generates file with OpenApi specifications
141
     * @param string $module
142
     */
143
    private function generateOpenapiSpecification(string $module)
144
    {
145
        exec(base_dir() . DS . 'vendor' . DS . 'bin' . DS . 'openapi ' . modules_dir() . DS . $module . DS . 'Controllers' . DS . ' -o ' . modules_dir() . DS . $module . DS . 'Resources' . DS . 'openapi' . DS . 'spec.json');
146
    }
147
148
    /**
149
     * Gets the OpenApi routes
150
     * @param string $module
151
     * @return string
152
     */
153
    private function openapiRoutes(string $module): string
154
    {
155
        return 'return function ($route) {
156
    $route->group("openapi", function ($route) {
157
        $route->get("' . strtolower($module) . '/docs", function (Quantum\Http\Response $response) {
158
            $response->html(partial("openapi/openapi"));
159
        });
160
161
        $route->get("' . strtolower($module) . '/spec", function (Quantum\Http\Response $response) {
162
            $fs = Quantum\Di\Di::get(Quantum\Libraries\Storage\FileSystem::class);
163
            $response->json((array) json_decode($fs->get(modules_dir() . "' . DS . $module . DS . 'Resources' . DS . 'openapi' . DS . 'spec.json")));
164
        });
165
    });' . PHP_EOL;
166
    }
167
168
}
169