KMBaseBuilder   A
last analyzed

Complexity

Total Complexity 22

Size/Duplication

Total Lines 228
Duplicated Lines 0 %

Importance

Changes 7
Bugs 0 Features 4
Metric Value
eloc 74
c 7
b 0
f 4
dl 0
loc 228
rs 10
wmc 22

12 Methods

Rating   Name   Duplication   Size   Complexity  
A callArtisan() 0 5 1
A requestReplacer() 0 26 3
A initialResource() 0 5 1
A updatePaths() 0 12 3
A array_first_value() 0 3 1
A ImplodeNameSpace() 0 3 1
A checkIfFileInSubFolder() 0 4 2
A build() 0 12 1
A array_last_value() 0 3 1
A modelAndMigrationReplacer() 0 32 4
A getClassName() 0 5 1
A replacement() 0 7 3
1
<?php
2
3
4
namespace KMLaravel\ApiGenerator\BuildClasses;
5
6
use Illuminate\Support\Facades\Artisan;
7
use Illuminate\Support\Facades\File;
8
use KMLaravel\ApiGenerator\Facade\KMFunctionsFacade;
9
use KMLaravel\ApiGenerator\Helpers\KMFile;
10
11
class KMBaseBuilder
12
{
13
    /**
14
     * @var string
15
     */
16
    protected $fileName;
17
    /**
18
     * @var string
19
     */
20
    protected $filepath;
21
    /**
22
     * @var string|mixed
23
     */
24
    protected $fileToCreate;
25
    /**
26
     * @var string
27
     */
28
    protected $functionToBuild;
29
    /**
30
     * @var array
31
     */
32
    protected $helperFileToGet = [
33
        "requestReplacer" => ["getRequestFile", "getRequestFileAsStream"],
34
        "modelAndMigrationReplacer" => ["getModelFile", "getModelFileAsStream"],
35
    ];
36
37
    /**
38
     * @param string $fileName
39
     * @param string $functionToBuild
40
     * @return KMBaseBuilder
41
     */
42
    public function initialResource($fileName, $functionToBuild): KMBaseBuilder
43
    {
44
        $this->functionToBuild = $functionToBuild;
45
        $this->fileName = $fileName;
46
        return $this;
47
    }
48
49
    /**
50
     * @param string $option
51
     * @return KMBaseBuilder
52
     */
53
    public function callArtisan($option = ''): KMBaseBuilder
54
    {
55
        $command = strtolower($this->typeToMake);
56
        Artisan::call("make:$command $this->fileName $option");
57
        return $this;
58
    }
59
60
    /**
61
     * @param array $options
62
     * @param null|string $file
63
     * @param null|string $fileAsStream
64
     * @return KMBaseBuilder
65
     *
66
     */
67
    public function updatePaths($options = [], $file = null, $fileAsStream = null): KMBaseBuilder
68
    {
69
        // check if user dose not insert any custom files paths
70
        if (is_null($file) && is_null($fileAsStream)) {
71
            $file = $this->helperFileToGet[$this->functionToBuild][0];
72
            $fileAsStream = $this->helperFileToGet[$this->functionToBuild][1];
73
        }
74
        // get this fil according whatever function we use from KMFileFacade facade
75
        $this->filepath = KMFile::$file("$this->fileName.php");
76
        // get this fil according whatever function we use from KMFileFacade facade as stream to read it and doing replacement process
77
        $this->fileToCreate = KMFile::$fileAsStream("$this->fileName.php");
78
        return $this;
79
    }
80
81
    /**
82
     * @param array $columns
83
     * @param array $options
84
     * @return false|int
85
     */
86
    public function requestReplacer($columns, $options = [])
87
    {
88
        file_put_contents($this->filepath, KMFile::getFilesFromStubsAsStream("Request"));
89
        $this->updatePaths();
90
        $validation = [];
91
        $validationRow = null;
92
        foreach ($columns as $name => $item) {
93
            // if user dose not choose any validations rules the default  rule will be sometimes
94
            // this allow Request Class to see fields
95
            foreach ($item['validation'] ?? ['sometimes'] as $rule) {
96
                $validation[] = $rule;
97
            }
98
            // we combine rules here like "name" => "required|min:1"
99
            $rulesAsString = implode("|", $validation);
100
            $validationRow .= "'$name' =>  '$rulesAsString',\n";
101
            $validation = [];
102
        }
103
        return $this->replacement(
104
            ["{{ request_namespace }}" , "{{ rules }}", "{{ request_class }}", "{{ request_auth }}"],
105
            [
106
                $this->checkIfFileInSubFolder("App\Http\Requests" , $this->fileName),
107
                $validationRow,
108
                $this->array_last_value(explode('/', $this->fileName)),
109
                KMFunctionsFacade::getRequestAuthAccessibility()
110
            ],
111
            $this->fileToCreate, $this->filepath);
112
    }
113
114
    /**
115
     * @param array $columns
116
     * @param array $options
117
     * the main job is to replace fillabe property in model
118
     * and column with type in migration file
119
     * @return false|int
120
     */
121
    public function modelAndMigrationReplacer($columns, $options = [])
122
    {
123
        // model area
124
        $fillable = [];
125
        $protectedFillable = "";
126
        // this step to support laravel 5.8
127
        $migrationId = app()->version() > 6 ? '$table->id();' : '$table->bigIncrements(\'id\');';
0 ignored issues
show
Bug introduced by
The function app was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

127
        $migrationId = /** @scrutinizer ignore-call */ app()->version() > 6 ? '$table->id();' : '$table->bigIncrements(\'id\');';
Loading history...
128
        $databaseColumn = $migrationId."\n";
129
        // we build here fillable for model and column for migration file at once.
130
        foreach ($columns as $name => $item) {
131
            // build fillable property in model.
132
            array_push($fillable, "'$name'");
133
            // get column type.
134
            $type = array_key_first($item['type']);
135
            // put this column as this ex : $table->string('name').
136
            $databaseColumn .= '$table->' . "$type('$name'); \n";
137
        }
138
        $imp = implode(",", $fillable);
139
        $protectedFillable .= 'protected $fillable = ' . " [$imp];";
140
        $this->replacement("//", $protectedFillable, $options["file"], $options["path"]);
0 ignored issues
show
Bug introduced by
'//' of type string is incompatible with the type array expected by parameter $searchFor of KMLaravel\ApiGenerator\B...eBuilder::replacement(). ( Ignorable by Annotation )

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

140
        $this->replacement(/** @scrutinizer ignore-type */ "//", $protectedFillable, $options["file"], $options["path"]);
Loading history...
Bug introduced by
$protectedFillable of type string is incompatible with the type array expected by parameter $replacementWith of KMLaravel\ApiGenerator\B...eBuilder::replacement(). ( Ignorable by Annotation )

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

140
        $this->replacement("//", /** @scrutinizer ignore-type */ $protectedFillable, $options["file"], $options["path"]);
Loading history...
141
        // check if user choose to build migration.
142
        if (isset($options['migrationRequired'])) {
143
            // get all migrations files.
144
            $appMigrationPath = File::files(app_path("../database/migrations"));
145
            // get last migration file we create from second steps when we call artisan.
146
            $fileMigrationName = $appMigrationPath[array_key_last($appMigrationPath)]->getRelativePathname();
147
            // get final path.
148
            $fileMigrationPath = app_path("../database/migrations/$fileMigrationName");
149
            // open and read this migration file.
150
            $fileMigrationPathAsStream = File::get($fileMigrationPath);
151
            // now put columns inside file.
152
            return $this->replacement($migrationId, $databaseColumn, $fileMigrationPathAsStream, $fileMigrationPath);
153
        }
154
    }
155
156
    /**
157
     * @param array $searchFor
158
     * @param array $replacementWith
159
     * @param string $file
160
     * @param string $path
161
     * @return false|int
162
     */
163
    public function replacement($searchFor, $replacementWith, $file, $path)
164
    {
165
        if (!gettype($searchFor) == 'array' && !gettype($replacementWith) == "array") {
166
            [$searchFor, $replacementWith] = [[$searchFor], [$replacementWith]];
167
        }
168
        $newFile = str_replace($searchFor, $replacementWith, $file);
0 ignored issues
show
Bug introduced by
It seems like $searchFor can also be of type array<integer,array>; however, parameter $search of str_replace() does only seem to accept string|string[], maybe add an additional type check? ( Ignorable by Annotation )

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

168
        $newFile = str_replace(/** @scrutinizer ignore-type */ $searchFor, $replacementWith, $file);
Loading history...
Bug introduced by
It seems like $replacementWith can also be of type array<integer,array>; however, parameter $replace of str_replace() does only seem to accept string|string[], maybe add an additional type check? ( Ignorable by Annotation )

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

168
        $newFile = str_replace($searchFor, /** @scrutinizer ignore-type */ $replacementWith, $file);
Loading history...
169
        return file_put_contents($path, $newFile);
170
    }
171
172
    /**
173
     * @param array $column
174
     * @param array $options
175
     * @return mixed
176
     */
177
    public function build($column, $options = [])
178
    {
179
        // update path after we build file name and whatever function we want to run.
180
        $this->updatePaths();
181
        // determine this function to run.
182
        $functionToBuild = $this->functionToBuild;
183
        // run this function.
184
        $this->$functionToBuild($column, array_merge([
185
            "file" => $this->fileToCreate, "path" => $this->filepath
186
        ], $options));
187
        // return final file path we process.
188
        return $this->filepath;
189
    }
190
191
    /**
192
     * @param array $array
193
     * @return mixed
194
     */
195
    protected function array_first_value($array)
196
    {
197
        return $array[0];
198
    }
199
200
    /**
201
     * @param array $array
202
     * @return mixed
203
     */
204
    protected function array_last_value($array = [])
205
    {
206
        return $array[array_key_last($array)];
207
    }
208
209
    /**
210
     * @param array | mixed $classNameSpace
211
     * @return mixed
212
     */
213
    protected function getClassName($classNameSpace)
214
    {
215
        $fullNameSpaceClass = explode('\\', $classNameSpace);
216
        $lastWord = array_key_last(explode('\\', $classNameSpace));
217
        return $this->array_first_value(explode('\\', $fullNameSpaceClass[$lastWord]));
218
    }
219
220
    /**
221
     * @param $initPath
222
     * @param $fileName
223
     * @return string
224
     */
225
    protected function checkIfFileInSubFolder($initPath , $fileName){
226
        $fileNameAsArray = explode('/' , $fileName);
227
        if (sizeof($fileNameAsArray) > 1)  return $this->ImplodeNameSpace($initPath , $fileNameAsArray);
228
        return $initPath;
229
    }
230
231
    /**
232
     * @param $initPath
233
     * @param $fileNameAsArray
234
     * @return string
235
     */
236
    protected function ImplodeNameSpace($initPath , $fileNameAsArray){
237
        array_pop($fileNameAsArray);
238
        return "$initPath\\".implode('\\' , $fileNameAsArray);
239
    }
240
}
241