Completed
Push — master ( 00c11c...0014e4 )
by Iurii
01:57
created

Generator::createStructureAsset()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.2
c 0
b 0
f 0
cc 4
eloc 6
nc 4
nop 2
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
     * Constructor
80
     * @param ZipHelper $zip
81
     */
82
    public function __construct(ZipHelper $zip)
83
    {
84
        parent::__construct();
85
86
        $this->zip = $zip;
87
    }
88
89
    /**
90
     * Returns an array of licenses and their URLs
91
     * @return array
92
     */
93
    public function getLicenses()
94
    {
95
        return array(
96
            'GNU General Public License 3.0' => 'https://www.gnu.org/licenses/gpl-3.0.en.html',
97
            'MIT License' => 'https://opensource.org/licenses/MIT',
98
            'Apache License 2.0' => 'https://www.apache.org/licenses/LICENSE-2.0',
99
            '3-Clause BSD License' => 'https://opensource.org/licenses/BSD-3-Clause',
100
            'GNU Lesser General Public License' => 'https://www.gnu.org/licenses/lgpl-3.0.en.html'
101
        );
102
    }
103
104
    /**
105
     * Generates module files and folders
106
     * @param array $data
107
     */
108
    public function generate(array $data)
109
    {
110
        $this->prepareData($data);
111
112
        $folder = $this->getModuleFolder($data['module']['id']);
113
        $this->createMainClass($folder, $data);
114
115
        if (!empty($data['structure'])) {
116
            $this->createStructure($folder, $data);
117
        }
118
119
        return $this->createZip($folder, $data);
120
    }
121
122
    /**
123
     * Creates various structure elements
124
     * @param string $folder
125
     * @param array $data
126
     */
127
    protected function createStructure($folder, array $data)
128
    {
129
        foreach ($data['structure'] as $element) {
130
            switch ($element) {
131
                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...
132
                    $this->createStructureController($folder, $data);
133
                    break;
134
                case 'model':
135
                    $this->createStructureModel($folder, $data);
136
                    break;
137
                case 'helper':
138
                    $this->createStructureHelper($folder, $data);
139
                    break;
140
                case 'handler':
141
                    $this->createStructureHandler($folder, $data);
142
                    break;
143
                case 'override':
144
                    $this->createStructureOverride($folder, $data);
145
                    break;
146
                case 'template':
147
                    $this->createStructureTemplate($folder, $data);
148
                    break;
149
                case 'asset':
150
                    $this->createStructureAsset($folder, $data);
151
                    break;
152
            }
153
        }
154
    }
155
156
    /**
157
     * Creates asset structure
158
     * @param string $folder
159
     * @param array $data
160
     */
161
    protected function createStructureAsset($folder, array $data)
162
    {
163
        $subfolders = array(self::FOLDER_CSS, self::FOLDER_JS, self::FOLDER_IMAGE);
164
        foreach ($subfolders as $subfolder) {
165
            if ($this->prepareFolder("$folder/$subfolder")) {
166
                $filename = $subfolder == self::FOLDER_IMAGE ? 'image.png' : "common.$subfolder";
167
                $this->write("$folder/$subfolder/$filename", $subfolder, $data, false);
168
            }
169
        }
170
    }
171
172
    /**
173
     * Creates a controller class
174
     * @param string $folder
175
     * @param array $data
176
     */
177
    protected function createStructureController($folder, array $data)
178
    {
179
        $folder .= '/' . self::FOLDER_CONTROLLER;
180
        if ($this->prepareFolder($folder)) {
181
            $this->write("$folder/Settings.php", 'controller', $data);
182
        }
183
    }
184
185
    /**
186
     * Cretates module main class
187
     * @param string $folder
188
     * @param array $data
189
     * @return boolean
190
     */
191
    protected function createMainClass($folder, array $data)
192
    {
193
        if ($this->prepareFolder($folder)) {
194
            $this->write("$folder/{$data['module']['class_name']}.php", 'main', $data);
195
        }
196
    }
197
198
    /**
199
     * Creates a model class
200
     * @param string $folder
201
     * @param array $data
202
     */
203
    protected function createStructureModel($folder, array $data)
204
    {
205
        $folder .= '/' . self::FOLDER_MODEL;
206
        if ($this->prepareFolder($folder)) {
207
            $this->write("$folder/{$data['module']['class_name']}.php", 'model', $data);
208
        }
209
    }
