reviewer-1.2.x-dev/src/Reviewer/Review/ReviewBuilder.php
src/Reviewer/Review/ReviewBuilder.php
<?php
declare(strict_types=1);
namespace Drupal\reviewer\Reviewer\Review;
use Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException;
use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Component\Plugin\Exception\PluginNotFoundException;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\reviewer\Attribute\Review;
use Drupal\reviewer\Exception\AttributeMissingException;
use Drupal\reviewer\Plugin\reviewer\BuildableInterface;
use Drupal\reviewer\Plugin\reviewer\Review\ReviewPluginInterface;
use Drupal\reviewer\Plugin\ReviewManagerInterface;
use Drupal\reviewer\Reviewer\BundleEvaluatorInterface;
use Drupal\reviewer\Reviewer\Checklist\ChecklistFactoryInterface;
/**
* Builds runnable reviews from review plugins.
*/
final readonly class ReviewBuilder implements ReviewBuilderInterface {
// phpcs:ignore Drupal.Commenting.FunctionComment.Missing
public function __construct(
private BundleEvaluatorInterface $bundleEvaluator,
private ChecklistFactoryInterface $checklistFactory,
private EntityTypeManagerInterface $entityTypeManager,
private ReviewFactoryInterface $reviewFactory,
private ReviewManagerInterface $reviewManager,
) {}
/**
* {@inheritdoc}
*/
public function fromClass(string $runnable_plugin_class): array {
$reflection = new \ReflectionClass($runnable_plugin_class);
$attributes = $reflection->getAttributes(Review::class);
$plugin_attribute = reset($attributes);
if (!$plugin_attribute) {
throw new AttributeMissingException(Review::class, $runnable_plugin_class);
}
return $this->fromId($plugin_attribute->newInstance()->getId());
}
/**
* {@inheritdoc}
*/
public function fromClasses(array $runnable_plugin_classes): array {
$built = [];
foreach ($runnable_plugin_classes as $runnable_plugin_class) {
$built += $this->fromClass($runnable_plugin_class);
}
return $built;
}
/**
* {@inheritdoc}
*/
public function fromId(string $runnable_plugin_id, string $id = ''): array {
try {
$buildable_plugin = $this->reviewManager->createInstance(
$runnable_plugin_id,
$this->reviewManager->getDefinition($runnable_plugin_id),
);
return $this->fromPlugin($buildable_plugin, $id);
}
catch (PluginNotFoundException | PluginException) {
}
return [];
}
/**
* {@inheritdoc}
*/
public function fromIds(array $runnable_plugin_ids, string $id = ''): array {
$built = [];
foreach ($runnable_plugin_ids as $runnable_plugin_id) {
$built += $this->fromId($runnable_plugin_id, $id);
}
return $built;
}
/**
* {@inheritdoc}
*/
public function fromPlugin(
BuildableInterface $plugin,
string $id = '',
): array {
assert($plugin instanceof ReviewPluginInterface);
$reviews = [];
if ($plugin->getConfigEntityId()) {
foreach ($this->bundleEvaluator->allBundlesOfReview($plugin) as $bundle) {
$bundle_id = $id ?: "{$plugin->getPluginId()}.$bundle";
$checklists = array_map(
fn(string $checklist) => $this->checklistFactory->create($checklist),
$plugin->getChecklists(),
);
/** @var \Drupal\Core\Config\Entity\ConfigEntityInterface|null $config_entity */
$config_entity = $this
->entityTypeManager
->getStorage($plugin->getConfigEntityId())
->load($bundle);
$reviews[$bundle_id] = $this->reviewFactory->create(
$bundle_id,
$this->labelWithBundle($plugin, $bundle),
$checklists,
$plugin->getIgnored(),
$config_entity,
);
}
}
else {
$checklists = array_map(
fn(string $checklist) => $this->checklistFactory->create($checklist),
$plugin->getChecklists(),
);
$reviews[$id ?: $plugin->getPluginId()] = $this->reviewFactory->create(
$id ?: $plugin->getPluginId(),
$plugin->getLabel(),
$checklists,
$plugin->getIgnored(),
);
}
foreach ($reviews as $review) {
foreach ($review->getChecklists() as $checklist) {
$checklist->setReview($review);
}
}
return $reviews;
}
/**
* {@inheritdoc}
*/
public function fromPlugins(array $plugins, string $id = ''): array {
$built = [];
/** @var \Drupal\reviewer\Plugin\reviewer\BuildableInterface&\Drupal\reviewer\Plugin\reviewer\Review\ReviewPluginInterface $plugin */
foreach ($plugins as $plugin) {
$built += $this->fromPlugin($plugin, $id);
}
return $built;
}
/**
* Add the bundle label to a review plugin label.
*/
private function labelWithBundle(
ReviewPluginInterface $review,
string $bundle,
): string {
$entity_type = $review->getConfigEntityId();
if ($entity_type) {
try {
$entity = $this->entityTypeManager->getStorage($entity_type)->load($bundle);
if ($entity) {
return sprintf(
'%s: %s',
$review->getLabel(),
$entity->label(),
);
}
}
catch (InvalidPluginDefinitionException | PluginNotFoundException) {
}
}
return $review->getLabel();
}
}
