Passed
Push — master ( 972013...9066c2 )
by karam
03:22
created

KMBaseBuilder::callArtisan()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 3
c 1
b 0
f 1
nc 1
nop 1
dl 0
loc 5
rs 10
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
        $databaseColumn = '$table->id();' . "\n";
127
        // we build here fillabel for model and column for migration file at once.
128
        foreach ($columns as $name => $item) {
129
            // build fillabe property in model.
130
            array_push($fillable, "'$name'");
131
            // get column type.
132
            $type = array_key_first($item['type']);
133
            // put this column as this ex : $table->string('name').
134
            $databaseColumn .= '$table->' . "$type('$name'); \n";
135
        }
136
        $imp = implode(",", $fillable);
137
        $protectedFillable .= 'protected $fillable = ' . " [$imp];";
138
        $this->replacement("//", $protectedFillable, $options["file"], $options["path"]);
0 ignored issues
show
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

138
        $this->replacement("//", /** @scrutinizer ignore-type */ $protectedFillable, $options["file"], $options["path"]);
Loading history...
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

138
        $this->replacement(/** @scrutinizer ignore-type */ "//", $protectedFillable, $options["file"], $options["path"]);
Loading history...
139
        // check if user choose to build migration.
140
        if (isset($options['migrationRequired'])) {
141
            // get all migrations files.
142
            $appMigrationPath = File::files(app_path("../database/migrations"));
143
            // get last migration file we create from second steps when we call artisan.
144
            $fileMigrationName = $appMigrationPath[array_key_last($appMigrationPath)]->getRelativePathname();
145
            // get final path.
146
            $fileMigrationPath = app_path("../database/migrations/$fileMigrationName");
147
            // open and read this migration file.
148
            $fileMigrationPathAsStream = File::get($fileMigrationPath);
149
            // now put columns inside file.
150
            return $this->replacement('$table->id();', $databaseColumn, $fileMigrationPathAsStream, $fileMigrationPath);
151
        }
152
    }
153
154
    /**
155
     * @param array $searchFor
156
     * @param array $replacementWith
157
     * @param string $file
158
     * @param string $path
159
     * @return false|int
160
     */
161
    public function replacement($searchFor, $replacementWith, $file, $path)
162
    {
163
        if (!gettype($searchFor) == 'array' && !gettype($replacementWith) == "array") {
164
            [$searchFor, $replacementWith] = [[$searchFor], [$replacementWith]];
165
        }
166
        $newFile = str_replace($searchFor, $replacementWith, $file);
0 ignored issues
show
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

166
        $newFile = str_replace($searchFor, /** @scrutinizer ignore-type */ $replacementWith, $file);
Loading history...
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

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