ProblemChecker.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. <?php
  2. namespace Grav\Plugin\Problems\Base;
  3. use Grav\Common\Cache;
  4. use Grav\Common\Grav;
  5. use RocketTheme\Toolbox\Event\Event;
  6. /**
  7. * Class ProblemChecker
  8. * @package Grav\Plugin\Problems\Base
  9. */
  10. class ProblemChecker
  11. {
  12. /** @var string */
  13. const PROBLEMS_PREFIX = 'problem-check-';
  14. /** @var array */
  15. protected $problems = [];
  16. /** @var string */
  17. protected $status_file;
  18. public function __construct()
  19. {
  20. /** @var Cache $cache */
  21. $cache = Grav::instance()['cache'];
  22. $this->status_file = CACHE_DIR . $this::PROBLEMS_PREFIX . $cache->getKey() . '.json';
  23. }
  24. /**
  25. * @return bool
  26. */
  27. public function load(): bool
  28. {
  29. if ($this->statusFileExists()) {
  30. $json = file_get_contents($this->status_file) ?: '';
  31. $data = json_decode($json, true);
  32. if (!is_array($data)) {
  33. return false;
  34. }
  35. foreach ($data as $problem) {
  36. $class = $problem['class'];
  37. $this->problems[] = new $class($problem);
  38. }
  39. }
  40. return true;
  41. }
  42. /**
  43. * @return string
  44. */
  45. public function getStatusFile():string
  46. {
  47. return $this->status_file;
  48. }
  49. /**
  50. * @return bool
  51. */
  52. public function statusFileExists(): bool
  53. {
  54. return file_exists($this->status_file);
  55. }
  56. /**
  57. * @return void
  58. */
  59. public function storeStatusFile(): void
  60. {
  61. $problems = $this->getProblemsSerializable();
  62. $json = json_encode($problems);
  63. file_put_contents($this->status_file, $json);
  64. }
  65. /**
  66. * @param string|null $problems_dir
  67. * @return bool
  68. */
  69. public function check($problems_dir = null): bool
  70. {
  71. $problems_dir = $problems_dir ?: dirname(__DIR__);
  72. $problems = [];
  73. $problems_found = false;
  74. $iterator = new \DirectoryIterator($problems_dir);
  75. foreach ($iterator as $file) {
  76. if (!$file->isFile() || $file->getExtension() !== 'php') {
  77. continue;
  78. }
  79. $classname = 'Grav\\Plugin\\Problems\\' . $file->getBasename('.php');
  80. if (class_exists($classname)) {
  81. /** @var Problem $problem */
  82. $problem = new $classname();
  83. $problems[$problem->getId()] = $problem;
  84. }
  85. }
  86. // Fire event to allow other plugins to add problems
  87. Grav::instance()->fireEvent('onProblemsInitialized', new Event(['problems' => $problems]));
  88. // Get the problems in order
  89. usort($problems, function($a, $b) {
  90. /** @var Problem $a */
  91. /** @var Problem $b */
  92. return $b->getOrder() - $a->getOrder();
  93. });
  94. // run the process methods in new order
  95. foreach ($problems as $problem) {
  96. $problem->process();
  97. if ($problem->getStatus() === false && $problem->getLevel() === Problem::LEVEL_CRITICAL) {
  98. $problems_found = true;
  99. }
  100. }
  101. $this->problems = $problems;
  102. return $problems_found;
  103. }
  104. /**
  105. * @return array
  106. */
  107. public function getProblems(): array
  108. {
  109. if (empty($this->problems)) {
  110. $this->check();
  111. }
  112. $problems = $this->problems;
  113. // Put the failed ones first
  114. usort($problems, function($a, $b) {
  115. /** @var Problem $a */
  116. /** @var Problem $b */
  117. return $a->getStatus() - $b->getStatus();
  118. });
  119. return $problems;
  120. }
  121. /**
  122. * @return array
  123. */
  124. public function getProblemsSerializable(): array
  125. {
  126. if (empty($this->problems)) {
  127. $this->getProblems();
  128. }
  129. $problems = [];
  130. foreach ($this->problems as $problem) {
  131. $problems[] = $problem->toArray();
  132. }
  133. return $problems;
  134. }
  135. }