Passed
Push — master ( 1e46f8...619c15 )
by Fran
03:40 queued 28s
created

GeneratorService::generatePropertiesTemplate()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 13
nc 1
nop 3
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
1
<?php
2
namespace PSFS\Services;
3
4
use PSFS\base\Cache;
5
use PSFS\base\config\Config;
6
use PSFS\base\exception\ConfigException;
7
use PSFS\base\Service;
8
9
class GeneratorService extends Service
10
{
11
    /**
12
     * @Inyectable
13
     * @var \PSFS\base\config\Config Servicio de configuración
14
     */
15
    protected $config;
16
    /**
17
     * @Inyectable
18
     * @var \PSFS\base\Security Servicio de autenticación
19
     */
20
    protected $security;
21
    /**
22
     * @Inyectable
23
     * @var \PSFS\base\Template Servicio de gestión de plantillas
24
     */
25
    protected $tpl;
26
27
    /**
28
     * Método que revisa las traducciones directorio a directorio
29
     * @param $path
30
     * @param $locale
31
     * @return array
32
     */
33
    public static function findTranslations($path, $locale)
34
    {
35
        $locale_path = realpath(BASE_DIR . DIRECTORY_SEPARATOR . 'locale');
36
        $locale_path .= DIRECTORY_SEPARATOR . $locale . DIRECTORY_SEPARATOR . 'LC_MESSAGES' . DIRECTORY_SEPARATOR;
37
38
        $translations = array();
39
        if (file_exists($path)) {
40
            $d = dir($path);
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $d. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
41
            while (false !== ($dir = $d->read())) {
42
                Config::createDir($locale_path);
43
                if (!file_exists($locale_path . 'translations.po')) {
44
                    file_put_contents($locale_path . 'translations.po', '');
45
                }
46
                $inspect_path = realpath($path . DIRECTORY_SEPARATOR . $dir);
47
                $cmd_php = "export PATH=\$PATH:/opt/local/bin; xgettext " .
48
                    $inspect_path . DIRECTORY_SEPARATOR .
49
                    "*.php --from-code=UTF-8 -j -L PHP --debug --force-po -o {$locale_path}translations.po";
50
                if (is_dir($path . DIRECTORY_SEPARATOR . $dir) && preg_match('/^\./', $dir) == 0) {
51
                    $res = _('Revisando directorio: ') . $inspect_path;
52
                    $res .= _('Comando ejecutado: ') . $cmd_php;
53
                    $res .= shell_exec($cmd_php);
54
                    usleep(10);
55
                    $translations[] = $res;
56
                    $translations = array_merge($translations, self::findTranslations($inspect_path, $locale));
57
                }
58
            }
59
        }
60
        return $translations;
61
    }
62
63
    /**
64
     * Servicio que genera la estructura de un módulo o lo actualiza en caso de ser necesario
65
     * @param string $module
66
     * @param boolean $force
67
     * @param string $type
68
     * @param boolean $isModule
69
     * @return mixed
70
     */
71
    public function createStructureModule($module, $force = false, $type = "", $isModule = false)
72
    {
73
        $mod_path = CORE_DIR . DIRECTORY_SEPARATOR;
74
        $module = ucfirst($module);
75
        $this->createModulePath($module, $mod_path, $isModule);
76
        $this->createModulePathTree($module, $mod_path, $isModule);
77
        $this->createModuleBaseFiles($module, $mod_path, $force, $type, $isModule);
78
        $this->createModuleModels($module, $mod_path, $isModule);
79
        $this->generateBaseApiTemplate($module, $mod_path, $force, $isModule);
80
        //Redireccionamos al home definido
81
        $this->log->infoLog("Módulo generado correctamente");
82
    }
83
84
    /**
85
     * Service that creates the root paths for the modules
86
     * @param string $module
87
     * @param string $mod_path
88
     * @param boolean $isModule
89
     */
90
    private function createModulePath($module, $mod_path, $isModule = false)
91
    {
92
        // Creates the src folder
93
        Config::createDir($mod_path);
94
        // Create module path
95
        if (false === $isModule) {
96
            Config::createDir($mod_path . $module);
97
        }
98
    }
99
100
    /**
101
     * Servicio que genera la estructura base
102
     * @param $module
103
     * @param $mod_path
104
     * @param boolean $isModule
105
     */
106
    private function createModulePathTree($module, $mod_path, $isModule = false)
107
    {
108
        //Creamos las carpetas CORE del módulo
109
        $this->log->infoLog("Generamos la estructura");
110
        $paths = [
111
            "Api", "Api/base", "Config", "Controller", "Form", "Models", "Public", "Templates", "Services", "Test"
112
        ];
113
        $module_path = $isModule ? $mod_path : $mod_path . $module;
114
        foreach ($paths as $path) {
115
            Config::createDir($module_path . DIRECTORY_SEPARATOR . $path);
116
        }
117
        //Creamos las carpetas de los assets
118
        $htmlPaths = array("css", "js", "img", "media", "font");
119
        foreach ($htmlPaths as $path) {
120
            Config::createDir($module_path . DIRECTORY_SEPARATOR . "Public" . DIRECTORY_SEPARATOR . $path);
121
        }
122
123
        if ($isModule) {
124
            return $this->writeTemplateToFile(json_encode([
125
                "module" => "\\" . preg_replace('/(\\\|\/)/', '\\\\', $module),
126
            ], JSON_PRETTY_PRINT), $mod_path . DIRECTORY_SEPARATOR . "module.json", true);
127
        }
128
    }
129
130
    /**
131
     * Servicio que genera las plantillas básicas de ficheros del módulo
132
     * @param string $module
133
     * @param string $mod_path
134
     * @param boolean $force
135
     * @param string $controllerType
136
     * @param boolean $isModule
137
     */
138
    private function createModuleBaseFiles($module, $mod_path, $force = false, $controllerType = '', $isModule = false)
139
    {
140
        $module_path = $isModule ? $mod_path : $mod_path . $module;
141
        $this->generateControllerTemplate($module, $module_path, $force, $controllerType);
142
        $this->generateServiceTemplate($module, $module_path, $force);
143
        $this->genereateAutoloaderTemplate($module, $module_path, $force, $isModule);
144
        $this->generateSchemaTemplate($module, $module_path, $force);
145
        $this->generatePropertiesTemplate($module, $module_path, $force);
146
        $this->generateConfigTemplate($module_path, $force);
147
        $this->generateIndexTemplate($module, $module_path, $force);
148
        $this->generatePublicTemplates($module_path, $force);
149
    }
150
151
    /**
152
     * Servicio que ejecuta Propel y genera el modelo de datos
153
     * @param string $module
154
     * @param string $path
155
     * @param boolean $isModule
156
     */
157
    private function createModuleModels($module, $path, $isModule = false)
158
    {
159
        $module_path = $isModule ? $path : $path . $module;
160
        $module_path = str_replace(CORE_DIR . DIRECTORY_SEPARATOR, '', $module_path);
161
        //Generamos las clases de propel y la configuración
162
        $exec = "export PATH=\$PATH:/opt/local/bin; " . BASE_DIR . DIRECTORY_SEPARATOR .
163
            "vendor" . DIRECTORY_SEPARATOR . "bin" . DIRECTORY_SEPARATOR . "propel ";
164
        $schemaOpt = " --schema-dir=" . CORE_DIR . DIRECTORY_SEPARATOR . $module_path .
165
            DIRECTORY_SEPARATOR . "Config";
166
        $opt = " --config-dir=" . CORE_DIR . DIRECTORY_SEPARATOR . $module_path . DIRECTORY_SEPARATOR .
167
            "Config --output-dir=" . CORE_DIR . " --verbose";
168
        $this->log->infoLog("[GENERATOR] Ejecutamos propel:\n" . $exec . "build" . $opt . $schemaOpt);
169
        $ret = shell_exec($exec . "build" . $opt . $schemaOpt);
170
171
        $this->log->infoLog("[GENERATOR] Generamos clases invocando a propel:\n $ret");
172
        $ret = shell_exec($exec . "sql:build" . $opt . " --output-dir=" . CORE_DIR . DIRECTORY_SEPARATOR .
173
            $module_path . DIRECTORY_SEPARATOR . "Config" . $schemaOpt);
174
        $this->log->infoLog("[GENERATOR] Generamos sql invocando a propel:\n $ret");
175
        $ret = shell_exec($exec . "config:convert" . $opt . " --output-dir=" . CORE_DIR . DIRECTORY_SEPARATOR .
176
            $module_path . DIRECTORY_SEPARATOR . "Config");
177
        $this->log->infoLog("[GENERATOR] Generamos configuración invocando a propel:\n $ret");
178
    }
179
180
    /**
181
     * @param string $module
182
     * @param string $mod_path
183
     * @param boolean $force
184
     * @param string $controllerType
185
     * @return boolean
186
     */
187
    private function generateControllerTemplate($module, $mod_path, $force = false, $controllerType = "")
188
    {
189
        //Generamos el controlador base
190
        $this->log->infoLog("Generamos el controlador BASE");
191
        $class = preg_replace('/(\\\|\/)/', '', $module);
192
        $controllerBody = $this->tpl->dump("generator/controller.template.twig", array(
193
            "module" => $module,
194
            "namespace" => preg_replace('/(\\\|\/)/', '\\', $module),
195
            "url" => preg_replace('/(\\\|\/)/', '/', $module),
196
            "class" => $class,
197
            "controllerType" => $class . "Base",
198
            "is_base" => false
199
        ));
200
        $controller = $this->writeTemplateToFile($controllerBody, $mod_path . DIRECTORY_SEPARATOR . "Controller" .
201
            DIRECTORY_SEPARATOR . "{$class}Controller.php", $force);
202
203
        $controllerBody = $this->tpl->dump("generator/controller.template.twig", array(
204
            "module" => $module,
205
            "namespace" => preg_replace('/(\\\|\/)/', '\\', $module),
206
            "url" => preg_replace('/(\\\|\/)/', '/', $module),
207
            "class" => $class . "Base",
208
            "service" => $class,
209
            "controllerType" => $controllerType,
210
            "is_base" => true
211
        ));
212
        $controllerBase = $this->writeTemplateToFile($controllerBody, $mod_path . DIRECTORY_SEPARATOR . "Controller" .
213
            DIRECTORY_SEPARATOR . "base" . DIRECTORY_SEPARATOR . "{$class}BaseController.php", true);
214
        return ($controller && $controllerBase);
215
    }
216
217
    /**
218
     * @param string $module
219
     * @param string $mod_path
220
     * @param boolean $force
221
     * @param boolean $isModule
222
     * @return boolean
223
     */
224
    private function generateBaseApiTemplate($module, $mod_path, $force = false, $isModule = false)
225
    {
226
        $created = true;
227
        $modelPath = $isModule ?
228
            $mod_path . DIRECTORY_SEPARATOR . 'Models' :
229
            $mod_path . $module . DIRECTORY_SEPARATOR . 'Models';
230
        $api_path = $isModule ?
231
            $mod_path . DIRECTORY_SEPARATOR . 'Api' :
232
            $mod_path . $module . DIRECTORY_SEPARATOR . 'Api';
233
        if (file_exists($modelPath)) {
234
            $dir = dir($modelPath);
235
            while ($file = $dir->read()) {
236
                if (!in_array($file, array('.', '..'))
237
                    && !preg_match('/Query\.php$/i', $file)
238
                    && preg_match('/\.php$/i', $file)
239
                ) {
240
                    $filename = str_replace(".php", "", $file);
241
                    $this->log->infoLog("Generamos Api BASES para {$filename}");
242
                    $this->createApiBaseFile($module, $api_path, $filename);
243
                    $this->createApi($module, $api_path, $force, $filename);
244
                }
245
            }
246
        }
247
        return $created;
248
    }
249
250
    /**
251
     * @param string $mod_path
252
     * @param boolean $force
253
     * @return boolean
254
     */
255
    private function generateConfigTemplate($mod_path, $force = false)
256
    {
257
        //Generamos el fichero de configuración
258
        $this->log->infoLog("Generamos fichero vacío de configuración");
259
        return $this->writeTemplateToFile("<?php\n\t",
260
            $mod_path . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . "config.php",
261
            $force);
262
    }
263
264
    /**
265
     * @param string $mod_path
266
     * @param string $mod_path
267
     * @param boolean $force
268
     * @return boolean
269
     */
270
    private function generatePublicTemplates($mod_path, $force = false)
271
    {
272
        //Generamos el fichero de configuración
273
        $this->log->infoLog("Generamos ficheros para assets base");
274
        $css = $this->writeTemplateToFile("/* CSS3 STYLES */\n\n",
275
            $mod_path . DIRECTORY_SEPARATOR . "Public" . DIRECTORY_SEPARATOR . "css" . DIRECTORY_SEPARATOR . "styles.css",
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 122 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
276
            $force);
277
        $js = $this->writeTemplateToFile("/* APP MODULE JS */\n\n(function() {\n\t'use strict';\n})();",
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $js. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
278
            $mod_path . DIRECTORY_SEPARATOR . "Public" . DIRECTORY_SEPARATOR . "js" . DIRECTORY_SEPARATOR . "app.js",
279
            $force);
280
        return ($css && $js);
281
    }
282
283
    /**
284
     * @param string $module
285
     * @param string $mod_path
286
     * @param boolean $force
287
     * @return boolean
288
     */
289
    private function generateServiceTemplate($module, $mod_path, $force = false)
290
    {
291
        //Generamos el controlador base
292
        $this->log->infoLog("Generamos el servicio BASE");
293
        $class = preg_replace('/(\\\|\/)/', '', $module);
294
        $controller = $this->tpl->dump("generator/service.template.twig", array(
295
            "module" => $module,
296
            "namespace" => preg_replace('/(\\\|\/)/', '\\', $module),
297
            "class" => $class,
298
        ));
299
        return $this->writeTemplateToFile($controller,
300
            $mod_path . DIRECTORY_SEPARATOR . "Services" . DIRECTORY_SEPARATOR . "{$class}Service.php",
301
            $force);
302
    }
303
304
    /**
305
     * @param string $module
306
     * @param string $mod_path
307
     * @param boolean $force
308
     * @param boolean $isModule
309
     * @return boolean
310
     */
311
    private function genereateAutoloaderTemplate($module, $mod_path, $force = false, $isModule = false)
312
    {
313
        //Generamos el autoloader del módulo
314
        $this->log->infoLog("Generamos el autoloader");
315
        $autoloader = $this->tpl->dump("generator/autoloader.template.twig", array(
316
            "module" => $module,
317
            "autoloader" => preg_replace('/(\\\|\/)/', '_', $module),
318
            "regex" => preg_replace('/(\\\|\/)/m', '\\\\\\\\\\\\', $module),
319
            "is_module" => $isModule,
320
        ));
321
        return $this->writeTemplateToFile($autoloader, $mod_path . DIRECTORY_SEPARATOR . "autoload.php", $force);
322
    }
323
324
    /**
325
     * @param string $module
326
     * @param string $mod_path
327
     * @param boolean $force
328
     * @return boolean
329
     */
330
    private function generateSchemaTemplate($module, $mod_path, $force = false)
331
    {
332
        //Generamos el autoloader del módulo
333
        $this->log->infoLog("Generamos el schema");
334
        $schema = $this->tpl->dump("generator/schema.propel.twig", array(
335
            "module" => $module,
336
            "namespace" => preg_replace('/(\\\|\/)/', '', $module),
337
            "prefix" => preg_replace('/(\\\|\/)/', '', $module),
338
            "db" => $this->config->get("db_name"),
339
        ));
340
        return $this->writeTemplateToFile($schema,
341
            $mod_path . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . "schema.xml",
342
            $force);
343
    }
344
345
    /**
346
     * @param string $module
347
     * @param string $mod_path
348
     * @param boolean $force
349
     * @return boolean
350
     */
351
    private function generatePropertiesTemplate($module, $mod_path, $force = false)
352
    {
353
        $this->log->infoLog("Generamos la configuración de Propel");
354
        $build_properties = $this->tpl->dump("generator/build.properties.twig", array(
355
            "module" => $module,
356
            "host" => $this->config->get("db_host"),
357
            "port" => $this->config->get("db_port"),
358
            "user" => $this->config->get("db_user"),
359
            "pass" => $this->config->get("db_password"),
360
            "db" => $this->config->get("db_name"),
361
            "namespace" => preg_replace('/(\\\|\/)/', '', $module),
362
        ));
363
        return $this->writeTemplateToFile($build_properties,
364
            $mod_path . DIRECTORY_SEPARATOR . "Config" . DIRECTORY_SEPARATOR . "propel.yml",
365
            $force);
366
    }
367
368
    /**
369
     * @param string $module
370
     * @param string $mod_path
371
     * @param boolean $force
372
     * @return boolean
373
     */
374
    private function generateIndexTemplate($module, $mod_path, $force = false)
375
    {
376
        //Generamos la plantilla de index
377
        $this->log->infoLog("Generamos una plantilla base por defecto");
378
        $index = $this->tpl->dump("generator/index.template.twig", array(
379
            "module" => $module,
380
        ));
381
        return $this->writeTemplateToFile($index,
382
            $mod_path . DIRECTORY_SEPARATOR . "Templates" . DIRECTORY_SEPARATOR . "index.html.twig",
383
            $force);
384
    }
385
386
    /**
387
     * Método que graba el contenido de una plantilla en un fichero
388
     * @param string $fileContent
389
     * @param string $filename
390
     * @param boolean $force
391
     * @return boolean
392
     */
393
    private function writeTemplateToFile($fileContent, $filename, $force = false)
394
    {
395
        $created = false;
396
        if ($force || !file_exists($filename)) {
397
            try {
398
                $this->cache->storeData($filename, $fileContent, Cache::TEXT, true);
399
                $created = true;
400
            } catch (\Exception $e) {
401
                $this->log->errorLog($e->getMessage());
402
            }
403
        } else {
404
            $this->log->errorLog($filename . _(' not exists or cant write'));
405
        }
406
        return $created;
407
    }
408
409
    /**
410
     * Create ApiBase
411
     * @param string $module
412
     * @param string $mod_path
413
     * @param string $api
414
     *
415
     * @return bool
416
     */
417
    private function createApiBaseFile($module, $mod_path, $api)
418
    {
419
        $class = preg_replace('/(\\\|\/)/', '', $module);
420
        $controller = $this->tpl->dump("generator/api.base.template.twig", array(
421
            "module" => $module,
422
            "api" => $api,
423
            "namespace" => preg_replace('/(\\\|\/)/', '\\', $module),
424
            "url" => preg_replace('/(\\\|\/)/', '/', $module),
425
            "class" => $class,
426
        ));
427
428
        return $this->writeTemplateToFile($controller,
429
            $mod_path . DIRECTORY_SEPARATOR . 'base' . DIRECTORY_SEPARATOR . "{$api}BaseApi.php", true);
430
    }
431
432
    /**
433
     * Create Api
434
     * @param string $module
435
     * @param string $mod_path
436
     * @param bool $force
437
     * @param string $api
438
     *
439
     * @return bool
440
     */
441
    private function createApi($module, $mod_path, $force, $api)
442
    {
443
        $class = preg_replace('/(\\\|\/)/', '', $module);
444
        $controller = $this->tpl->dump("generator/api.template.twig", array(
445
            "module" => $module,
446
            "api" => $api,
447
            "namespace" => preg_replace('/(\\\|\/)/', '\\', $module),
448
            "url" => preg_replace('/(\\\|\/)/', '/', $module),
449
            "class" => $class,
450
        ));
451
452
        return $this->writeTemplateToFile($controller, $mod_path . DIRECTORY_SEPARATOR . "{$api}.php", $force);
453
    }
454
455
    /**
456
     * Method that copy resources recursively
457
     * @param string $dest
458
     * @param boolean $force
459
     * @param $filename_path
460
     * @param boolean $debug
461
     */
462
    public static function copyResources($dest, $force, $filename_path, $debug)
463
    {
464
        if (file_exists($filename_path)) {
465
            $destfolder = basename($filename_path);
466
            if (!file_exists(WEB_DIR . $dest . DIRECTORY_SEPARATOR . $destfolder) || $debug || $force) {
467
                if (is_dir($filename_path)) {
468
                    self::copyr($filename_path, WEB_DIR . $dest . DIRECTORY_SEPARATOR . $destfolder);
469
                } else {
470
                    if (@copy($filename_path, WEB_DIR . $dest . DIRECTORY_SEPARATOR . $destfolder) === FALSE) {
471
                        throw new ConfigException("Can't copy " . $filename_path . " to " . WEB_DIR . $dest . DIRECTORY_SEPARATOR . $destfolder);
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 145 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
472
                    }
473
                }
474
            }
475
        }
476
    }
477
478
    /**
479
     * Method that copy a resource
480
     * @param string $src
481
     * @param string $dst
482
     * @throws ConfigException
483
     */
484
    public static function copyr($src, $dst)
485
    {
486
        $dir = opendir($src);
487
        Config::createDir($dst);
488
        while (false !== ($file = readdir($dir))) {
489
            if (($file != '.') && ($file != '..')) {
490
                if (is_dir($src . '/' . $file)) {
491
                    self::copyr($src . '/' . $file, $dst . '/' . $file);
492
                } elseif (@copy($src . '/' . $file, $dst . '/' . $file) === false) {
493
                    throw new ConfigException("Can't copy " . $src . " to " . $dst);
494
                }
495
            }
496
        }
497
        closedir($dir);
498
    }
499
}
500