reviewer-1.2.x-dev/src/Reviewer/Ignorer.php
src/Reviewer/Ignorer.php
<?php
declare(strict_types=1);
namespace Drupal\reviewer\Reviewer;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\reviewer\Exception\NotIgnoredException;
use Drupal\reviewer\Plugin\ReviewManagerInterface;
use Drupal\reviewer\Reviewer\Result\ResultInterface;
use Drupal\reviewer\Reviewer\Status\StatusEvaluatorInterface;
/**
* Ignores review results.
*/
final readonly class Ignorer implements IgnorerInterface {
// phpcs:ignore Drupal.Commenting.FunctionComment.Missing
public function __construct(
private ConfigFactoryInterface $configFactory,
private ReviewManagerInterface $reviewManager,
private StatusEvaluatorInterface $statusEvaluator,
) {}
/**
* {@inheritdoc}
*/
public function getIgnored(): array {
return array_merge($this->getCodeIgnored(), $this->getConfigIgnored());
}
/**
* {@inheritdoc}
*/
public function getCodeIgnored(): array {
$ignored = [];
foreach ($this->reviewManager->createAllInstances() as $review_plugin) {
$ignored = array_merge($ignored, $review_plugin->getIgnored());
}
return $ignored;
}
/**
* {@inheritdoc}
*/
public function getConfigIgnored(): array {
// This is an array because the schema says so.
// @phpstan-ignore-next-line
return $this->configFactory->get('reviewer.settings')->get('ignored') ?: [];
}
/**
* {@inheritdoc}
*/
public function isIgnored(ResultInterface|string $result): bool {
return $this->isCodeIgnored($result) || $this->isConfigIgnored($result);
}
/**
* {@inheritdoc}
*/
public function isCodeIgnored(ResultInterface|string $result): bool {
$result_id = \is_string($result) ? $result : $result->getId();
$code_ignored_ids = $this->ignoredIds($this->getCodeIgnored());
return \in_array($result_id, $code_ignored_ids, TRUE);
}
/**
* {@inheritdoc}
*/
public function isConfigIgnored(ResultInterface|string $result): bool {
$result_id = \is_string($result) ? $result : $result->getId();
$config_ignored_ids = $this->ignoredIds($this->getConfigIgnored());
return \in_array($result_id, $config_ignored_ids, TRUE);
}
/**
* {@inheritdoc}
*/
public function ignoredReason(ResultInterface|string $result): string {
$result_id = \is_string($result) ? $result : $result->getId();
if (!$this->isIgnored($result_id)) {
throw new NotIgnoredException($result_id);
}
foreach ($this->getIgnored() as $ignored) {
if ($result_id === $ignored['id']) {
return $ignored['reason'];
}
}
return '';
}
/**
* {@inheritdoc}
*/
public function ignoredResults(array $results): array {
return array_filter(
$results,
fn(ResultInterface $result) => $this->statusEvaluator->isIgnored($result->getStatus()),
);
}
/**
* {@inheritdoc}
*/
public function unignoredResults(array $results): array {
return array_filter(
$results,
fn(ResultInterface $result) => !$this->statusEvaluator->isIgnored($result->getStatus()),
);
}
/**
* {@inheritdoc}
*/
public function ignore(
ResultInterface|string $result,
string $reason = '',
): void {
if ($this->isCodeIgnored($result)) {
return;
}
if ($this->isConfigIgnored($result)) {
$this->unignore($result);
}
$result_id = \is_string($result) ? $result : $result->getId();
$ignored = $this->getConfigIgnored();
$ignored[] = [
'id' => $result_id,
'reason' => $reason,
];
$this->setIgnored($ignored);
}
/**
* {@inheritdoc}
*/
public function unignore(ResultInterface|array|string $results): void {
$ignored = $this->getConfigIgnored();
if (!\is_array($results)) {
$results = [$results];
}
foreach ($results as $result) {
$result_id = \is_string($result) ? $result : $result->getId();
$ignored = array_filter(
$ignored,
fn(array $row) => $row['id'] !== $result_id,
);
}
$this->setIgnored($ignored);
}
/**
* {@inheritdoc}
*/
public function unignoreAll(): void {
$this->setIgnored([]);
}
/**
* Set the ignored IDs configuration values.
*
* @param array{id: string, reason: string}[] $ignored
*/
private function setIgnored(array $ignored): void {
usort(
$ignored,
fn(array $a, array $b) => strcasecmp($a['id'], $b['id']),
);
$this
->configFactory
->getEditable('reviewer.settings')
->set('ignored', $ignored)
->save();
}
/**
* Get a list of all ignored IDs from ignored rows.
*
* @param array{id: string, reason: string}[] $ignored
*
* @return string[]
*/
private function ignoredIds(array $ignored): array {
return array_map(
fn(array $ignored_item) => $ignored_item['id'],
$ignored,
);
}
}
