Completed
Push — master ( f62bbe...8c83be )
by Iurii
01:27
created

Generator::generateImage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 11
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 module translations
53
     */
54
    const FOLDER_LOCALE = 'locale';
55
56
    /**
57
     * Name of folder that contains JS assets
58
     */
59
    const FOLDER_JS = 'js';
60
61
    /**
62
     * Name of folder that contains CSS assets
63
     */
64
    const FOLDER_CSS = 'css';
65
66
    /**
67
     * Name of folder that contains images
68
     */
69
    const FOLDER_IMAGE = 'image';
70
71
    /**
72
     * Zip class instance
73
     * @var \gplcart\core\helpers\Zip $zip
74
     */
75
    protected $zip;
76
77
    /**
78
     * Full path to a ZIP file containing generated module
79
     * @var string
80
     */
81
    protected $file;
82
83
    /**
84
     * The current module directory
85
     * @var string
86
     */
87
    protected $directory;
88
89
    /**
90
     * An array of module data
91
     * @var array
92
     */
93
    protected $data = array();
94
95
    /**
96
     * @param ZipHelper $zip
97
     */
98
    public function __construct(ZipHelper $zip)
99
    {
100
        parent::__construct();
101
102
        $this->zip = $zip;
103
    }
104
105
    /**
106
     * Returns an array of licenses and their URLs
107
     * @return array
108
     */
109
    public function getLicenses()
110
    {
111
        return array(
112
            'GPL-3.0+' => 'https://www.gnu.org/licenses/gpl-3.0.en.html',
113
            'MIT' => 'https://opensource.org/licenses/MIT',
114
            'Apache-2.0' => 'https://www.apache.org/licenses/LICENSE-2.0',
115
            'BSD-3-Clause' => 'https://opensource.org/licenses/BSD-3-Clause'
116
        );
117
    }
118
119
    /**
120
     * Generates module files and folders
121
     * @param array $data
122
     * @return bool
123
     */
124
    public function generate(array $data)
125
    {
126
        $this->setData($data);
127
128
        $this->createMainClass();
129
        $this->createManifest();
130
        $this->createStructure();
131
132
        return $this->createZip();
133
    }
134
135
    /**
136
     * Create module manifest file
137
     */
138
    protected function createManifest()
139
    {
140
        $data = array(
141
            'name' => $this->data['module']['name'],
142
            'version' => $this->data['module']['version'],
143
            'description' => $this->data['module']['description'],
144
            'author' => $this->data['module']['author'],
145
            'core' => $this->data['module']['core'],
146
            'license' => $this->data['module']['license']
147
        );
148
149
        if (!empty($this->data['structure']) && in_array('configurable', $this->data['structure'])) {
150
            $data['configure'] = 'admin/module/settings/' . $this->data['module']['id'];
151
            $data['settings'] = array();
152
        }
153
154
        $json = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
155
        file_put_contents("{$this->directory}/module.json", $json);
156
    }
157
158
    /**
159
     * Creates various structure elements
160
     */
161
    protected function createStructure()
162
    {
163
        $this->write("{$this->directory}/README.md", 'readme');
164
        $this->write("{$this->directory}/.gitignore", 'gitignore');
165
        $this->write("{$this->directory}/composer.json", 'composer');
166
        $this->write("{$this->directory}/.scrutinizer.yml", 'scrutinizer');
167
168
        if (empty($this->data['structure'])) {
169
            return null;
170
        }
171
172
        foreach ($this->data['structure'] as $element) {
173
            switch ($element) {
174
                case 'controller':
175
                    $this->createStructureController();
176
                    break;
177
                case 'model':
178
                    $this->createStructureModel();
179
                    break;
180
                case 'helper':
181
                    $this->createStructureHelper();
182
                    break;
183
                case 'handler':
184
                    $this->createStructureHandler();
185
                    break;
186
                case 'override':
187
                    $this->createStructureOverride();
188
                    break;
189
                case 'template':
190
                    $this->createStructureTemplate();
191
                    break;
192
                case 'asset':
193
                    $this->createStructureAsset();
194
                    break;
195
                case 'locale':
196
                    $this->createStructureLocale();
197
                    break;
198
            }
199
        }
200
    }
201
202
    /**
203
     * Creates asset structure
204
     */
205
    protected function createStructureAsset()
206
    {
207
        foreach (array(self::FOLDER_CSS, self::FOLDER_JS) as $folder) {
208
            if ($this->prepareFolder("{$this->directory}/$folder")) {
209
                $this->write("{$this->directory}/$folder/common.$folder", $folder);
210
            }
211
        }
212
213
        $this->generateImage();
214
    }
215
216
    /**
217
     * Generate an image sample
218
     * @return bool
219
     */
220
    protected function generateImage()
221
    {
222
        $directory = $this->directory . '/' . self::FOLDER_IMAGE;
223
224
        if (!mkdir($directory, 0775, true)) {
225
            return false;
226
        }
227
228
        $im = imagecreate(100, 100);
229
        $bg = imagecolorallocate($im, 255, 255, 255);
0 ignored issues
show
Unused Code introduced by
$bg is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
230
        $text = imagecolorallocate($im, 0, 0, 255);
231
        imagestring($im, 5, 0, 0, $this->data['module']['name'], $text);
232
        $result = imagepng($im, "$directory/image.png");
233
        imagedestroy($im);
234
        return $result;
235
    }
236
237
    /**
238
     * Creates locale structure
239
     */
