Passed
Pull Request — master (#25)
by Prateek
03:11
created

BaseGenerator::getFileContents()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Prateekkarki\Laragen\Generators;
4
use Prateekkarki\Laragen\Models\Module;
5
use Prateekkarki\Laragen\Models\FileSystem;
6
7
class BaseGenerator
8
{
9
    /**
10
     * Module instance to be generated
11
     *
12
     * @var \Prateekkarki\Laragen\Models\Module
13
     */
14
    protected $module;
15
16
    /**
17
     * Filesystem instance used to write files
18
     *
19
     * @var \Prateekkarki\Laragen\Models\FileSystem
20
     */
21
    protected $fileSystem;
22
23
    /**
24
     * File extension of the file to be generated
25
     * almost always equals "php", depending to the item being generated
26
     * kept to be able to generate html, txt or other similar file in the future
27
     *
28
     * @var string
29
     */
30
    protected $fileExtension = "php";
31
32
    /**
33
     * Suffix to be added to the end of filename, changes according to the generator
34
     * e.g. equals "Controller" on Controller generator to generate file PostController.php
35
     * e.g. equals ".blade" on view generator to generate file post.blade.php
36
     *
37
     * @var string
38
     */
39
    protected $fileSuffix = "";
40
41
    /**
42
     * Relative stub path for the child class
43
     * child classes usually just extend base class generated on laragen directory
44
     * child classes can be used to write updates that are not generated by laragen
45
     *
46
     * @var string
47
     */
48
    protected $childTemplate  = "backend/EmptyClass";
49
50
    /**
51
     * Option to check if generator requires a separate child class file to be generated
52
     *
53
     * @var boolean
54
     */
55
    protected $needsChildGeneration = true;
56
57
    /**
58
     * Create a new generator instance
59
     *
60
     * @param Module $module each generator requires a module to generate
61
     */
62
    public function __construct(Module $module)
63
    {
64
        $this->module = $module;
65
        $this->fileSystem = new FileSystem();
66
    }
67
68
    /**
69
     * Get current module being generated
70
     *
71
     * @return \Prateekkarki\Laragen\Models\Module
72
     */
73
    public function getModule()
74
    {
75
        return $this->module;
76
    }
77
78
    /**
79
     * Get stub content for the provided stubPath
80
     * allows the stub file from laragen/stubs directory on project base dir to override the one on package
81
     *
82
     * @param  string $stubPath relative path of the stub file to read from
83
     * @return string content read from the stub file
84
     */
85
    public function getStub($stubPath)
86
    {
87
        $customThemeStub = base_path('laragen/stubs/' . $stubPath.".stub");
88
89
        // Set stub file to the one from custom folder i.e. laragen/stubs if it exists, else use default from laragen package
90
        $stubFilePath = file_exists($customThemeStub) ?
91
            base_path('laragen/stubs/' . $stubPath.".stub") :
92
            realpath(__DIR__."/../stubs"). "/$stubPath.stub";
93
94
        return $this->getFileContents($stubFilePath);
95
    }
96
97
    /**
98
     * Sanitize the content for use in php
99
     * removes the carriage returns that comes from reading a file
100
     *
101
     * @param string  $content
102
     * @return string
103
     */
104
    public function sanitize($content)
105
    {
106
        return str_replace("\r", '', $content);
107
    }
108
109
    /**
110
     * Reads and returns the contents of a file as a string
111
     *
112
     * @param string $filePath absolute path of file to be read
113
     * @return string contents of the file
114
     */
115
    public function getFileContents($filePath){
116
        return $this->sanitize(file_get_contents($filePath));
117
    }
118
119
    /**
120
     * Get complete directory path by creating if not existing dir
121
     *
122
     * @param string $path
123
     * @return string
124
     */
125
    public function getPath($path)
126
    {
127
        $dir = base_path($path);
128
129
        if (!is_dir($dir)) {
130
            $this->fileSystem->mkdir($dir, 0755);
131
        }
132
133
        return $dir;
134
    }
135
136
    /**
137
     * Get file path for the base class of current generator
138
     *
139
     * @param  string|null $fileName is just the first part of filename without suffix or extension,
140
     *                               usually just null and the value is taken from model name of current module
141
     * @return string
142
     */
143
    public function getFilePath($fileName = null)
144
    {
145
        return $this->getPath($this->destination."/") . ($fileName ?? $this->module->getModelName()) . $this->fileSuffix . "." . $this->fileExtension;
146
    }
147
148
    /**
149
     * Get file path for the child class of current generator
150
     * very similar to getFilePath except this returns destination for child class
151
     * separate from getFilePath for better readability
152
     *
153
     * @param  string|null $fileName is same as in getFilePath above
154
     * @return string
155
     */
156
    public function getChildClassFilePath($fileName = null)
157
    {
158
        return $this->getPath($this->childDestination."/") . ($fileName ?? $this->module->getModelName()) . $this->fileSuffix . "." . $this->fileExtension;
159
    }
160
161
    /**
162
     * Generate file using the content and return the generated filename
163
     *
164
     * @param  string      $content
165
     * @param  string|null $file
166
     * @return string absolute path of generated file
167
     */
168
    public function generateFile($content, $filename = null)
169
    {
170
        $file = $this->getFilePath($filename);
171
        $this->fileSystem->dumpFile($file, $content);
172
173
        // Check if a child should be generated as in regular laravel file structure
174
        if($this->needsChildGeneration()){
175
            $childFile = $this->getChildClassFilePath($filename);
176
            if(!file_exists($childFile)){
177
                $childFileContent = $this->buildTemplate($this->childTemplate, [
178
                    '{{namespace}}'          => $this->childNamespace,
179
                    '{{className}}'          => $this->module->getModelName(),
180
                    '{{extendsClass}}'       => $this->namespace . '\\' . $this->module->getModelName()
181
                ]);
182
                $this->fileSystem->dumpFile($childFile, $childFileContent);
183
            }
184
        }
185
186
        return $file;
187
    }
188
189
    /**
190
     * Checks if current combination module and generator requires a child file to be generated
191
     *
192
     * ToDo: functionality to check for modules to be added
193
     *
194
     * @return boolean
195
     */
196
    public function needsChildGeneration(){
197
        return $this->needsChildGeneration;
198
    }
199
200
    /**
201
     * Delete files from target directory, used to remove previously generated files
202
     * Deletes all the files from target directory but not the directory itself
203
     *
204
     * @param string $target the directory to be cleared
205
     * @return void
206
     */
207
    public function deleteFiles($target) {
208
        if(is_dir($target)){
209
            $files = glob( $target . '*', GLOB_MARK );
210
211
            foreach( $files as $file ){
212
                $this->deleteFiles( $file );
213
            }
214
215
            rmdir( $target );
216
        } elseif(is_file($target)) {
217
            unlink( $target );
218
        }
219
    }
220
221
    /**
222
     * Used to initialize a new file at given path
223
     * rewrites if file already available
224
     *
225
     * @param string      $fullFilePath        absolute path of the file to write on
226
     * @param string      $stub                relative path of the stub file to read from
227
     * @param string|null $initializeContent   content to initialize the file with can be empty, just stub will be used in that case
228
     * @return void
229
     */
230
    public function initializeFile($fullFilePath, $stub, $initializeContent = null) {
231
        $content = $initializeContent ?? $this->buildTemplate($stub);
232
        $this->fileSystem->dumpFile($fullFilePath, $content);
233
    }
234
235
    /**
236
     * Iterates through provided filemaps and calls initializeFile()
237
     *
238
     * @param array $fileMaps
239
     * @return void
240
     */
241
    public function initializeFiles($fileMaps = []) {
242
        foreach ($fileMaps as $file => $stub) {
243
            $this->initializeFile($file, $stub);
244
        }
245
    }
246
247
    /**
248
     * Get contents to be written on generated file
249
     *
250
     * @param string $stub
251
     * @param array  $replacements
252
     * @return string
253
     */
254
    public function buildTemplate($stub, $replacements = [])
255
    {
256
        return str_replace(array_keys($replacements), array_values($replacements), $this->getStub($stub));
257
    }
258
259
    /**
260
     * Insert content into an existing file on the given position
261
     *
262
     * @param string  $file_path      absolute path of the file
263
     * @param string  $insert_marker  position of the file to be written on, this is a portion of content available on the file
264
     * @param string  $content        content to be written
265
     * @param boolean $after          option to write the content either after(true) or before(false) the insert marker
266
     * @return void
267
     */
268
    public function insertIntoFile($file_path, $insert_marker, $content, $after = true) {
269
        $contents = $this->getFileContents($file_path);
270
        $new_contents = ($after) ? str_replace($insert_marker, $insert_marker.$content, $contents) : str_replace($insert_marker, $content.$insert_marker, $contents);
271
        $this->fileSystem->dumpFile($file_path, $new_contents);
272
    }
273
274
275
    /**
276
     * Get string for the number of tabs
277
     * used to insert a certain number of tabs on a file
278
     *
279
     * @param int $number number of tabs to be generated
280
     * @return string
281
     */
282
    public function getTabs($number)
283
    {
284
        $str = "";
285
        for ($i = 0; $i < $number; $i++) {
286
            $str .= "    ";
287
        }
288
        return $str;
289
    }
290
}
291