SimplePageHandler.php 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. <?php
  2. /**
  3. * @package Grav\Common\Errors
  4. *
  5. * @copyright Copyright (c) 2015 - 2023 Trilby Media, LLC. All rights reserved.
  6. * @license MIT License; see LICENSE file for details.
  7. */
  8. namespace Grav\Common\Errors;
  9. use ErrorException;
  10. use InvalidArgumentException;
  11. use RuntimeException;
  12. use Whoops\Handler\Handler;
  13. use Whoops\Util\Misc;
  14. use Whoops\Util\TemplateHelper;
  15. /**
  16. * Class SimplePageHandler
  17. * @package Grav\Common\Errors
  18. */
  19. class SimplePageHandler extends Handler
  20. {
  21. /** @var array */
  22. private $searchPaths = [];
  23. /** @var array */
  24. private $resourceCache = [];
  25. public function __construct()
  26. {
  27. // Add the default, local resource search path:
  28. $this->searchPaths[] = __DIR__ . '/Resources';
  29. }
  30. /**
  31. * @return int
  32. */
  33. public function handle()
  34. {
  35. $inspector = $this->getInspector();
  36. $helper = new TemplateHelper();
  37. $templateFile = $this->getResource('layout.html.php');
  38. $cssFile = $this->getResource('error.css');
  39. $code = $inspector->getException()->getCode();
  40. if (($code >= 400) && ($code < 600)) {
  41. $this->getRun()->sendHttpCode($code);
  42. }
  43. $message = $inspector->getException()->getMessage();
  44. if ($inspector->getException() instanceof ErrorException) {
  45. $code = Misc::translateErrorCode($code);
  46. }
  47. $vars = array(
  48. 'stylesheet' => file_get_contents($cssFile),
  49. 'code' => $code,
  50. 'message' => htmlspecialchars(strip_tags(rawurldecode($message)), ENT_QUOTES, 'UTF-8'),
  51. );
  52. $helper->setVariables($vars);
  53. $helper->render($templateFile);
  54. return Handler::QUIT;
  55. }
  56. /**
  57. * @param string $resource
  58. * @return string
  59. * @throws RuntimeException
  60. */
  61. protected function getResource($resource)
  62. {
  63. // If the resource was found before, we can speed things up
  64. // by caching its absolute, resolved path:
  65. if (isset($this->resourceCache[$resource])) {
  66. return $this->resourceCache[$resource];
  67. }
  68. // Search through available search paths, until we find the
  69. // resource we're after:
  70. foreach ($this->searchPaths as $path) {
  71. $fullPath = "{$path}/{$resource}";
  72. if (is_file($fullPath)) {
  73. // Cache the result:
  74. $this->resourceCache[$resource] = $fullPath;
  75. return $fullPath;
  76. }
  77. }
  78. // If we got this far, nothing was found.
  79. throw new RuntimeException(
  80. "Could not find resource '{$resource}' in any resource paths (searched: " . implode(', ', $this->searchPaths). ')'
  81. );
  82. }
  83. /**
  84. * @param string $path
  85. * @return void
  86. */
  87. public function addResourcePath($path)
  88. {
  89. if (!is_dir($path)) {
  90. throw new InvalidArgumentException(
  91. "'{$path}' is not a valid directory"
  92. );
  93. }
  94. array_unshift($this->searchPaths, $path);
  95. }
  96. /**
  97. * @return array
  98. */
  99. public function getResourcePaths()
  100. {
  101. return $this->searchPaths;
  102. }
  103. }