Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- /**
- * @file
- * Contains \Drupal\mymodule\Forms\ManageEntitiesBaseForm.
- */
- namespace Drupal\mymodule\Form;
- use Drupal\Core\Form\FormBase;
- use Drupal\Core\Entity\EntityInterface;
- use Drupal\Core\Form\FormStateInterface;
- use Drupal\Core\Entity\EntityManager;
- use Symfony\Component\DependencyInjection\ContainerInterface;
- use Drupal\Component\Plugin\CategorizingPluginManagerInterface;
- /**
- * Defines base for administering entities.
- */
- abstract class ManageEntitiesBaseForm extends FormBase {
- /**
- * The Entity Manager.
- *
- * @var \Drupal\Core\Entity\EntityManager
- */
- protected $entityManager;
- /**
- * The action plugin manager.
- *
- * @var \Drupal\Core\Action\ActionManager
- */
- protected $actionManager;
- /**
- * The original query used to load the entities without any filters applied.
- *
- * @var \Drupal\Core\Entity\Query\QueryInterface
- */
- private $original_query;
- /**
- * The query used to load the entities with applied filters, if any.
- *
- * @var \Drupal\Core\Entity\Query\QueryInterface
- */
- private $query;
- /**
- * The total amount of entities matching the current filter criteria.
- *
- * @var int
- */
- private $all_entities_count = 0;
- /**
- * List of allowed actions.
- *
- * @var array
- */
- private $actions = array();
- /**
- * Constructs a ManageEntitiesBaseForm object.
- *
- * @param \Drupal\Core\Entity\EntityManager $entity_manager
- * The entity manager.
- * @param \Drupal\Component\Plugin\CategorizingPluginManagerInterface $action_manager
- * The action manager.
- */
- public function __construct(EntityManager $entity_manager, CategorizingPluginManagerInterface $action_manager) {
- $this->entityManager = $entity_manager;
- $this->actionManager = $action_manager;
- $this->initializeQuery();
- }
- /**
- * {@inheritdoc}
- */
- public static function create(ContainerInterface $container) {
- return new static(
- $container->get('entity.manager'),
- $container->get('plugin.manager.action')
- );
- }
- /**
- * {@inheritdoc}
- */
- public function getFormId() {
- $class = explode('\\', get_called_class());
- $class = end($class);
- return strtolower(preg_replace('/(?<!^)([A-Z])/', '_\\1', $class));
- }
- /**
- * Get the entity type id.
- *
- * @return string
- */
- abstract public function getEntityType();
- /**
- * Returns renderable elements for one entity entry entry.
- * Each element represents one column.
- *
- * @param \Drupal\Core\Entity\EntityInterface $entity
- * The entity to display the elements for.
- *
- * @return array
- * Returns array of renderable form elements.
- */
- abstract public function buildEntry(EntityInterface $entity);
- /**
- * Get the table headers.
- * Each field that wants to be used for sorting needs to define the
- * 'field' and 'specifier' values and the 'data' is used as label.
- * The field that should be used as default sorting filter has to
- * define the 'sort' value which can be 'asc' or 'desc'.
- *
- * @see \Drupal\Core\Entity\Query\QueryInterface::tableSort
- *
- * @return array
- * List of headers with keys corresponding with those returned
- * by the buildEntry() method.
- */
- abstract public function headers();
- /**
- * Returns the table headers with the 'select all' checkbox.
- *
- * @return array
- */
- final public function getHeaders() {
- $headers = $this->headers();
- // Make sure there are headers.
- if (empty($headers)) {
- return array();
- }
- // Make sure at least one column has 'sort' set, otherwise the first column
- // would be used for sorting, which in this case is a checkbox and it would
- // thrown an error.
- $has_sort = FALSE;
- foreach ($headers AS $header) {
- if (isset($header['sort'])) {
- $has_sort = TRUE;
- break;
- }
- }
- if (!$has_sort) {
- reset($headers);
- $column = key($headers);
- $headers[$column]['sort'] = 'desc';
- }
- return array_merge(
- array(
- 'identifier' => array(
- 'data' => array(
- '#type' => 'checkbox'
- )
- )
- ),
- $headers
- );
- }
- /**
- * Returns the entity query for the current entity type.
- *
- * In case any default filtering is need the extendeding classes
- * should override this method.
- *
- * @return \Drupal\Core\Entity\Query\QueryInterface
- */
- public function getQuery() {
- return $this->entityManager->getStorage($this->getEntityType())->getQuery();
- }
- /**
- * Sets the un-executed query object used to retrieve the entities.
- * When executed the \Drupal\Core\Database\StatementInterface::fetchCol()
- * method has to return a sorted list of entity IDs.
- */
- final protected function initializeQuery() {
- // Since we do not want to load the entities right away we need
- // to use the original query.
- $query = $this->getQuery();
- // Apply table sort.
- $headers = $this->getHeaders();
- $query->tableSort($headers);
- // Apply pager.
- $query->pager(15);
- // Save the query.
- // Clone the query since we're about to count the number of all entities
- // and that changes the whole query into a count query instead of returning
- // a cloned object.
- // @see \Drupal\Core\Entity\Query\QueryInterface::count().
- $this->query = clone $query;
- // Save the query again, but this query cannot be altered by filters.
- $this->original_query = clone $query;
- // Compute the number of all entities matching the current filter criteria.
- $this->all_entities_count = $query->count()->execute();
- }
- /**
- * Attaches checkbox identifier to one entry.
- *
- * @param array $entry
- * The array with elements of one entry.
- *
- * @return array
- * Renderable array of element for one entry with attached identifier.
- */
- public function attachIdentifier(array $entry) {
- return array_merge(
- array(
- 'identifier' => array(
- '#type' => 'checkbox'
- )
- ),
- $entry
- );
- }
- /**
- * Return the list of specifically allowed actions.
- *
- * @return array
- */
- final public function getActions() {
- return $this->actions;
- }
- /**
- * Set a list of specifically allowed actions.
- *
- * @param array $actions
- */
- final public function setActions(array $actions) {
- $this->actions = $actions;
- }
- /**
- * Add a specifically allowed action.
- *
- * @param string $action
- * The machine name of the action.
- */
- final public function addAction($action) {
- if (!in_array($action, $this->actions)) {
- $this->actions[] = $action;
- }
- }
- /**
- * Load the action entities.
- * If there are a specifically allowed actions then those will be loaded
- * if they match the type of the entity.
- * Otherwise all actions for the used entity type will be loaded.
- *
- * @return \Drupal\Core\Entity\EntityInterface[]
- */
- final public function loadActions() {
- $actions = empty($this->actions)
- ? array_keys($this->actionManager->getDefinitionsByType($this->getEntityType()))
- : $this->actions;
- return $this->entityManager->getStorage('action')->loadByProperties(array(
- 'plugin' => $actions,
- // In case actions were provided, make sure they work with proper type.
- 'type' => $this->getEntityType()
- ));
- }
- /**
- * Returns the message that will be displayed in case there are no results.
- *
- * @return string
- */
- public function emptyMessage() {
- return $this->t('There are no results to display.');
- }
- /**
- * {@inheritdoc}
- */
- public function buildForm(array $form, FormStateInterface $form_state) {
- // Add helper class to identify these forms.
- $form['#attributes']['class'][] = 'manage-entities-form';
- // Get the IDs.
- $ids = $this->query->execute();
- // Add actions if there is at least one and if there are entities available.
- if (!empty($ids)) {
- $actions = $this->loadActions();
- if (!empty($actions)) {
- $form['actions_wrapper'] = array(
- '#type' => 'fieldset',
- '#title' => $this->t('Bulk operations')
- );
- $form['actions_wrapper']['action'] = array(
- '#type' => 'select',
- '#title' => $this->t('Action'),
- '#options' => array_map(function ($action) {
- return $action->label();
- }, $actions)
- );
- // In order to avoid ajax rebuilds we will insert configuration per each
- // configurable action.
- $form['actions_wrapper']['configuration'] = array('#tree' => TRUE);
- foreach ($actions AS $action) {
- if ($action->getPlugin() instanceof \Drupal\Core\Action\ConfigurableActionBase) {
- $form['actions_wrapper']['configuration'][$action->id()] =
- $action->getPlugin()->buildConfigurationForm($form, $form_state);
- $form['actions_wrapper']['configuration'][$action->id()]['#states'] =
- array(
- 'visible' => array(
- 'select[name="action"]' => array('value' => $action->id())
- )
- );
- }
- }
- $form['actions_wrapper']['buttons']['apply_to_selected'] = array(
- '#type' => 'submit',
- '#value' => t('Apply to selected items'),
- '#states' => array(
- 'visible' => array(
- ':input[name$="][identifier]"]' => array('checked' => TRUE)
- )
- )
- );
- $form['actions_wrapper']['buttons']['apply_to_all'] = array(
- '#type' => 'submit',
- '#value' => t('Apply to all @count items', array('@count' => $this->all_entities_count))
- );
- }
- }
- // Load the entities.
- $entities = $this->entityManager->getStorage($this->getEntityType())->loadMultiple($ids);
- // Transform entities into renderable arrays.
- $entities = array_map(array($this, 'buildEntry'), $entities);
- // Add identifier for each entry.
- $entities = array_map(array($this, 'attachIdentifier'), $entities);
- // Create table.
- $form['entities'] = array(
- '#type' => 'table',
- '#header' => $this->getHeaders(),
- '#empty' => $this->emptyMessage()
- ) + $entities;
- $form['pager'] = array(
- '#type' => 'pager'
- );
- return $form;
- }
- /**
- * {@inheritdoc}
- */
- public function submitForm(array &$form, FormStateInterface $form_state) {
- dsm($form_state->getValues());
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement