Completed
Pull Request — master (#128)
by Ali
01:36
created

GenerateCode   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 7

Importance

Changes 0
Metric Value
dl 0
loc 129
rs 10
c 0
b 0
f 0
wmc 19
lcom 1
cbo 7

7 Methods

Rating   Name   Duplication   Size   Complexity  
B serviceProvider() 0 42 5
A makeDirectory() 0 8 2
A ask() 0 4 1
A isProvidersKey() 0 8 3
B addToProvidersArray() 0 23 6
A generateFolderStructure() 0 9 1
A routeContent() 0 10 1
1
<?php
2
3
namespace Imanghafoori\LaravelMicroscope;
4
5
use Illuminate\Support\Str;
6
use Imanghafoori\LaravelMicroscope\Analyzers\FunctionCall;
7
use Imanghafoori\LaravelMicroscope\Analyzers\NamespaceCorrector;
8
use Imanghafoori\LaravelMicroscope\Analyzers\Refactor;
9
use Imanghafoori\LaravelMicroscope\LaravelPaths\FilePath;
10
use Imanghafoori\LaravelMicroscope\Stubs\ServiceProviderStub;
11
12
class GenerateCode
13
{
14
    /**
15
     * Get all of the listeners and their corresponding events.
16
     *
17
     * @param  iterable  $paths
18
     * @param  $composerPath
19
     * @param  $composerNamespace
20
     * @param  $command
21
     *
22
     * @return void
23
     */
24
    public static function serviceProvider($paths, $composerPath, $composerNamespace, $command)
25
    {
26
        foreach ($paths as $classFilePath) {
27
            /**
28
             * @var $classFilePath \Symfony\Component\Finder\SplFileInfo
29
             */
30
            if (!Str::endsWith($classFilePath->getFilename(), ['ServiceProvider.php'])) {
31
                continue;
32
            }
33
            $absFilePath = $classFilePath->getRealPath();
34
            $content = file_get_contents($absFilePath);
35
36
            if (strlen(\trim($content)) > 10) {
37
                // file is not empty
38
                continue;
39
            }
40
41
            $relativePath = FilePath::getRelativePath($absFilePath);
42
            $correctNamespace = NamespaceCorrector::calculateCorrectNamespace($relativePath, $composerPath, $composerNamespace);
43
44
            $className = \str_replace('.php', '', $classFilePath->getFilename());
45
            $answer = self::ask($command, $correctNamespace . '\\' . $className);
46
            if (!$answer) {
47
                continue;
48
            }
49
            $prefix = strtolower(str_replace('ServiceProvider', '', $className));
50
51
            $stubContent = StubFileManager::getRenderedStub(
52
                'microscopeServiceProvider',
53
                [
54
                    'correctNamespace' => $correctNamespace,
55
                    'className' => $className,
56
                    'name' => $prefix,
57
                ]
58
            );
59
            
60
            file_put_contents($absFilePath, $stubContent);
61
62
            self::generateFolderStructure($classFilePath, $correctNamespace, $prefix);
63
            self::addToProvidersArray($correctNamespace . '\\' . $className);
64
        }
65
    }
66
67
    /**
68
     * Build the directory for the class if necessary.
69
     *
70
     * @param  string  $path
71
     * @return string
72
     */
73
    protected static function makeDirectory($path)
74
    {
75
        if (!is_dir($path)) {
76
            @mkdir($path, 0777, true);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
77
        }
78
79
        return $path;
80
    }
81
82
    private static function ask($command, $name)
83
    {
84
        return $command->getOutput()->confirm('Do you want to generate a service provider: ' . $name, true);
85
    }
86
87
    private static function isProvidersKey($tokens, $i)
88
    {
89
        $token = $tokens[$i];
90
91
        return $token[0] == T_CONSTANT_ENCAPSED_STRING &&
92
            \trim($token[1], '\'\"') == 'providers' &&
93
            \in_array(T_DOUBLE_ARROW, [$tokens[$i + 1][0], $tokens[$i + 2][0]]);
94
    }
95
96
    private static function addToProvidersArray($providerPath)
97
    {
98
        $tokens = token_get_all(file_get_contents(config_path('app.php')));
99
100
        foreach ($tokens as $i => $token) {
101
            if (!self::isProvidersKey($tokens, $i)) {
102
                continue;
103
            }
104
            $closeBracketIndex = FunctionCall::readBody($tokens, $i + 15, ']')[1];
105
106
            $j = $closeBracketIndex;
107
            while ($tokens[--$j][0] == T_WHITESPACE && $tokens[--$j][0] == T_COMMENT) {
108
            }
109
110
            // put a comma at the end of the array if it is not there
111
            $tokens[$j] !== ',' && array_splice($tokens, $j + 1, 0, [[',']]);
112
113
            array_splice($tokens, (int) $closeBracketIndex, 0, [["\n        " . $providerPath . '::class,' . "\n    "]]);
114
            file_put_contents(config_path('app.php'), Refactor::toString($tokens));
115
        }
116
117
        return $tokens;
118
    }
119
120
    protected static function generateFolderStructure($classFilePath, $namespace, $prefix)
121
    {
122
        $_basePath = $classFilePath->getPath() . DIRECTORY_SEPARATOR;
123
        file_put_contents($_basePath . $prefix . '_routes.php', self::routeContent($namespace));
124
        self::makeDirectory($_basePath . 'Database' . DIRECTORY_SEPARATOR . 'migrations');
125
        self::makeDirectory($_basePath . 'views');
126
        self::makeDirectory($_basePath . 'Http');
127
        self::makeDirectory($_basePath . 'Database' . DIRECTORY_SEPARATOR . 'Models');
128
    }
129
130
    protected static function routeContent($namespace)
131
    {
132
        return "<?php
133
134
use Illuminate\Support\Facades\Route;
135
136
Route::group(['middleware' => ['web'], 'namespace' => '$namespace\Http'], function () {
137
138
});";
139
    }
140
}
141