blitz-php /
framework
| 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\View\Adapters; |
||||||
| 13 | |||||||
| 14 | use BlitzPHP\Debug\Toolbar\Collectors\ViewsCollector; |
||||||
| 15 | use BlitzPHP\Exceptions\ViewException; |
||||||
| 16 | use BlitzPHP\Utilities\Helpers; |
||||||
| 17 | use RuntimeException; |
||||||
| 18 | |||||||
| 19 | /** |
||||||
| 20 | * Class View |
||||||
| 21 | */ |
||||||
| 22 | class NativeAdapter extends AbstractAdapter |
||||||
| 23 | { |
||||||
| 24 | /** |
||||||
| 25 | * {@inheritDoc} |
||||||
| 26 | */ |
||||||
| 27 | protected string $ext = 'php'; |
||||||
| 28 | |||||||
| 29 | /** |
||||||
| 30 | * Fusionner les données enregistrées et les données utilisateur |
||||||
| 31 | */ |
||||||
| 32 | protected $tempData; |
||||||
| 33 | |||||||
| 34 | /** |
||||||
| 35 | * Indique si les données doivent être enregistrées entre les rendus. |
||||||
| 36 | * |
||||||
| 37 | * @var bool |
||||||
| 38 | */ |
||||||
| 39 | protected $saveData; |
||||||
| 40 | |||||||
| 41 | /** |
||||||
| 42 | * Nombre de vues chargées |
||||||
| 43 | */ |
||||||
| 44 | protected int $viewsCount = 0; |
||||||
| 45 | |||||||
| 46 | /** |
||||||
| 47 | * Contient les sections et leurs données. |
||||||
| 48 | */ |
||||||
| 49 | protected array $sections = []; |
||||||
| 50 | |||||||
| 51 | /** |
||||||
| 52 | * Le nom de la section actuelle en cours de rendu, le cas échéant. |
||||||
| 53 | * |
||||||
| 54 | * @var list<string> |
||||||
|
0 ignored issues
–
show
|
|||||||
| 55 | */ |
||||||
| 56 | protected array $sectionStack = []; |
||||||
| 57 | |||||||
| 58 | /** |
||||||
| 59 | * Contient les css charges a partie de la section actuelle en cours de rendu |
||||||
| 60 | */ |
||||||
| 61 | protected array $_styles = []; |
||||||
| 62 | |||||||
| 63 | /** |
||||||
| 64 | * Contient les librairies css charges a partie de la section actuelle en cours de rendu |
||||||
| 65 | */ |
||||||
| 66 | protected array $_lib_styles = []; |
||||||
| 67 | |||||||
| 68 | /** |
||||||
| 69 | * Contient les scripts js charges a partie de la section actuelle en cours de rendu |
||||||
| 70 | */ |
||||||
| 71 | protected array $_scripts = []; |
||||||
| 72 | |||||||
| 73 | /** |
||||||
| 74 | * Contient les scripts js des librairies charges a partie de la section actuelle en cours de rendu |
||||||
| 75 | */ |
||||||
| 76 | protected array $_lib_scripts = []; |
||||||
| 77 | |||||||
| 78 | /** |
||||||
| 79 | * {@inheritDoc} |
||||||
| 80 | */ |
||||||
| 81 | public function __construct(protected array $config, $viewPath = null, protected bool $debug = BLITZ_DEBUG) |
||||||
| 82 | { |
||||||
| 83 | 8 | parent::__construct($config, $viewPath, $debug); |
|||||
| 84 | |||||||
| 85 | 8 | $this->saveData = (bool) ($config['save_data'] ?? true); |
|||||
| 86 | } |
||||||
| 87 | |||||||
| 88 | /** |
||||||
| 89 | * {@inheritDoc} |
||||||
| 90 | */ |
||||||
| 91 | public function render(string $view, ?array $options = null, ?bool $saveData = null): string |
||||||
| 92 | { |
||||||
| 93 | 6 | $this->renderVars['start'] = microtime(true); |
|||||
| 94 | 6 | $this->renderVars['view'] = $view; |
|||||
| 95 | 6 | $this->renderVars['options'] = $options ?? []; |
|||||
| 96 | |||||||
| 97 | // Stocke les résultats ici donc même si |
||||||
| 98 | // plusieurs vues sont appelées dans une vue, ce ne sera pas le cas |
||||||
| 99 | // nettoyez-le sauf si nous le voulons. |
||||||
| 100 | 6 | $saveData ??= $this->saveData; |
|||||
| 101 | |||||||
| 102 | // A-t-il été mis en cache ? |
||||||
| 103 | if (isset($this->renderVars['options']['cache'])) { |
||||||
| 104 | 6 | $cacheName = $this->renderVars['options']['cache_name'] ?? str_replace('.' . $this->ext, '', $this->renderVars['view']); |
|||||
| 105 | $cacheName = str_replace(['\\', '/'], '', $cacheName); |
||||||
| 106 | |||||||
| 107 | $this->renderVars['cacheName'] = $cacheName; |
||||||
| 108 | |||||||
| 109 | if ($output = cache($this->renderVars['cacheName'])) { |
||||||
| 110 | $this->logPerformance($this->renderVars['start'], microtime(true), $this->renderVars['view']); |
||||||
|
0 ignored issues
–
show
It seems like
$this->renderVars['start'] can also be of type string; however, parameter $start of BlitzPHP\View\Adapters\A...apter::logPerformance() does only seem to accept double, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
It seems like
microtime(true) can also be of type string; however, parameter $end of BlitzPHP\View\Adapters\A...apter::logPerformance() does only seem to accept double, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 111 | |||||||
| 112 | return $output; |
||||||
|
0 ignored issues
–
show
|
|||||||
| 113 | } |
||||||
| 114 | } |
||||||
| 115 | |||||||
| 116 | 6 | $this->renderVars['file'] = $this->getRenderedFile($this->renderVars['options'], $this->renderVars['view'], $this->ext); |
|||||
| 117 | |||||||
| 118 | // Rendre nos données de vue disponibles pour la vue. |
||||||
| 119 | 6 | $this->prepareTemplateData($saveData); |
|||||
| 120 | |||||||
| 121 | // Enregistrer les variables actuelles |
||||||
| 122 | 6 | $renderVars = $this->renderVars; |
|||||
| 123 | |||||||
| 124 | $output = (function (): string { |
||||||
| 125 | 6 | extract($this->tempData); |
|||||
| 126 | 6 | ob_start(); |
|||||
| 127 | 6 | include $this->renderVars['file']; |
|||||
| 128 | |||||||
| 129 | 6 | return ob_get_clean() ?: ''; |
|||||
| 130 | 6 | })(); |
|||||
| 131 | |||||||
| 132 | // Lors de l'utilisation de mises en page, les données ont déjà été stockées |
||||||
| 133 | // dans $this->sections, et aucune autre sortie valide |
||||||
| 134 | // est autorisé dans $output donc nous allons l'écraser. |
||||||
| 135 | if ($this->layout !== null && $this->sectionStack === []) { |
||||||
| 136 | $layoutView = $this->layout; |
||||||
| 137 | $this->layout = null; |
||||||
| 138 | // Enregistrer les variables actuelles |
||||||
| 139 | $renderVars = $this->renderVars; |
||||||
| 140 | $output = $this->render($layoutView, array_merge($options ?? [], ['viewPath' => LAYOUT_PATH]), $saveData); |
||||||
| 141 | } |
||||||
| 142 | |||||||
| 143 | 6 | $this->logPerformance($this->renderVars['start'], microtime(true), $this->renderVars['view']); |
|||||
| 144 | |||||||
| 145 | if ($this->debug && (! isset($options['debug']) || $options['debug'] === true) && in_array(ViewsCollector::class, config('toolbar.collectors'), true)) { |
||||||
|
0 ignored issues
–
show
config('toolbar.collectors') of type T|null|object is incompatible with the type array expected by parameter $haystack of in_array().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 146 | // Nettoyer nos noms de chemins pour les rendre un peu plus propres |
||||||
| 147 | $this->renderVars['file'] = clean_path($this->renderVars['file']); |
||||||
| 148 | $this->renderVars['file'] = ++$this->viewsCount . ' ' . $this->renderVars['file']; |
||||||
| 149 | $output = '<!-- DEBUG-VIEW START ' . $this->renderVars['file'] . ' -->' . PHP_EOL |
||||||
| 150 | . $output . PHP_EOL |
||||||
| 151 | . '<!-- DEBUG-VIEW ENDED ' . $this->renderVars['file'] . ' -->' . PHP_EOL; |
||||||
| 152 | } |
||||||
| 153 | |||||||
| 154 | 6 | $output = $this->decorate($output); |
|||||
| 155 | |||||||
| 156 | // Faut-il mettre en cache ? |
||||||
| 157 | if (isset($this->renderVars['options']['cache'])) { |
||||||
| 158 | 6 | cache()->write($this->renderVars['cacheName'], $output, (int) $this->renderVars['options']['cache']); |
|||||
| 159 | } |
||||||
| 160 | |||||||
| 161 | 6 | $this->tempData = null; |
|||||
| 162 | |||||||
| 163 | // Récupère les variables actuelles |
||||||
| 164 | 6 | $this->renderVars = $renderVars; |
|||||
| 165 | |||||||
| 166 | 6 | return $output; |
|||||
| 167 | } |
||||||
| 168 | |||||||
| 169 | /** |
||||||
| 170 | * {@inheritDoc} |
||||||
| 171 | */ |
||||||
| 172 | public function renderString(string $view, ?array $options = null, ?bool $saveData = null): string |
||||||
| 173 | { |
||||||
| 174 | $start = microtime(true); |
||||||
| 175 | $saveData ??= $this->saveData; |
||||||
| 176 | $this->prepareTemplateData($saveData); |
||||||
| 177 | |||||||
| 178 | $output = (function (string $view): string { |
||||||
| 179 | extract($this->tempData); |
||||||
| 180 | ob_start(); |
||||||
| 181 | eval('?>' . $view); |
||||||
|
0 ignored issues
–
show
|
|||||||
| 182 | |||||||
| 183 | return ob_get_clean() ?: ''; |
||||||
| 184 | })($view); |
||||||
| 185 | |||||||
| 186 | $this->logPerformance($start, microtime(true), $this->excerpt($view)); |
||||||
|
0 ignored issues
–
show
It seems like
microtime(true) can also be of type string; however, parameter $end of BlitzPHP\View\Adapters\A...apter::logPerformance() does only seem to accept double, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
It seems like
$start can also be of type string; however, parameter $start of BlitzPHP\View\Adapters\A...apter::logPerformance() does only seem to accept double, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 187 | $this->tempData = null; |
||||||
| 188 | |||||||
| 189 | return $output; |
||||||
| 190 | } |
||||||
| 191 | |||||||
| 192 | /** |
||||||
| 193 | * Extraire le premier bit d'une longue chaîne et ajouter des points de suspension |
||||||
| 194 | */ |
||||||
| 195 | public function excerpt(string $string, int $length = 20): string |
||||||
| 196 | { |
||||||
| 197 | return (strlen($string) > $length) ? substr($string, 0, $length - 3) . '...' : $string; |
||||||
| 198 | } |
||||||
| 199 | |||||||
| 200 | /** |
||||||
| 201 | * {@inheritDoc} |
||||||
| 202 | */ |
||||||
| 203 | public function setData(array $data = [], ?string $context = null): self |
||||||
| 204 | { |
||||||
| 205 | if ($context !== null && $context !== '') { |
||||||
| 206 | 6 | $data = esc($data, $context); |
|||||
| 207 | } |
||||||
| 208 | |||||||
| 209 | 6 | $this->tempData = $data; |
|||||
| 210 | |||||||
| 211 | 6 | return $this; |
|||||
| 212 | } |
||||||
| 213 | |||||||
| 214 | /** |
||||||
| 215 | * {@inheritDoc} |
||||||
| 216 | */ |
||||||
| 217 | public function addData(array $data = [], ?string $context = null): self |
||||||
| 218 | { |
||||||
| 219 | if ($context !== null && $context !== '') { |
||||||
| 220 | $data = esc($data, $context); |
||||||
| 221 | } |
||||||
| 222 | |||||||
| 223 | $this->tempData ??= $this->data; |
||||||
| 224 | $this->tempData = array_merge($this->tempData, $data); |
||||||
| 225 | |||||||
| 226 | return $this; |
||||||
| 227 | } |
||||||
| 228 | |||||||
| 229 | /** |
||||||
| 230 | * {@inheritDoc} |
||||||
| 231 | */ |
||||||
| 232 | public function setVar(string $name, $value = null, ?string $context = null): self |
||||||
| 233 | { |
||||||
| 234 | if ($context !== null && $context !== '') { |
||||||
| 235 | $value = esc($value, $context); |
||||||
| 236 | } |
||||||
| 237 | |||||||
| 238 | $this->tempData ??= $this->data; |
||||||
| 239 | $this->tempData[$name] = $value; |
||||||
| 240 | |||||||
| 241 | return $this; |
||||||
| 242 | } |
||||||
| 243 | |||||||
| 244 | /** |
||||||
| 245 | * {@inheritDoc} |
||||||
| 246 | */ |
||||||
| 247 | public function getData(): array |
||||||
| 248 | { |
||||||
| 249 | return $this->tempData ?? $this->data; |
||||||
| 250 | } |
||||||
| 251 | |||||||
| 252 | /** |
||||||
| 253 | * {@inheritDoc} |
||||||
| 254 | */ |
||||||
| 255 | public function resetData(): self |
||||||
| 256 | { |
||||||
| 257 | $this->data = []; |
||||||
| 258 | $this->tempData = []; |
||||||
| 259 | |||||||
| 260 | return $this; |
||||||
| 261 | } |
||||||
| 262 | |||||||
| 263 | /** |
||||||
| 264 | * Spécifie que la vue actuelle doit étendre une mise en page existante. |
||||||
| 265 | */ |
||||||
| 266 | public function extend(string $layout) |
||||||
| 267 | { |
||||||
| 268 | $this->setLayout($layout); |
||||||
| 269 | } |
||||||
| 270 | |||||||
| 271 | /** |
||||||
| 272 | * Commence le contenu d'une section dans la mise en page. |
||||||
| 273 | */ |
||||||
| 274 | public function start(string $name, ?string $content = null) |
||||||
| 275 | { |
||||||
| 276 | if (null === $content) { |
||||||
| 277 | $this->sectionStack[] = $name; |
||||||
| 278 | |||||||
| 279 | ob_start(); |
||||||
| 280 | } else { |
||||||
| 281 | $this->sections[$name] = [$content]; |
||||||
| 282 | } |
||||||
| 283 | } |
||||||
| 284 | |||||||
| 285 | /** |
||||||
| 286 | * Commence le contenu d'une section dans la mise en page. |
||||||
| 287 | * |
||||||
| 288 | * @alias self::start() |
||||||
| 289 | */ |
||||||
| 290 | public function section(string $name, ?string $content = null): void |
||||||
| 291 | { |
||||||
| 292 | $this->start($name, $content); |
||||||
| 293 | } |
||||||
| 294 | |||||||
| 295 | /** |
||||||
| 296 | * Commence le contenu d'une section dans la mise en page. |
||||||
| 297 | * |
||||||
| 298 | * @alias self::start() |
||||||
| 299 | */ |
||||||
| 300 | public function begin(string $name, ?string $content = null): void |
||||||
| 301 | { |
||||||
| 302 | $this->start($name, $content); |
||||||
| 303 | } |
||||||
| 304 | |||||||
| 305 | /** |
||||||
| 306 | * Capture la dernière section |
||||||
| 307 | * |
||||||
| 308 | * @throws RuntimeException |
||||||
| 309 | */ |
||||||
| 310 | public function stop() |
||||||
| 311 | { |
||||||
| 312 | $contents = ob_get_clean(); |
||||||
| 313 | |||||||
| 314 | if ($this->sectionStack === []) { |
||||||
| 315 | throw new RuntimeException('View themes, no current section.'); |
||||||
| 316 | } |
||||||
| 317 | |||||||
| 318 | $section = array_pop($this->sectionStack); |
||||||
| 319 | |||||||
| 320 | // Assurez-vous qu'un tableau existe afin que nous puissions stocker plusieurs entrées pour cela. |
||||||
| 321 | if (! array_key_exists($section, $this->sections)) { |
||||||
| 322 | $this->sections[$section] = []; |
||||||
| 323 | } |
||||||
| 324 | |||||||
| 325 | $this->sections[$section][] = $contents; |
||||||
| 326 | } |
||||||
| 327 | |||||||
| 328 | /** |
||||||
| 329 | * Capture la dernière section |
||||||
| 330 | * |
||||||
| 331 | * @throws RuntimeException |
||||||
| 332 | * |
||||||
| 333 | * @alias self::stop() |
||||||
| 334 | */ |
||||||
| 335 | public function endSection(): void |
||||||
| 336 | { |
||||||
| 337 | $this->stop(); |
||||||
| 338 | } |
||||||
| 339 | |||||||
| 340 | /** |
||||||
| 341 | * Capture la dernière section |
||||||
| 342 | * |
||||||
| 343 | * @throws RuntimeException |
||||||
| 344 | * |
||||||
| 345 | * @alias self::stop() |
||||||
| 346 | */ |
||||||
| 347 | public function end(): void |
||||||
| 348 | { |
||||||
| 349 | $this->stop(); |
||||||
| 350 | } |
||||||
| 351 | |||||||
| 352 | /** |
||||||
| 353 | * Restitue le contenu d'une section. |
||||||
| 354 | */ |
||||||
| 355 | public function show(string $sectionName, bool $preserve = false) |
||||||
| 356 | { |
||||||
| 357 | if (! isset($this->sections[$sectionName])) { |
||||||
| 358 | echo ''; |
||||||
| 359 | |||||||
| 360 | return; |
||||||
| 361 | } |
||||||
| 362 | |||||||
| 363 | foreach ($this->sections[$sectionName] as $key => $contents) { |
||||||
| 364 | echo $contents; |
||||||
| 365 | |||||||
| 366 | if (false === $preserve) { |
||||||
| 367 | unset($this->sections[$sectionName][$key]); |
||||||
| 368 | } |
||||||
| 369 | } |
||||||
| 370 | } |
||||||
| 371 | |||||||
| 372 | /** |
||||||
| 373 | * Affichage rapide du contenu principal |
||||||
| 374 | */ |
||||||
| 375 | public function renderView(): void |
||||||
| 376 | { |
||||||
| 377 | $this->show('content'); |
||||||
| 378 | } |
||||||
| 379 | |||||||
| 380 | /** |
||||||
| 381 | * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires. |
||||||
| 382 | */ |
||||||
| 383 | public function insert(string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string |
||||||
| 384 | { |
||||||
| 385 | $view = Helpers::ensureExt($view, $this->ext); |
||||||
| 386 | $view = str_replace(' ', '', $view); |
||||||
| 387 | |||||||
| 388 | if ($view[0] !== '/') { |
||||||
| 389 | $view = $this->retrievePartialPath($view); |
||||||
| 390 | } |
||||||
| 391 | |||||||
| 392 | return $this->addData($data)->render($view, $options, $saveData); |
||||||
| 393 | } |
||||||
| 394 | |||||||
| 395 | /** |
||||||
| 396 | * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires. |
||||||
| 397 | * |
||||||
| 398 | * @alias self::insert() |
||||||
| 399 | */ |
||||||
| 400 | public function include(string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string |
||||||
| 401 | { |
||||||
| 402 | return $this->insert($view, $data, $options, $saveData); |
||||||
| 403 | } |
||||||
| 404 | |||||||
| 405 | /** |
||||||
| 406 | * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires lorsqu'une condition est remplie. |
||||||
| 407 | */ |
||||||
| 408 | public function insertWhen(bool|callable $condition, string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string |
||||||
| 409 | { |
||||||
| 410 | if (is_callable($condition)) { |
||||||
| 411 | $condition = $condition(); |
||||||
| 412 | } |
||||||
| 413 | |||||||
| 414 | if (true === $condition) { |
||||||
| 415 | return $this->insert($view, $data, $options, $saveData); |
||||||
| 416 | } |
||||||
| 417 | |||||||
| 418 | return ''; |
||||||
| 419 | } |
||||||
| 420 | |||||||
| 421 | /** |
||||||
| 422 | * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires lorsqu'une condition est remplie. |
||||||
| 423 | * |
||||||
| 424 | * @alias self::insertWhen() |
||||||
| 425 | */ |
||||||
| 426 | public function includeWhen(bool|callable $condition, string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string |
||||||
| 427 | { |
||||||
| 428 | return $this->insertWhen($condition, $view, $data, $options, $saveData); |
||||||
| 429 | } |
||||||
| 430 | |||||||
| 431 | /** |
||||||
| 432 | * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires lorsqu'une condition n'est pas remplie. |
||||||
| 433 | */ |
||||||
| 434 | public function insertUnless(bool|callable $condition, string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string |
||||||
| 435 | { |
||||||
| 436 | if (is_callable($condition)) { |
||||||
| 437 | $condition = $condition(); |
||||||
| 438 | } |
||||||
| 439 | |||||||
| 440 | return $this->insertWhen(false === $condition, $view, $data, $options, $saveData); |
||||||
| 441 | } |
||||||
| 442 | |||||||
| 443 | /** |
||||||
| 444 | * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires lorsqu'une condition n'est pas remplie. |
||||||
| 445 | * |
||||||
| 446 | * @alias self::insertUnless() |
||||||
| 447 | */ |
||||||
| 448 | public function includeUnless(bool|callable $condition, string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string |
||||||
| 449 | { |
||||||
| 450 | return $this->insertUnless($condition, $view, $data, $options, $saveData); |
||||||
| 451 | } |
||||||
| 452 | |||||||
| 453 | /** |
||||||
| 454 | * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires si elle existe. |
||||||
| 455 | * |
||||||
| 456 | * @alias self::insertIf() |
||||||
| 457 | */ |
||||||
| 458 | public function includeIf(string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string |
||||||
| 459 | { |
||||||
| 460 | return $this->insertIf($view, $data, $options, $saveData); |
||||||
| 461 | } |
||||||
| 462 | |||||||
| 463 | /** |
||||||
| 464 | * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires si elle existe. |
||||||
| 465 | */ |
||||||
| 466 | public function insertIf(string $view, ?array $data = [], ?array $options = null, ?bool $saveData = null): string |
||||||
| 467 | { |
||||||
| 468 | $view = Helpers::ensureExt($view, $this->ext); |
||||||
| 469 | $view = str_replace(' ', '', $view); |
||||||
| 470 | |||||||
| 471 | if ($view[0] !== '/') { |
||||||
| 472 | $view = $this->retrievePartialPath($view); |
||||||
| 473 | } |
||||||
| 474 | |||||||
| 475 | if (is_file($view)) { |
||||||
| 476 | return $this->addData($data)->render($view, $options, $saveData); |
||||||
| 477 | } |
||||||
| 478 | |||||||
| 479 | return ''; |
||||||
| 480 | } |
||||||
| 481 | |||||||
| 482 | /** |
||||||
| 483 | * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires si elle existe. |
||||||
| 484 | * |
||||||
| 485 | * @alias self::insertFisrt() |
||||||
| 486 | */ |
||||||
| 487 | public function includeFirst(array $views, ?array $data = [], ?array $options = null, ?bool $saveData = null): string |
||||||
| 488 | { |
||||||
| 489 | return $this->insertFirst($views, $data, $options, $saveData); |
||||||
| 490 | } |
||||||
| 491 | |||||||
| 492 | /** |
||||||
| 493 | * Utilisé dans les vues de mise en page pour inclure des vues supplémentaires si elle existe. |
||||||
| 494 | */ |
||||||
| 495 | public function insertFirst(array $views, ?array $data = [], ?array $options = null, ?bool $saveData = null): string |
||||||
| 496 | { |
||||||
| 497 | foreach ($views as $view) { |
||||||
| 498 | if ('' !== $output = $this->includeIf($view, $data, $options, $saveData)) { |
||||||
| 499 | return $output; |
||||||
| 500 | } |
||||||
| 501 | } |
||||||
| 502 | |||||||
| 503 | throw ViewException::invalidFile(implode(' OR ', $views)); |
||||||
| 504 | } |
||||||
| 505 | |||||||
| 506 | /** |
||||||
| 507 | * Compile de manière conditionnelle une chaîne de classe CSS. |
||||||
| 508 | */ |
||||||
| 509 | public function class(array $classes): string |
||||||
| 510 | { |
||||||
| 511 | if ($classes === []) { |
||||||
| 512 | return ''; |
||||||
| 513 | } |
||||||
| 514 | |||||||
| 515 | $class = []; |
||||||
| 516 | |||||||
| 517 | foreach ($classes as $key => $value) { |
||||||
| 518 | if (is_int($key)) { |
||||||
| 519 | $class[] = $value; |
||||||
| 520 | } elseif (true === $value) { |
||||||
| 521 | $class[] = $key; |
||||||
| 522 | } |
||||||
| 523 | } |
||||||
| 524 | |||||||
| 525 | return 'class="' . implode(' ', $class) . '"'; |
||||||
| 526 | } |
||||||
| 527 | |||||||
| 528 | /** |
||||||
| 529 | * Ajoute conditionnellement des styles CSS en ligne à un élément HTML |
||||||
| 530 | */ |
||||||
| 531 | public function style(array $styles): string |
||||||
| 532 | { |
||||||
| 533 | if ($styles === []) { |
||||||
| 534 | return ''; |
||||||
| 535 | } |
||||||
| 536 | |||||||
| 537 | $style = []; |
||||||
| 538 | |||||||
| 539 | foreach ($styles as $key => $value) { |
||||||
| 540 | if (is_int($key)) { |
||||||
| 541 | $style[] = $value . ';'; |
||||||
| 542 | } elseif (true === $value) { |
||||||
| 543 | $style[] = $key . ';'; |
||||||
| 544 | } |
||||||
| 545 | } |
||||||
| 546 | |||||||
| 547 | return 'style="' . implode(' ', $style) . '"'; |
||||||
| 548 | } |
||||||
| 549 | |||||||
| 550 | /** |
||||||
| 551 | * Utiliser pour indiquer facilement si une case à cocher HTML donnée est "cochée". |
||||||
| 552 | * Indiquera que la case est cochée si la condition fournie est évaluée à true. |
||||||
| 553 | */ |
||||||
| 554 | public function checked(bool|string $condition): string |
||||||
| 555 | { |
||||||
| 556 | return true === filter_var($condition, FILTER_VALIDATE_BOOLEAN) ? 'checked="checked"' : ''; |
||||||
| 557 | } |
||||||
| 558 | |||||||
| 559 | /** |
||||||
| 560 | * Utiliser pour indiquer si une option de sélection donnée doit être "sélectionnée". |
||||||
| 561 | */ |
||||||
| 562 | public function selected(bool|string $condition): string |
||||||
| 563 | { |
||||||
| 564 | return true === filter_var($condition, FILTER_VALIDATE_BOOLEAN) ? 'selected="selected"' : ''; |
||||||
| 565 | } |
||||||
| 566 | |||||||
| 567 | /** |
||||||
| 568 | * Utiliser pour indiquer si un élément donné doit être "désactivé". |
||||||
| 569 | */ |
||||||
| 570 | public function disabled(bool|string $condition): string |
||||||
| 571 | { |
||||||
| 572 | return true === filter_var($condition, FILTER_VALIDATE_BOOLEAN) ? 'disabled' : ''; |
||||||
| 573 | } |
||||||
| 574 | |||||||
| 575 | /** |
||||||
| 576 | * Utiliser pour indiquer si un élément donné doit être "readonly". |
||||||
| 577 | */ |
||||||
| 578 | public function readonly(bool|string $condition): string |
||||||
| 579 | { |
||||||
| 580 | return true === filter_var($condition, FILTER_VALIDATE_BOOLEAN) ? 'readonly' : ''; |
||||||
| 581 | } |
||||||
| 582 | |||||||
| 583 | /** |
||||||
| 584 | * Utiliser pour indiquer si un élément donné doit être "obligatoire". |
||||||
| 585 | */ |
||||||
| 586 | public function required(bool|string $condition): string |
||||||
| 587 | { |
||||||
| 588 | return true === filter_var($condition, FILTER_VALIDATE_BOOLEAN) ? 'required' : ''; |
||||||
| 589 | } |
||||||
| 590 | |||||||
| 591 | /** |
||||||
| 592 | * Génère un champ input caché à utiliser dans les formulaires générés manuellement. |
||||||
| 593 | */ |
||||||
| 594 | public function csrf(?string $id = null): string |
||||||
| 595 | { |
||||||
| 596 | return csrf_field($id); |
||||||
| 597 | } |
||||||
| 598 | |||||||
| 599 | /** |
||||||
| 600 | * Générer un champ de formulaire pour usurper le verbe HTTP utilisé par les formulaires. |
||||||
| 601 | */ |
||||||
| 602 | public function method(string $method): string |
||||||
| 603 | { |
||||||
| 604 | return method_field($method); |
||||||
| 605 | } |
||||||
| 606 | |||||||
| 607 | /** |
||||||
| 608 | * Ajoute un fichier css de librairie a la vue |
||||||
| 609 | */ |
||||||
| 610 | public function addLibCss(string ...$src): self |
||||||
| 611 | { |
||||||
| 612 | $this->_lib_styles = array_merge($this->_lib_styles, $src); |
||||||
| 613 | |||||||
| 614 | return $this; |
||||||
| 615 | } |
||||||
| 616 | |||||||
| 617 | /** |
||||||
| 618 | * Ajoute un fichier css a la vue |
||||||
| 619 | */ |
||||||
| 620 | public function addCss(string ...$src): self |
||||||
| 621 | { |
||||||
| 622 | $this->_styles = array_merge($this->_styles, $src); |
||||||
| 623 | |||||||
| 624 | return $this; |
||||||
| 625 | } |
||||||
| 626 | |||||||
| 627 | /** |
||||||
| 628 | * Compile les fichiers de style de l'instance et genere les link:href vers ceux-ci |
||||||
| 629 | */ |
||||||
| 630 | public function stylesBundle(): void |
||||||
| 631 | { |
||||||
| 632 | if ($this->_lib_styles !== []) { |
||||||
| 633 | lib_styles(array_unique($this->_lib_styles)); |
||||||
|
0 ignored issues
–
show
array_unique($this->_lib_styles) of type array is incompatible with the type list expected by parameter $name of lib_styles().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 634 | } |
||||||
| 635 | |||||||
| 636 | if ($this->_styles !== []) { |
||||||
| 637 | styles(array_unique($this->_styles)); |
||||||
|
0 ignored issues
–
show
array_unique($this->_styles) of type array is incompatible with the type list expected by parameter $name of styles().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 638 | } |
||||||
| 639 | |||||||
| 640 | $this->show('css'); |
||||||
| 641 | } |
||||||
| 642 | |||||||
| 643 | /** |
||||||
| 644 | * Ajoute un fichier js de librairie a la vue |
||||||
| 645 | */ |
||||||
| 646 | public function addLibJs(string ...$src): self |
||||||
| 647 | { |
||||||
| 648 | $this->_lib_scripts = array_merge($this->_lib_scripts, $src); |
||||||
| 649 | |||||||
| 650 | return $this; |
||||||
| 651 | } |
||||||
| 652 | |||||||
| 653 | /** |
||||||
| 654 | * Ajoute un fichier js a la vue |
||||||
| 655 | */ |
||||||
| 656 | public function addJs(string ...$src): self |
||||||
| 657 | { |
||||||
| 658 | $this->_scripts = array_merge($this->_scripts, $src); |
||||||
| 659 | |||||||
| 660 | return $this; |
||||||
| 661 | } |
||||||
| 662 | |||||||
| 663 | /** |
||||||
| 664 | * Compile les fichiers de script de l'instance et genere les link:href vers ceux-ci |
||||||
| 665 | */ |
||||||
| 666 | public function scriptsBundle(): void |
||||||
| 667 | { |
||||||
| 668 | if ($this->_lib_scripts !== []) { |
||||||
| 669 | lib_scripts(array_unique($this->_lib_scripts)); |
||||||
|
0 ignored issues
–
show
array_unique($this->_lib_scripts) of type array is incompatible with the type list expected by parameter $name of lib_scripts().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 670 | } |
||||||
| 671 | |||||||
| 672 | if ($this->_scripts !== []) { |
||||||
| 673 | scripts(array_unique($this->_scripts)); |
||||||
|
0 ignored issues
–
show
array_unique($this->_scripts) of type array is incompatible with the type list expected by parameter $name of scripts().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 674 | } |
||||||
| 675 | |||||||
| 676 | $this->show('js'); |
||||||
| 677 | } |
||||||
| 678 | |||||||
| 679 | protected function prepareTemplateData(bool $saveData): void |
||||||
| 680 | { |
||||||
| 681 | 6 | $this->tempData ??= $this->data; |
|||||
| 682 | |||||||
| 683 | if ($saveData) { |
||||||
| 684 | 6 | $this->data = $this->tempData; |
|||||
| 685 | } |
||||||
| 686 | } |
||||||
| 687 | |||||||
| 688 | private function retrievePartialPath(string $view): string |
||||||
| 689 | { |
||||||
| 690 | $current_dir = pathinfo($this->renderVars['file'] ?? '', PATHINFO_DIRNAME); |
||||||
| 691 | if (file_exists(rtrim($current_dir, DS) . DS . $view)) { |
||||||
|
0 ignored issues
–
show
It seems like
$current_dir can also be of type array; however, parameter $string of rtrim() does only seem to accept string, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 692 | $view = rtrim($current_dir, DS) . DS . $view; |
||||||
| 693 | } elseif (file_exists(rtrim($current_dir, DS) . DS . 'partials' . DS . $view)) { |
||||||
| 694 | $view = rtrim($current_dir, DS) . DS . 'partials' . DS . $view; |
||||||
| 695 | } elseif (file_exists($this->viewPath . 'partials' . DS . $view)) { |
||||||
| 696 | $view = $this->viewPath . 'partials' . DS . $view; |
||||||
| 697 | } elseif (file_exists($this->viewPath . trim(dirname($current_dir), '/\\') . DS . $view)) { |
||||||
|
0 ignored issues
–
show
It seems like
$current_dir can also be of type array; however, parameter $path of dirname() does only seem to accept string, maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||||
| 698 | $view = $this->viewPath . trim(dirname($current_dir), '/\\') . DS . $view; |
||||||
| 699 | } elseif (file_exists(VIEW_PATH . 'partials' . DS . $view)) { |
||||||
| 700 | $view = VIEW_PATH . 'partials' . DS . $view; |
||||||
| 701 | } elseif (file_exists(VIEW_PATH . trim(dirname($current_dir), '/\\') . DS . $view)) { |
||||||
| 702 | $view = VIEW_PATH . trim(dirname($current_dir), '/\\') . DS . $view; |
||||||
| 703 | } |
||||||
| 704 | |||||||
| 705 | return $view; |
||||||
| 706 | } |
||||||
| 707 | } |
||||||
| 708 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths