Completed
Push — master ( 770f4c...1169d0 )
by Iurii
05:14
created

Generator::createStructureTranslation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 5
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\helpers\Zip as ZipHelper;
13
use gplcart\core\Module;
14
15
/**
16
 * Methods to generate module skeletons
17
 */
18
class Generator
19
{
20
21
    /**
22
     * Module class instance
23
     * @var \gplcart\core\Module $module
24
     */
25
    protected $module;
26
27
    /**
28
     * Zip class instance
29
     * @var \gplcart\core\helpers\Zip $zip
30
     */
31
    protected $zip;
32
33
    /**
34
     * Full path to a ZIP file containing generated module
35
     * @var string
36
     */
37
    protected $file;
38
39
    /**
40
     * The current module directory
41
     * @var string
42
     */
43
    protected $directory;
44
45
    /**
46
     * An array of module data
47
     * @var array
48
     */
49
    protected $data = array();
50
51
    /**
52
     * @param Module $module
53
     * @param ZipHelper $zip
54
     */
55
    public function __construct(Module $module, ZipHelper $zip)
56
    {
57
        $this->zip = $zip;
58
        $this->module = $module;
59
    }
60
61
    /**
62
     * Returns an array of licenses and their URLs
63
     * @return array
64
     */
65
    public function getLicenses()
66
    {
67
        return array(
68
            'GPL-3.0-or-later' => 'https://www.gnu.org/licenses/gpl-3.0.en.html',
69
            'MIT' => 'https://opensource.org/licenses/MIT',
70
            'Apache-2.0' => 'https://www.apache.org/licenses/LICENSE-2.0',
71
            'BSD-3-Clause' => 'https://opensource.org/licenses/BSD-3-Clause'
72
        );
73
    }
74
75
    /**
76
     * Generates module files and folders
77
     * @param array $data
78
     * @return bool
79
     */
80
    public function generate(array $data)
81
    {
82
        $this->setData($data);
83
84
        $this->createMainClass();
85
        $this->createManifest();
86
        $this->createStructure();
87
88
        return $this->createZip();
89
    }
90
91
    /**
92
     * Create module manifest file
93
     */
94
    protected function createManifest()
95
    {
96
        $data = array(
97
            'name' => $this->data['module']['name'],
98
            'core' => $this->data['module']['core'],
99
            'author' => $this->data['module']['author'],
100
            'license' => $this->data['module']['license'],
101
            'version' => $this->data['module']['version'],
102
            'description' => $this->data['module']['description']
103
        );
104
105
        if (!empty($this->data['structure']) && in_array('configurable', $this->data['structure'])) {
106
            $data['configure'] = 'admin/module/settings/' . $this->data['module']['id'];
107
            $data['settings'] = array();
108
        }
109
110
        $json = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT);
111
        file_put_contents("$this->directory/module.json", $json);
112
    }
113
114
    /**
115
     * Creates various structure elements
116
     */
117
    protected function createStructure()
118
    {
119
        $this->write("$this->directory/README.md", 'readme');
120
        $this->write("$this->directory/.gitignore", 'gitignore');
121
        $this->write("$this->directory/composer.json", 'composer');
122
        $this->write("$this->directory/.scrutinizer.yml", 'scrutinizer');
123
124
        if (empty($this->data['structure'])) {
125
            return null;
126
        }
127
128
        foreach ($this->data['structure'] as $element) {
129
            switch ($element) {
130
                case 'controller':
131
                    $this->createStructureController();
132
                    break;
133
                case 'model':
134
                    $this->createStructureModel();
135
                    break;
136
                case 'helper':
137
                    $this->createStructureHelper();
138
                    break;
139
                case 'handler':
140
                    $this->createStructureHandler();
141
                    break;
142
                case 'override':
143
                    $this->createStructureOverride();
144
                    break;
145
                case 'template':
146
                    $this->createStructureTemplate();
147
                    break;
148
                case 'asset':
149
                    $this->createStructureAsset();
150
                    break;
151
                case 'locale':
152
                    $this->createStructureTranslation();
153
                    break;
154
                case 'tests':
155
                    $this->createStructureTests();
156
                    break;
157
                case 'config_files':
158
                    $this->createStructureConfigFiles();
159
                    break;
160
            }
161
        }
162
    }
163
164
    /**
165
     * Creates asset structure
166
     */
167
    protected function createStructureAsset()
168
    {
169
        foreach (array('css', 'js') as $folder) {
170
            if ($this->prepareFolder("$this->directory/$folder")) {
171
                $this->write("$this->directory/$folder/common.$folder", $folder);
172
            }
173
        }
174
175
        $this->generateImage();
176
    }
177
178
    /**
179
     * Generate an image sample
180
     * @return bool
181
     */
182
    protected function generateImage()
183
    {
184
        $directory = "$this->directory/image";
185
186
        if (!mkdir($directory, 0775, true)) {
187
            return false;
188
        }
189
190
        $im = imagecreate(100, 100);
191
        imagecolorallocate($im, 255, 255, 255);
192
        $text = imagecolorallocate($im, 0, 0, 255);
193
        imagestring($im, 5, 0, 0, $this->data['module']['name'], $text);
194
        $result = imagepng($im, "$directory/image.png");
195
        imagedestroy($im);
196
        return $result;
197
    }
198
199
    /**
200
     * Creates translations structure
201
     */
202
    protected function createStructureTranslation()
203
    {
204
        $folder = "$this->directory/translations";
205
206
        if ($this->prepareFolder($folder)) {
207
            $name = $this->data['module']['name'];
208
            gplcart_file_csv("$folder/en.csv", array($name, $name));
209
        }
210
    }