240
    protected function createStructureLocale()
241
    {
242
        $folder = $this->directory . '/' . self::FOLDER_LOCALE;
243
244
        if ($this->prepareFolder($folder)) {
245
            $name = $this->data['module']['name'];
246
            gplcart_file_csv("$folder/en.csv", array($name, $name));
247
        }
248
    }
249
250
    /**
251
     * Creates a controller class
252
     */
253
    protected function createStructureController()
254
    {
255
        $folder = $this->directory . '/' . self::FOLDER_CONTROLLER;
256
257
        if ($this->prepareFolder($folder)) {
258
            $this->write("$folder/Settings.php", 'controller');
259
        }
260
    }
261
262
    /**
263
     * Creates module main class
264
     */
265
    protected function createMainClass()
266
    {
267
        if ($this->prepareFolder($this->directory)) {
268
            $this->write("{$this->directory}/{$this->data['module']['class_name']}.php", 'main');
269
        }
270
    }
271
272
    /**
273
     * Creates a model class
274
     */
275
    protected function createStructureModel()
276
    {
277
        $folder = $this->directory . '/' . self::FOLDER_MODEL;
278
279
        if ($this->prepareFolder($folder)) {
280
            $this->write("$folder/{$this->data['module']['class_name']}.php", 'model');
281
        }
282
    }
283
284
    /**
285
     * Creates a helper class
286
     */
287
    protected function createStructureHelper()
288
    {
289
        $folder = $this->directory . '/' . self::FOLDER_HELPER;
290
291
        if ($this->prepareFolder($folder)) {
292
            $this->write("$folder/{$this->data['module']['class_name']}.php", 'helper');
293
        }
294
    }
295
296
    /**
297
     * Creates a handler class
298
     */
299
    protected function createStructureHandler()
300
    {
301
        $folder = $this->directory . '/' . self::FOLDER_HANDLER;
302
303
        if ($this->prepareFolder($folder)) {
304
            $this->write("$folder/{$this->data['module']['class_name']}.php", 'handler');
305
        }
306
    }
307
308
    /**
309
     * Creates module overrides
310
     */
311
    protected function createStructureOverride()
312
    {
313
        $folder = $this->directory . '/' . self::FOLDER_OVERRIDE . "/classes/modules/{$this->data['module']['id']}";
314
315
        if ($this->prepareFolder($folder)) {
316
            $this->write("$folder/{$this->data['module']['class_name']}Override.php", 'override');
317
        }
318
    }
319
320
    /**
321
     * Creates a template sample
322
     */
323
    protected function createStructureTemplate()
324
    {
325
        $folder = $this->directory . '/' . self::FOLDER_TEMPLATE;
326
327
        if ($this->prepareFolder($folder)) {
328
            $this->write("$folder/settings.php", 'template');
329
        }
330
    }
331
332
    /**
333
     * Pack module folder into zip file
334
     * @return bool
335
     */
336
    protected function createZip()
337
    {
338
        $this->file = "{$this->directory}.zip";
339
340
        if (is_file($this->file)) {
341
            unlink($this->file);
342
        }
343
344
        $result = $this->zip->folder($this->directory, $this->file, $this->data['module']['id']);
345
        gplcart_file_delete_recursive($this->directory);
346
        return $result;
347
    }
348
349
    /**
350
     * Returns a path to zip file
351
     * @return string
352
     */
353
    public function getZip()
354
    {
355
        return $this->file;
356
    }
357
358
    /**
359
     * Recursively creates folders
360
     * @param string $folder
361
     * @return bool
362
     */
363
    protected function prepareFolder($folder)
364
    {
365
        return !file_exists($folder) && mkdir($folder, 0775, true);
366
    }
367
368
    /**
369
     * Prepares an array of data before rendering
370
     * @param array $data
371
     * @return array
372
     */
373
    protected function setData(array &$data)
374
    {
375
        $licenses = $this->getLicenses();
376
377
        $data['module']['class_name'] = $this->config->getModuleClassName($data['module']['id']);
378
        $data['module']['namespace'] = $this->config->getModuleClassNamespace($data['module']['id']);
379
        $data['module']['license_url'] = $licenses[$data['module']['license']] . ' ' . $data['module']['license'];
380
381
        $this->directory = gplcart_file_unique(GC_PRIVATE_DOWNLOAD_DIR . "/skeleton/{$data['module']['id']}");
382
        return $this->data = $data;
383
    }
384
385
    /**
386
     * Renders a template
387
     * @param string $template
388
     * @return string|null
389
     */
390
    protected function render($template)
391
    {
392
        $file = GC_MODULE_DIR . "/skeleton/templates/code/$template.php";
393
394
        if (!is_file($file)) {
395
            return null;
396
        }
397
398
        extract($this->data, EXTR_SKIP);
399
        ob_start();
400
        include $file;
401
        return ob_get_clean();
402
    }
403
404
    /**
405
     * Writes to a file using a template as an source
406
     * @param string $file
407
     * @param string $template
408
     * @return null|bool
409
     */
410
    protected function write($file, $template)
411
    {
412
        $content = $this->render($template);
413
414
        if (!isset($content)) {
415
            return null;
416
        }
417
418
        if (pathinfo($file, PATHINFO_EXTENSION) === 'php') {
419
            $content = "<?php\n\n$content";
420
        }
421
422
        return file_put_contents($file, $content) !== false;
423
    }
424
425
}
426