learnosity-1.0.x-dev/src/Plugin/EntityReferenceSelection/LearnosityActivitySelection.php
src/Plugin/EntityReferenceSelection/LearnosityActivitySelection.php
<?php
namespace Drupal\learnosity\Plugin\EntityReferenceSelection;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\EntityFieldManagerInterface;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionPluginBase;
use Drupal\Core\Entity\EntityReferenceSelection\SelectionWithAutocreateInterface;
use Drupal\Core\Entity\EntityRepositoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\user\EntityOwnerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides specific access control for the learnosity activity entity type.
*
* @EntityReferenceSelection(
* id = "default:learnosity",
* label = @Translation("Learnosity activities"),
* entity_types = {"learnosity_activity"},
* group = "default",
* weight = 1
* )
*/
class LearnosityActivitySelection extends SelectionPluginBase implements SelectionWithAutocreateInterface, ContainerFactoryPluginInterface {
/**
* The entity manager service.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* The current user.
*
* @var \Drupal\Core\Session\AccountInterface
*/
protected $currentUser;
/**
* The entity field manager.
*
* @var \Drupal\Core\Entity\EntityFieldManagerInterface
*/
protected $entityFieldManager;
/**
* The entity repository.
*
* @var \Drupal\Core\Entity\EntityRepositoryInterface
*/
protected $entityRepository;
/**
* Constructs a new LearnosityActivitySelection object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity manager service.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler service.
* @param \Drupal\Core\Session\AccountInterface $current_user
* The current user.
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
* The entity field manager.
* @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository
* The entity repository.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler, AccountInterface $current_user, EntityFieldManagerInterface $entity_field_manager = NULL, EntityRepositoryInterface $entity_repository = NULL) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
$this->moduleHandler = $module_handler;
$this->currentUser = $current_user;
$this->entityFieldManager = $entity_field_manager;
$this->entityRepository = $entity_repository;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('entity_type.manager'),
$container->get('module_handler'),
$container->get('current_user'),
$container->get('entity_field.manager'),
$container->get('entity.repository')
);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
// For the 'target_bundles' setting, a NULL value is equivalent to "allow
// entities from any bundle to be referenced" and an empty array value is
// equivalent to "no entities from any bundle can be referenced".
'target_type' => NULL,
'handler' => $this->getPluginId(),
'entity' => NULL,
];
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form['#markup'] = $this->t('No handler settings for this field type.');
return $form;
}
/**
* Builds an EntityQuery to get referenceable entities.
*
* @param string|null $match
* (Optional) Text to match the label against. Defaults to NULL.
* @param string $match_operator
* (Optional) The operation the matching should be done with. Defaults
* to "CONTAINS".
*
* @return \Drupal\Core\Entity\Query\QueryInterface
* The EntityQuery object with the basic conditions and sorting applied to
* it.
*/
protected function buildEntityQuery($match = NULL, $match_operator = 'CONTAINS') {
// Removing the restriction on target bundles in the query. This was causing
// a fatal error as well as restricting how the activity types could be
// used. We are only using activity types to control how the player is
// rendered to the user. It doesn't need the hard restriction like with
// entity reference fields.
$configuration = $this->getConfiguration();
$target_type = $configuration['target_type'];
$entity_type = $this->entityTypeManager->getDefinition($target_type);
$query = $this->entityTypeManager->getStorage($target_type)->getQuery();
$query->accessCheck(TRUE);
if (isset($match) && $label_key = $entity_type->getKey('label')) {
$query->condition($label_key, $match, $match_operator);
}
// Add entity-access tag.
$query->addTag($target_type . '_access');
// Add the Selection handler for system_query_entity_reference_alter().
$query->addTag('entity_reference');
$query->addMetaData('entity_reference_selection_handler', $this);
return $query;
}
/**
* {@inheritdoc}
*/
public function getReferenceableEntities($match = NULL, $match_operator = 'CONTAINS', $limit = 0) {
$target_type = $this->getConfiguration()['target_type'];
$query = $this->buildEntityQuery($match, $match_operator);
if ($limit > 0) {
$query->range(0, $limit);
}
$result = $query->execute();
if (empty($result)) {
return [];
}
$options = [];
$entities = $this->entityTypeManager->getStorage($target_type)->loadMultiple($result);
foreach ($entities as $entity_id => $entity) {
$options[$entity_id] = Html::escape($this->entityRepository->getTranslationFromContext($entity)->label());
}
return $options;
}
/**
* {@inheritdoc}
*/
public function validateReferenceableNewEntities(array $entities) {
// We're always returning this as true because we don't need to
// validate against bundles.
return array_filter($entities, function ($entity) {
return TRUE;
});
}
/**
* {@inheritdoc}
*/
public function countReferenceableEntities($match = NULL, $match_operator = 'CONTAINS') {
$query = $this->buildEntityQuery($match, $match_operator);
return $query
->count()
->execute();
}
/**
* {@inheritdoc}
*/
public function createNewEntity($entity_type_id, $bundle, $label, $uid) {
// Note: Bundle is deliberately not used because LearnosityActivity entity
// does not support bundles.
$entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
$values = [
$entity_type->getKey('label') => $label,
];
$entity = $this->entityTypeManager->getStorage($entity_type_id)->create($values);
if ($entity instanceof EntityOwnerInterface) {
$entity->setOwnerId($uid);
}
return $entity;
}
/**
* {@inheritdoc}
*/
public function validateReferenceableEntities(array $ids) {
$result = [];
if ($ids) {
$target_type = $this->configuration['target_type'];
$entity_type = $this->entityTypeManager->getDefinition($target_type);
$query = $this->buildEntityQuery();
$result = $query
->condition($entity_type->getKey('id'), $ids, 'IN')
->execute();
}
return $result;
}
/**
* Form element validation handler; Filters the #value property of an element.
*/
public static function elementValidateFilter(&$element, FormStateInterface $form_state) {
// For single values (such as with select lists), make sure that it saves
// it as an array.
if (is_string($element['#value'])) {
$element['#value'] = [$element['#value']];
}
else {
$element['#value'] = array_filter($element['#value']);
}
$form_state->setValueForElement($element, $element['#value']);
}
}