211
212
    /**
213
     * Creates a controller class
214
     */
215
    protected function createStructureController()
216
    {
217
        $folder = "$this->directory/controllers";
218
219
        if ($this->prepareFolder($folder)) {
220
            $this->write("$folder/Settings.php", 'controller');
221
        }
222
    }
223
224
    /**
225
     * Creates module main class
226
     */
227
    protected function createMainClass()
228
    {
229
        if ($this->prepareFolder($this->directory)) {
230
            $this->write("$this->directory/{$this->data['module']['class_name']}.php", 'main');
231
        }
232
    }
233
234
    /**
235
     * Creates a model class
236
     */
237
    protected function createStructureModel()
238
    {
239
        $folder = "$this->directory/models";
240
241
        if ($this->prepareFolder($folder)) {
242
            $this->write("$folder/{$this->data['module']['class_name']}.php", 'model');
243
        }
244
    }
245
246
    /**
247
     * Creates a helper class
248
     */
249
    protected function createStructureHelper()
250
    {
251
        $folder = "$this->directory/helpers";
252
253
        if ($this->prepareFolder($folder)) {
254
            $this->write("$folder/{$this->data['module']['class_name']}.php", 'helper');
255
        }
256
    }
257
258
    /**
259
     * Creates a handler class
260
     */
261
    protected function createStructureHandler()
262
    {
263
        $folder = "$this->directory/handlers";
264
265
        if ($this->prepareFolder($folder)) {
266
            $this->write("$folder/{$this->data['module']['class_name']}.php", 'handler');
267
        }
268
    }
269
270
    /**
271
     * Creates module overrides
272
     */
273
    protected function createStructureOverride()
274
    {
275
        $folder = "$this->directory/override/classes/modules/{$this->data['module']['id']}";
276
277
        if ($this->prepareFolder($folder)) {
278
            $this->write("$folder/{$this->data['module']['class_name']}Override.php", 'override');
279
        }
280
    }
281
282
    /**
283
     * Creates a template sample
284
     */
285
    protected function createStructureTemplate()
286
    {
287
        $folder = "$this->directory/templates";
288
289
        if ($this->prepareFolder($folder)) {
290
            $this->write("$folder/settings.php", 'template');
291
        }
292
    }
293
294
    /**
295
     * Creates files for unit testing
296
     */
297
    protected function createStructureTests()
298
    {
299
        $dir = "$this->directory/tests";
300
301
        if ($this->prepareFolder($dir)) {
302
            $this->prepareFolder("$dir/support");
303
            $this->write("$this->directory/phpunit.xml", 'test_xml');
304
            $this->write("$dir/support/bootstrap.php", 'test_bootstrap');
305
            $this->write("$dir/{$this->data['module']['class_name']}.php", 'test');
306
        }
307
    }
308
309
    /**
310
     * Creates config files structure
311
     */
312
    protected function createStructureConfigFiles()
313
    {
314
        $dir = "$this->directory/config";
315
316
        if ($this->prepareFolder($dir)) {
317
            $this->write("$dir/common.php", 'config');
318
        }
319
    }
320
321
    /**
322
     * Pack module folder into zip file
323
     * @return bool
324
     */
325
    protected function createZip()
326
    {
327
        $this->file = "$this->directory.zip";
328
329
        if (is_file($this->file)) {
330
            unlink($this->file);
331
        }
332
333
        $result = $this->zip->directory($this->directory, $this->file, $this->data['module']['id']);
334
        gplcart_file_delete_recursive($this->directory);
335
        return $result;
336
    }
337
338
    /**
339
     * Returns a path to zip file
340
     * @return string
341
     */
342
    public function getZip()
343
    {
344
        return $this->file;
345
    }
346
347
    /**
348
     * Recursively creates folders
349
     * @param string $folder
350
     * @return bool
351
     */
352
    protected function prepareFolder($folder)
353
    {
354
        return !file_exists($folder) && mkdir($folder, 0775, true);
355
    }
356
357
    /**
358
     * Prepares an array of data before rendering
359
     * @param array $data
360
     * @return array
361
     */
362
    protected function setData(array &$data)
363
    {
364
        $licenses = $this->getLicenses();
365
        $class = $this->module->getClass($data['module']['id']);
366
367
        $data['module']['namespace'] = $class;
368
        $data['module']['class_name'] = substr($class, strrpos($class, '\\') + 1);
369
        $data['module']['license_url'] = $licenses[$data['module']['license']] . ' ' . $data['module']['license'];
370
371
        $this->directory = gplcart_file_private_module('skeleton', $data['module']['id'], true);
372
        return $this->data = $data;
373
    }
374
375
    /**
376
     * Renders a template
377
     * @param string $template
378
     * @return string|null
379
     */
380
    protected function render($template)
381
    {
382
        $file = GC_DIR_MODULE . "/skeleton/templates/code/$template.php";
383
384
        if (!is_file($file)) {
385
            return null;
386
        }
387
388
        extract($this->data, EXTR_SKIP);
389
        ob_start();
390
        include $file;
391
        return ob_get_clean();
392
    }
393
394
    /**
395
     * Writes to a file using a template as an source
396
     * @param string $file
397
     * @param string $template
398
     * @return null|bool
399
     */
400
    protected function write($file, $template)
401
    {
402
        $content = $this->render($template);
403
404
        if (!isset($content)) {
405
            return null;
406
        }
407
408
        if (pathinfo($file, PATHINFO_EXTENSION) === 'php') {
409
            $content = "<?php\n\n$content";
410
        }
411
412
        return file_put_contents($file, $content) !== false;
413
    }
414
415
}
416