Completed
Push — master ( ca7128...04ca2c )
by Iurii
02:48
created

Generator::setData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

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