Issues (536)

src/Controllers/BaseController.php (4 issues)

1
<?php
2
3
/**
4
 * This file is part of Blitz PHP framework.
5
 *
6
 * (c) 2022 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace BlitzPHP\Controllers;
13
14
use BlitzPHP\Exceptions\HttpException;
15
use BlitzPHP\Exceptions\ValidationException;
16
use BlitzPHP\Http\Request;
17
use BlitzPHP\Http\Response;
18
use BlitzPHP\Validation\DataValidation;
19
use BlitzPHP\Validation\Validation;
20
use BlitzPHP\Validation\Validator;
21
use Dimtrovich\Validation\Exceptions\ValidationException as DimtrovichValidationException;
22
use Dimtrovich\Validation\ValidatedInput;
23
use Psr\Http\Message\ResponseInterface;
24
use Psr\Http\Message\ServerRequestInterface;
25
use Psr\Log\LoggerInterface;
26
use ReflectionException;
27
28
/**
29
 * Contrôleur de base pour toute application BlitzPHP
30
 */
31
abstract class BaseController
32
{
33
    /**
34
     * Helpers qui seront automatiquement chargés lors de l'instanciation de la classe.
35
     *
36
     * @var array
37
     */
38
    protected $helpers = [];
39
40
    /**
41
     * Le modèle qui contient les données de cette ressource
42
     *
43
     * @var string|null
44
     */
45
    protected $modelName;
46
47
    /**
48
     * Le modèle qui contient les données de cette ressource
49
     *
50
     * @var object|null
51
     */
52
    protected $model;
53
54
    /**
55
     * Instance de l'objet Request principal.
56
     *
57
     * @var Request
58
     */
59
    protected $request;
60
61
    /**
62
     * Instance de l'objet de Response principal.
63
     *
64
     * @var Response
65
     */
66
    protected $response;
67
68
    /**
69
     * Instance de logger à utiliser.
70
     *
71
     * @var LoggerInterface
72
     */
73
    protected $logger;
74
75
    /**
76
     * Devrait appliquer l'accès HTTPS pour toutes les méthodes de ce contrôleur.
77
     *
78
     * @var int Nombre de secondes pour définir l'en-tête HSTS
79
     */
80
    protected $forceHTTPS = 0;
81
82
    /**
83
     * Constructeur.
84
     *
85
     * @param Request  $request
86
     * @param Response $response
87
     *
88
     * @throws HttpException
89
     */
90
    public function initialize(ServerRequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
91
    {
92
        $this->request  = $request;
0 ignored issues
show
Documentation Bug introduced by
$request is of type Psr\Http\Message\ServerRequestInterface, but the property $request was declared to be of type BlitzPHP\Http\Request. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
93
        $this->response = $response;
0 ignored issues
show
Documentation Bug introduced by
$response is of type Psr\Http\Message\ResponseInterface, but the property $response was declared to be of type BlitzPHP\Http\Response. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
94
        $this->logger   = $logger;
95
96
        service('container')->set(Request::class, $request);
97
        service('container')->set(Response::class, $response);
98
99
        if ($this->forceHTTPS > 0) {
100
            $this->forceHTTPS($this->forceHTTPS);
101
        }
102
103
        $this->getModel();
104
105
        if ($this->helpers !== []) {
106
            helper($this->helpers);
107
        }
108
    }
109
110
    /**
111
     * Validation des donnees de la requete actuelle
112
     *
113
     * @param array|class-string<DataValidation> $rules
0 ignored issues
show
Documentation Bug introduced by
The doc comment array|class-string<DataValidation> at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in array|class-string<DataValidation>.
Loading history...
114
     * @param array                              $messages Si $rules est une chaine (representant) la classe de validation,
115
     *                                                     alors, $messages est consideré comme un tableau d'attribut à passer à la classe de validation.
116
     *                                                     Ceci peut par exemple être utilisé par spécifier l'ID à ignorer pour la règle `unique`.
117
     */
118
    protected function validate(array|string $rules, array $messages = []): ValidatedInput
119
    {
120
        return $this->request->validate($rules, $messages);
121
    }
122
123
    /**
124
     * Validation des donnees quelconques
125
     */
126
    protected function validateData(array $data, array $rules, array $messages = []): ValidatedInput
127
    {
128
        try {
129
            return Validator::make($data, $rules, $messages)->safe();
130
        } catch (DimtrovichValidationException $e) {
131
            $th = new ValidationException($e->getMessage());
132
            $th->setErrors($e->getErrors());
133
134
            throw $th;
135
        }
136
    }
137
138
    /**
139
     * Cree un validateur avec les donnees de la requete actuelle
140
     *
141
     * @param array|class-string<DataValidation> $rules
0 ignored issues
show
Documentation Bug introduced by
The doc comment array|class-string<DataValidation> at position 2 could not be parsed: Unknown type name 'class-string' at position 2 in array|class-string<DataValidation>.
Loading history...
142
     * @param array                              $messages Si $rules est une chaine (representant) la classe de validation,
143
     *                                                     alors, $messages est consideré comme un tableau d'attribut à passer à la classe de validation.
144
     *                                                     Ceci peut par exemple être utilisé par spécifier l'ID à ignorer pour la règle `unique`.
145
     */
146
    protected function validation(array|string $rules, array $messages = []): Validation
147
    {
148
        return $this->request->validation($rules, $messages);
149
    }
150
151
    /**
152
     * Définissez ou modifiez le modèle auquel ce contrôleur est lié.
153
     * Étant donné le nom ou l'objet, déterminer l'autre.
154
     *
155
     * @param object|string|null $which
156
     */
157
    protected function setModel($which = null)
158
    {
159
        if ($which) {
160
            $this->model     = is_object($which) ? $which : null;
161
            $this->modelName = is_object($which) ? null : $which;
162
        }
163
164
        if (empty($this->model) && ! empty($this->modelName) && class_exists($this->modelName)) {
165
            $this->model = model($this->modelName);
166
        }
167
168
        if (! empty($this->model) && empty($this->modelName)) {
169
            $this->modelName = $this->model::class;
170
        }
171
    }
172
173
    /**
174
     * Une méthode pratique à utiliser lorsque vous devez vous assurer qu'un seul
175
     * La méthode est accessible uniquement via HTTPS. Si ce n'est pas le cas, alors une redirection
176
     * reviendra à cette méthode et l'en-tête HSTS sera envoyé
177
     * pour que les navigateurs modernes transforment automatiquement les requêtes.
178
     *
179
     * @param int $duration Le nombre de secondes pendant lesquelles ce lien doit être
180
     *                      considéré comme sûr pour. Uniquement avec en-tête HSTS.
181
     *                      La valeur par défaut est 1 an.
182
     *
183
     * @throws HttpException
184
     */
185
    protected function forceHTTPS(int $duration = 31536000)
186
    {
187
        force_https($duration, $this->request, $this->response);
188
    }
189
190
    /**
191
     * Fournit un moyen simple de se lier à la classe principale de BlitzPHP
192
     * et de lui indiquer la durée de mise en cache de la page actuelle.
193
     */
194
    protected function cachePage(int $time)
195
    {
196
        service('responsecache')->setTtl($time);
197
    }
198
199
    /**
200
     * Recherche le model par defaut (à base de son nom) du controleur
201
     *
202
     * @throws ReflectionException
203
     */
204
    private function getModel()
205
    {
206
        $model = ! empty($this->modelName) ? $this->modelName : str_replace('Controller', 'Model', static::class);
207
208
        if (class_exists($model)) {
209
            $this->setModel($model);
210
        }
211
    }
212
}
213