Passed
Push — master ( 6ce89b...2955c9 )
by Fran
03:38
created

Admin::getTranslations()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
eloc 12
nc 2
nop 1
dl 0
loc 21
rs 9.3142
c 0
b 0
f 0
ccs 0
cts 13
cp 0
crap 6
1
<?php
2
3
namespace PSFS\controller;
4
5
use PSFS\base\config\AdminForm;
6
use PSFS\base\config\Config;
7
use PSFS\base\config\ConfigForm;
8
use PSFS\base\config\LoginForm;
9
use PSFS\base\config\ModuleForm;
10
use PSFS\base\exception\ConfigException;
11
use PSFS\base\Logger;
12
use PSFS\base\Router;
13
use PSFS\base\Security;
14
use PSFS\base\Template;
15
use PSFS\base\types\AuthAdminController;
16
use PSFS\Services\GeneratorService;
17
18
/**
19
 * Class Admin
20
 * @package PSFS\controller
21
 * @domain ROOT
22
 */
23
class Admin extends AuthAdminController{
24
25
    const DOMAIN = 'ROOT';
26
27
    /**
28
     * @Inyectable
29
     * @var \PSFS\base\config\Config Servicio de configuración
30
     */
31
    protected $config;
32
    /**
33
     * @Inyectable
34
     * @var \PSFS\services\AdminServices Servicios de administración
35
     */
36
    protected $srv;
37
    /**
38
     * @Inyectable
39
     * @var  \PSFS\services\GeneratorService Servicio de generación de estructura de directorios
40
     */
41
    protected $gen;
42
43
    /**
44
     * Wrapper de asignación de los menus
45
     * @return array
46
     */
47
    protected function getMenu() {
48
        return Router::getInstance()->getAdminRoutes();
49
    }
50
51
    /**
52
     * Método que gestiona los usuarios administradores de la plataforma
53
     * @GET
54
     * @route /admin/setup
55
     * @return string|null
56
     * @throws \HttpException
57
     */
58
    public function adminers() {
59
        $admins = $this->srv->getAdmins();
60
        $form = new AdminForm();
61
        $form->build();
62
        return $this->render('admin.html.twig', array(
63
            'admins' => $admins,
64
            'form' => $form,
65
            'profiles' => Security::getProfiles(),
66
        ));
67
    }
68
69
    /**
70
     * Servicio que guarda los usuarios de administración
71
     * @POST
72
     * @route /admin/setup
73
     * @visible false
74
     * @return string|void
75
     * @throws \HttpException
76
     */
77
    public function setAdminUsers() {
78
        $admins = $this->srv->getAdmins();
79
        $form = new AdminForm();
80
        $form->build();
81
        $form->hydrate();
82
        if ($form->isValid()) {
83
            if (Security::save($form->getData())) {
84
                Logger::log('Configuration saved successful');
85
                $this->security->setFlash("callback_message", _("Usuario agregado correctamente"));
86
                $this->security->setFlash("callback_route", $this->getRoute("admin"), true);
87
            } else {
88
                throw new ConfigException(_('Error al guardar los administradores, prueba a cambiar los permisos'));
89
            }
90
        }
91
        return $this->render('admin.html.twig', array(
92
            'admins' => $admins,
93
            'form' => $form,
94
            'profiles' => Security::getProfiles(),
95
        ));
96
    }
97
98
    /**
99
     * Acción que pinta un formulario genérico de login pra la zona restringida
100
     * @param string $route
101
     * @GET
102
     * @route /admin/login
103
     * @visible false
104
     * @return string HTML
105
     */
106
    public function adminLogin($route = null) {
107
        return Admin::staticAdminLogon($route);
108
    }
109
110
    /**
111
     * Método estático de login de administrador
112
     * @param string $route
113
     * @return string HTML
114
     * @throws \PSFS\base\exception\FormException
115
     */
116
    public static function staticAdminLogon($route = null) {
117
        $form = new LoginForm();
118
        $form->setData(array("route" => $route));
119
        $form->build();
120
        $tpl = Template::getInstance();
121
        $tpl->setPublicZone(true);
122
        return $tpl->render("login.html.twig", array(
123
            'form' => $form,
124
        ));
125
    }
126
127
    /**
128
     * Servicio que valida el login
129
     * @param null $route
130
     * @POST
131
     * @visible false
132
     * @route /admin/login
133
     * @return string
134
     * @throws \PSFS\base\exception\FormException
135
     */
136
    public function postLogin($route = null) {
137
        $form = new LoginForm();
138
        $form->setData(array("route" => $route));
139
        $form->build();
140
        $tpl = Template::getInstance();
141
        $tpl->setPublicZone(true);
142
        $template = "login.html.twig";
143
        $params = array(
144
            'form' => $form,
145
        );
146
        $cookies = array();
147
        $form->hydrate();
148
        if ($form->isValid()) {
149
            if (Security::getInstance()->checkAdmin($form->getFieldValue("user"), $form->getFieldValue("pass"))) {
150
                $cookies = array(
151
                    array(
152
                        "name" => Security::getInstance()->getHash(),
153
                        "value" => base64_encode($form->getFieldValue("user") . ":" . $form->getFieldValue("pass")),
154
                        "expire" => time() + 3600,
155
                        "http" => true,
156
                    )
157
                );
158
                $template = "redirect.html.twig";
159
                $params = array(
160
                    'route' => $form->getFieldValue("route"),
161
                    'status_message' => _("Acceso permitido... redirigiendo!!"),
162
                    'delay' => 1,
163
                );
164
            } else {
165
                $form->setError("user", _("El usuario no tiene acceso a la web"));
166
            }
167
        }
168
        return $tpl->render($template, $params, $cookies);
169
    }
170
171
    /**
172
     * Método que recorre los directorios para extraer las traducciones posibles
173
     * @GET
174
     * @param $locale string
175
     * @route /admin/translations/{locale}
176
     * @return string HTML
177
     */
178
    public function getTranslations($locale = '') {
179
        //Idioma por defecto
180
        if(empty($locale)) $locale = $this->config->get("default_language");
181
182
        //Generamos las traducciones de las plantillas
183
        $translations = $this->tpl->regenerateTemplates();
184
185
        $locale_path = realpath(BASE_DIR . DIRECTORY_SEPARATOR . 'locale');
186
        $locale_path .= DIRECTORY_SEPARATOR . $locale . DIRECTORY_SEPARATOR . 'LC_MESSAGES' . DIRECTORY_SEPARATOR;
187
188
        //Localizamos xgettext
189
        $translations = array_merge($translations, GeneratorService::findTranslations(SOURCE_DIR, $locale));
190
        $translations = array_merge($translations, GeneratorService::findTranslations(CORE_DIR, $locale));
191
        $translations = array_merge($translations, GeneratorService::findTranslations(CACHE_DIR, $locale));
192
193
        $translations[] = "msgfmt {$locale_path}translations.po -o {$locale_path}translations.mo";
194
        $translations[] = shell_exec("export PATH=\$PATH:/opt/local/bin:/bin:/sbin; msgfmt {$locale_path}translations.po -o {$locale_path}translations.mo");
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 156 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...
195
        return $this->render("translations.html.twig", array(
196
            "translations" => $translations,
197
        ));
198
    }
199
200
    /**
201
     * Método que gestiona la configuración de las variables
202
     * @GET
203
     * @Route /admin/config
204
     * @return string|null
205
     * @throws \HttpException
206
     */
207
    public function config() {
208
        Logger::log("Config loaded executed by ".$this->getRequest()->getRequestUri());
209
        /* @var $form \PSFS\base\config\ConfigForm */
210
        $form = new ConfigForm();
211
        $form->build();
212
        return $this->render('welcome.html.twig', array(
213
            'text' => _("Bienvenido a PSFS"),
214
            'config' => $form,
215
            'typeahead_data' => array_merge(Config::$required, Config::$optional),
216
        ));
217
    }
218
219
    /**
220
     * Servicio que guarda la configuración de la plataforma
221
     * @POST
222
     * @route /admin/config
223
     * @visible false
224
     * @return string
225
     * @throws \HttpException
226
     */
227
    public function saveConfig() {
228
        Logger::getInstance()->infoLog(_("Guardando configuración"));
229
        /* @var $form \PSFS\base\config\ConfigForm */
230
        $form = new ConfigForm();
231
        $form->build();
232
        $form->hydrate();
233
        if($form->isValid()) {
234
            $debug = Config::getInstance()->getDebugMode();
235
            $newDebug = $form->getFieldValue("debug");
236
            if(Config::save($form->getData(), $form->getExtraData())) {
237
                Logger::log(_('Configuración guardada correctamente'));
238
                //Verificamos si tenemos que limpiar la cache del DocumentRoot
239
                if(boolval($debug) !== boolval($newDebug)) {
240
                    Config::clearDocumentRoot();
241
                }
242
                $this->security->setFlash("callback_message", _("Configuración actualizada correctamente"));
243
                $this->security->setFlash("callback_route", $this->getRoute("admin-config", true));
244
            } else {
245
                throw new \HttpException(_('Error al guardar la configuración, prueba a cambiar los permisos'), 403);
246
            }
247
        }
248
        return $this->render('welcome.html.twig', array(
249
            'text' => _("Bienvenido a PSFS"),
250
            'config' => $form,
251
            'typeahead_data' => array_merge(Config::$required, Config::$optional),
252
        ));
253
    }
254
255
    /**
256
     * Método que gestiona el menú de administración
257
     * @GET
258
     * @route /admin
259
     * @visible false
260
     * @return string|null
261
     */
262
    public function index() {
263
        return $this->render("index.html.twig", array(
264
            "routes" => Router::getInstance()->getAdminRoutes(),
265
        ));
266
    }
267
268
    /**
269
     * Método que genera un nuevo módulo
270
     * @GET
271
     * @route /admin/module
272
     *
273
     * @return string HTML
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
274
     * @throws \HttpException
275
     */
276
    public function generateModule() {
277
        Logger::getInstance()->infoLog("Arranque generador de módulos al solicitar ".$this->getRequest()->getRequestUri());
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 123 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...
278
        /* @var $form \PSFS\base\config\ConfigForm */
279
        $form = new ModuleForm();
280
        $form->build();
281
        return $this->render("modules.html.twig", array(
282
            'properties' => $this->config->getPropelParams(),
283
            'form' => $form,
284
        ));
285
    }
286
287
    /**
288
     * @POST
289
     * @route /admin/module
290
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
291
     */
292
    public function doGenerateModule()
293
    {
294
        $form = new ModuleForm();
295
        $form->build();
296
        $form->hydrate();
297
        if ($form->isValid()) {
298
            $module = $form->getFieldValue("module");
299
            $force = $form->getFieldValue("force");
300
            $type = $form->getFieldValue("controllerType");
301
            try {
302
                $module = preg_replace('/(\\\|\/)/', '/', $module);
303
                $module = preg_replace('/^\//', '', $module);
304
                $this->gen->createStructureModule($module, $force, $type);
0 ignored issues
show
Bug introduced by
It seems like $module defined by preg_replace('/^\\//', '', $module) on line 303 can also be of type array<integer,string>; however, PSFS\Services\GeneratorS...createStructureModule() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
305
                $this->security->setFlash("callback_message", str_replace("%s",$module, _("Módulo %s generado correctamente")));
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 120 characters; contains 128 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...
306
                $this->security->setFlash("callback_route", $this->getRoute("admin-module", true));
307
            } catch(\Exception $e) {
308
                Logger::getInstance()->infoLog($e->getMessage() . " [" . $e->getFile() . ":" . $e->getLine() . "]");
309
                throw new ConfigException('Error al generar el módulo, prueba a cambiar los permisos', 403);
0 ignored issues
show
Unused Code introduced by
The call to ConfigException::__construct() has too many arguments starting with 403.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
310
            }
311
        }
312
        return $this->render("modules.html.twig", array(
313
            'properties' => $this->config->getPropelParams(),
314
            'form' => $form,
315
        ));
316
    }
317
318
319
320
    /**
321
     * Servicio que devuelve los parámetros disponibles
322
     * @GET
323
     * @route /admin/config/params
324
     * @visible false
325
     * @return mixed
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use string|null.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
326
     */
327
    public function getConfigParams() {
328
        $response = array_merge(Config::$required, Config::$optional);
329
        $domains = Router::getInstance()->getDomains();
330
        foreach($domains as $domain => $routes) {
0 ignored issues
show
Bug introduced by
The expression $domains of type array|string|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
331
            $pDomain = str_replace('@', '', $domain);
332
            $pDomain = str_replace('/', '', $pDomain);
333
            $response[] = strtolower($pDomain) . '.api.secret';
334
        }
335
        return $this->json($response);
336
    }
337
338
    /**
339
     * Método que pinta por pantalla todas las rutas del sistema
340
     * @GET
341
     * @route /admin/routes
342
     */
343
    public function printRoutes()
344
    {
345
        return $this->render('routing.html.twig', array(
346
            'slugs' => Router::getInstance()->getSlugs(),
347
        ));
348
    }
349
350
    /**
351
     * Servicio que devuelve los parámetros disponibles
352
     * @GET
353
     * @route /admin/routes/show
354
     * @visible false
355
     * @return mixed
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use string|null.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
356
     */
357
    public function getRouting()
358
    {
359
        $response = Router::getInstance()->getSlugs();
360
        return $this->json($response);
361
    }
362
363
    /**
364
     * Servicio que muestra los logs del sistema
365
     * @route /admin/logs
366
     * @return string|null
367
     */
368
    public function logs()
369
    {
370
        $log = _("Selecciona un fichero de log");
371
        $logs = $this->srv->getLogFiles();
372
373
        $selected = '';
374
        $monthOpen = null;
375
        if($this->getRequest()->getMethod() == 'POST')
376
        {
377
            $selected = $this->getRequest()->get("log");
378
            list($log, $monthOpen) = $this->srv->formatLogFile($selected);
379
        }
380
        asort($logs);
381
        return $this->render("logs.html.twig", array(
382
            "logs" => $logs,
383
            "log" => $log,
384
            "selected" => $selected,
385
            "month_open" => $monthOpen,
386
        ));
387
    }
388
389
    /**
390
     * Service to regenerate routes
391
     * @GET
392
     * @route /admin/routes/gen
393
     * @return string HTML
394
     */
395
    public function regenerateUrls()
396
    {
397
        $router = Router::getInstance();
398
        try {
399
            $router->hydrateRouting();
400
            $router->simpatize();
401
            $this->security->setFlash("callback_message", _("Rutas generadas correctamente"));
402
            $this->security->setFlash("callback_route", $this->getRoute("admin", true));
403
        } catch(\Exception $e) {
404
            Logger::log($e->getMessage(), LOG_ERR);
405
            $this->security->setFlash("callback_message", _("Algo no ha salido bien, revisa los logs"));
406
            $this->security->setFlash("callback_route", $this->getRoute("admin", true));
407
        }
408
        return $this->redirect($this->getRoute('admin'));
409
    }
410
411
}
412