210
211
    /**
212
     * Creates a helper class
213
     * @param string $folder
214
     * @param array $data
215
     */
216
    protected function createStructureHelper($folder, array $data)
217
    {
218
        $folder .= '/' . self::FOLDER_HELPER;
219
        if ($this->prepareFolder($folder)) {
220
            $this->write("$folder/{$data['module']['class_name']}.php", 'helper', $data);
221
        }
222
    }
223
224
    /**
225
     * Creates a handler class
226
     * @param string $folder
227
     * @param array $data
228
     */
229
    protected function createStructureHandler($folder, array $data)
230
    {
231
        $folder .= '/' . self::FOLDER_HANDLER;
232
        if ($this->prepareFolder($folder)) {
233
            $this->write("$folder/{$data['module']['class_name']}.php", 'handler', $data);
234
        }
235
    }
236
237
    /**
238
     * Creates module overrides
239
     * @param string $folder
240
     * @param array $data
241
     */
242
    protected function createStructureOverride($folder, array $data)
243
    {
244
        $folder .= '/' . self::FOLDER_OVERRIDE . "/modules/{$data['module']['id']}";
245
        if ($this->prepareFolder($folder)) {
246
            $this->write("$folder/{$data['module']['class_name']}Override.php", 'override', $data);
247
        }
248
    }
249
250
    /**
251
     * Creates a template sample
252
     * @param string $folder
253
     * @param array $data
254
     */
255
    protected function createStructureTemplate($folder, array $data)
256
    {
257
        $folder .= '/' . self::FOLDER_TEMPLATE;
258
        if ($this->prepareFolder($folder)) {
259
            $this->write("$folder/settings.php", 'template', $data);
260
        }
261
    }
262
263
    /**
264
     * Pack module folder into zip file
265
     * @param string $folder
266
     * @param array $data
267
     * @return bool
268
     */
269
    protected function createZip($folder, array $data)
270
    {
271
        $this->file = "$folder.zip";
272
        $result = $this->zip->folder("$folder/*", $this->file, $data['module']['id']);
273
        gplcart_file_delete_recursive($folder);
274
        return $result;
275
    }
276
277
    /**
278
     * Returns a path to zip file
279
     * @return string
280
     */
281
    public function getZip()
282
    {
283
        return $this->file;
284
    }
285
286
    /**
287
     * Returns a full path to the module folder
288
     * @param integer $module_id
289
     * @return string
290
     */
291
    protected function getModuleFolder($module_id)
292
    {
293
        return GC_PRIVATE_DOWNLOAD_DIR . "/$module_id";
294
    }
295
296
    /**
297
     * Recursively creates folders
298
     * @param string $folder
299
     * @return boolean
300
     */
301
    protected function prepareFolder($folder)
302
    {
303
        return (!file_exists($folder) && mkdir($folder, 0775, true));
304
    }
305
306
    /**
307
     * Prepares an array of data before rendering
308
     * @param array $data
309
     * @return string
310
     */
311
    protected function prepareData(array &$data)
312
    {
313
        $licenses = $this->getLicenses();
314
315
        $data['module']['class_name'] = $this->config->getModuleClassName($data['module']['id']);
316
        $data['module']['namespace'] = $this->config->getModuleClassNamespace($data['module']['id']);
317
        $data['module']['license_url'] = $licenses[$data['module']['license']] . ' ' . $data['module']['license'];
318
        return $data;
319
    }
320
321
    /**
322
     * Renders a template
323
     * @param string $template
324
     * @param array $data
325
     * @return string|null
326
     */
327
    protected function render($template, array $data)
328
    {
329
        $file = GC_MODULE_DIR . "/skeleton/templates/$template.php";
330
331
        if (!is_readable($file)) {
332
            return null;
333
        }
334
335
        extract($data, EXTR_SKIP);
336
        ob_start();
337
        include $file;
338
        return ob_get_clean();
339
    }
340
341
    /**
342
     * Writes to a file using a template as an source
343
     * @param string $file
344
     * @param string $template
345
     * @param array $data
346
     * @param bool $php
347
     * @return null
348
     */
349
    protected function write($file, $template, array $data, $php = true)
350
    {
351
        $content = $this->render($template, $data);
352
353
        if (!isset($content)) {
354
            return null;
355
        }
356
357
        if ($php) {
358
            $content = "<?php\n\n$content";
359
        }
360
361
        file_put_contents($file, $content);
362
    }
363
364
}
365