Completed
Push — master ( 757ee3...845f7d )
by Iurii
02:01
created

Generator::createManifest()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 19
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

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