Completed
Push — master ( ee6555...11b8cd )
by Iurii
17:35
created

Generator::prepareFolder()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 1
1
<?php
2
3
/**
4
 * @package Skeleton module
5
 * @author Iurii Makukh <[email protected]>
6
 * @copyright Copyright (c) 2015, Iurii Makukh
7
 * @license https://www.gnu.org/licenses/gpl.html GNU/GPLv3
8
 */
9
10
namespace gplcart\modules\skeleton\models;
11
12
use gplcart\core\Model;
13
use gplcart\core\helpers\Zip as ZipHelper;
14
15
/**
16
 * Methods to generate module skeletons
17
 */
18
class Generator extends Model
19
{
20
21
    /**
22
     * Name of folder that contains module controllers
23
     */
24
    const FOLDER_CONTROLLER = 'controllers';
25
26
    /**
27
     * Name of folder that contains module helpers
28
     */
29
    const FOLDER_HELPER = 'helpers';
30
31
    /**
32
     * Name of folder that contains module models
33
     */
34
    const FOLDER_MODEL = 'models';
35
36
    /**
37
     * Name of folder that contains module handlers
38
     */
39
    const FOLDER_HANDLER = 'handlers';
40
41
    /**
42
     * Name of folder that contains module templates
43
     */
44
    const FOLDER_TEMPLATE = 'templates';
45
46
    /**
47
     * Name of folder that contains module overrides
48
     */
49
    const FOLDER_OVERRIDE = 'override';
50
51
    /**
52
     * Name of folder that contains JS assets
53
     */
54
    const FOLDER_JS = 'js';
55
56
    /**
57
     * Name of folder that contains CSS assets
58
     */
59
    const FOLDER_CSS = 'css';
60
61
    /**
62
     * Name of folder that contains images
63
     */
64
    const FOLDER_IMAGE = 'image';
65
66
    /**
67
     * Zip class instance
68
     * @var \gplcart\core\helpers\Zip $zip
69
     */
70
    protected $zip;
71
72
    /**
73
     * Full path to a ZIP file containing generated module
74
     * @var string
75
     */
76
    protected $file;
77
78
    /**
79
     * The current module folder
80
     * @var string
81
     */
82
    protected $folder;
83
84
    /**
85
     * An array of module data
86
     * @var array
87
     */
88
    protected $data = array();
89
90
    /**
91
     * Constructor
92
     * @param ZipHelper $zip
93
     */
94
    public function __construct(ZipHelper $zip)
95
    {
96
        parent::__construct();
97
98
        $this->zip = $zip;
99
    }
100
101
    /**
102
     * Returns an array of licenses and their URLs
103
     * @return array
104
     */
105
    public function getLicenses()
106
    {
107
        return array(
108
            'GPL-3.0+' => 'https://www.gnu.org/licenses/gpl-3.0.en.html',
109
            'MIT' => 'https://opensource.org/licenses/MIT',
110
            'Apache-2.0' => 'https://www.apache.org/licenses/LICENSE-2.0',
111
            'BSD-3-Clause' => 'https://opensource.org/licenses/BSD-3-Clause'
112
        );
113
    }
114
115
    /**
116
     * Generates module files and folders
117
     * @param array $data
118
     * @return bool
119
     */
120
    public function generate(array $data)
121
    {
122
        $this->setData($data);
123
        $this->createMainClass();
124
125
        if (!empty($this->data['structure'])) {
126
            $this->createStructure();
127
        }
128
129
        return $this->createZip();
130
    }
131
132
    /**
133
     * Creates various structure elements
134
     */
135
    protected function createStructure()
136
    {
137
        foreach ($this->data['structure'] as $element) {
138
            switch ($element) {
139
                case 'controller' :
0 ignored issues
show
Coding Style introduced by
There must be no space before the colon in a CASE statement

As per the PSR-2 coding standard, there must not be a space in front of the colon in case statements.

switch ($selector) {
    case "A": //right
        doSomething();
        break;
    case "B" : //wrong
        doSomethingElse();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
140
                    $this->createStructureController();
141
                    break;
142
                case 'model':
143
                    $this->createStructureModel();
144
                    break;
145
                case 'helper':
146
                    $this->createStructureHelper();
147
                    break;
148
                case 'handler':
149
                    $this->createStructureHandler();
150
                    break;
151
                case 'override':
152
                    $this->createStructureOverride();
153
                    break;
154
                case 'template':
155
                    $this->createStructureTemplate();
156
                    break;
157
                case 'asset':
158
                    $this->createStructureAsset();
159
                    break;
160
            }
161
        }
162
163
        $this->write("{$this->folder}/README.md", 'readme');
164
        $this->write("{$this->folder}/.gitignore", 'gitignore');
165
        $this->write("{$this->folder}/composer.json", 'composer');
166
        $this->write("{$this->folder}/.scrutinizer.yml", 'scrutinizer');
167
    }
168
169
    /**
170
     * Creates asset structure
171
     */
172
    protected function createStructureAsset()
173
    {
174
        $subfolders = array(self::FOLDER_CSS, self::FOLDER_JS, self::FOLDER_IMAGE);
175
176
        foreach ($subfolders as $subfolder) {
177
            if ($this->prepareFolder("{$this->folder}/$subfolder")) {
178
                $filename = $subfolder == self::FOLDER_IMAGE ? 'image.png' : "common.$subfolder";
179
                $this->write("{$this->folder}/$subfolder/$filename", $subfolder);
180
            }
181
        }
182
    }
183
184
    /**
185
     * Creates a controller class
186
     */
187
    protected function createStructureController()
188
    {
189
        $folder = $this->folder . '/' . self::FOLDER_CONTROLLER;
190
191
        if ($this->prepareFolder($folder)) {
192
            $this->write("$folder/Settings.php", 'controller');
193
        }
194
    }
195
196
    /**
197
     * Cretates module main class
198
     */
199
    protected function createMainClass()
200
    {
201
        if ($this->prepareFolder($this->folder)) {
202
            $this->write("{$this->folder}/{$this->data['module']['class_name']}.php", 'main');
203
        }
204
    }
205
206
    /**
207
     * Creates a model class
208
     */
209
    protected function createStructureModel()
210
    {
211
        $folder = $this->folder . '/' . self::FOLDER_MODEL;
212
213
        if ($this->prepareFolder($folder)) {
214
            $this->write("$folder/{$this->data['module']['class_name']}.php", 'model');
215
        }
216
    }
217
218
    /**
219
     * Creates a helper class
220
     */
221
    protected function createStructureHelper()
222
    {
223
        $folder = $this->folder . '/' . self::FOLDER_HELPER;
224
225
        if ($this->prepareFolder($folder)) {
226
            $this->write("$folder/{$this->data['module']['class_name']}.php", 'helper');
227
        }
228
    }
229
230
    /**
231
     * Creates a handler class
232
     */
233
    protected function createStructureHandler()
234
    {
235
        $folder = $this->folder . '/' . self::FOLDER_HANDLER;
236
237
        if ($this->prepareFolder($folder)) {
238
            $this->write("$folder/{$this->data['module']['class_name']}.php", 'handler');
239
        }
240
    }
241
242
    /**
243
     * Creates module overrides
244
     */
245
    protected function createStructureOverride()
246
    {
247
        $folder = $this->folder . '/' . self::FOLDER_OVERRIDE . "/modules/{$this->data['module']['id']}";
248
249
        if ($this->prepareFolder($folder)) {
250
            $this->write("$folder/{$this->data['module']['class_name']}Override.php", 'override');
251
        }
252
    }
253
254
    /**
255
     * Creates a template sample
256
     */
257
    protected function createStructureTemplate()
258
    {
259
        $folder = $this->folder . '/' . self::FOLDER_TEMPLATE;
260
261
        if ($this->prepareFolder($folder)) {
262
            $this->write("$folder/settings.php", 'template');
263
        }
264
    }
265
266
    /**
267
     * Pack module folder into zip file
268
     * @return bool
269
     */
270
    protected function createZip()
271
    {
272
        $this->file = "{$this->folder}.zip";
273
274
        if (is_file($this->file)) {
275
            unlink($this->file);
276
        }
277
278
        $result = $this->zip->folder($this->folder, $this->file, $this->data['module']['id']);
279
        gplcart_file_delete_recursive($this->folder);
280
        return $result;
281
    }
282
283
    /**
284
     * Returns a path to zip file
285
     * @return string
286
     */
287
    public function getZip()
288
    {
289
        return $this->file;
290
    }
291
292
    /**
293
     * Recursively creates folders
294
     * @param string $folder
295
     * @return bool
296
     */
297
    protected function prepareFolder($folder)
298
    {
299
        return !is_dir($folder) && mkdir($folder, 0775, true);
300
    }
301
302
    /**
303
     * Prepares an array of data before rendering
304
     * @param array $data
305
     * @return string
306
     */
307
    protected function setData(array &$data)
308
    {
309
        $licenses = $this->getLicenses();
310
311
        $data['module']['class_name'] = $this->config->getModuleClassName($data['module']['id']);
312
        $data['module']['namespace'] = $this->config->getModuleClassNamespace($data['module']['id']);
313
        $data['module']['license_url'] = $licenses[$data['module']['license']] . ' ' . $data['module']['license'];
314
315
        $this->folder = gplcart_file_unique(GC_PRIVATE_DOWNLOAD_DIR . "/skeleton/{$data['module']['id']}");
316
        return $this->data = $data;
317
    }
318
319
    /**
320
     * Renders a template
321
     * @param string $template
322
     * @return string|null
323
     */
324
    protected function render($template)
325
    {
326
        $file = GC_MODULE_DIR . "/skeleton/templates/$template.php";
327
328
        if (!is_file($file)) {
329
            return null;
330
        }
331
332
        extract($this->data, EXTR_SKIP);
333
        ob_start();
334
        include $file;
335
        return ob_get_clean();
336
    }
337
338
    /**
339
     * Writes to a file using a template as an source
340
     * @param string $file
341
     * @param string $template
342
     * @return null
343
     */
344
    protected function write($file, $template)
345
    {
346
        $content = $this->render($template);
347
348
        if (!isset($content)) {
349
            return null;
350
        }
351
352
        if (pathinfo($file, PATHINFO_EXTENSION) === 'php') {
353
            $content = "<?php\n\n$content";
354
        }
355
356
        file_put_contents($file, $content);
357
    }
358
359
}
360