diff --git a/entityqueue.routing.yml b/entityqueue.routing.yml index c576bf4..7f3e64d 100644 --- a/entityqueue.routing.yml +++ b/entityqueue.routing.yml @@ -64,20 +64,20 @@ entity.entity_subqueue.add_form: requirements: _entity_create_access: 'entity_subqueue:{entity_queue}' -entity.entity_subqueue.add: - path: '/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}/{entity}/add' +entity.entity_subqueue.add_item: + path: '/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}/{entity}/add-item' defaults: - _controller: '\Drupal\entityqueue\Controller\EntityQueueEntityController::subqueueAjaxOperation' - op: add + _controller: '\Drupal\entityqueue\Controller\EntityQueueUIController::subqueueAjaxOperation' + op: addItem requirements: _permission: 'administer entityqueue+manipulate entityqueues+manipulate all entityqueues' _csrf_token: 'TRUE' -entity.entity_subqueue.remove: - path: '/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}/{entity}/remove' +entity.entity_subqueue.remove_item: + path: '/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}/{entity}/remove-item' defaults: - _controller: '\Drupal\entityqueue\Controller\EntityQueueEntityController::subqueueAjaxOperation' - op: remove + _controller: '\Drupal\entityqueue\Controller\EntityQueueUIController::subqueueAjaxOperation' + op: removeItem requirements: _permission: 'administer entityqueue+manipulate entityqueues+manipulate all entityqueues' _csrf_token: 'TRUE' diff --git a/src/Controller/EntityQueueEntityController.php b/src/Controller/EntityQueueEntityController.php deleted file mode 100644 index c95cb41..0000000 --- a/src/Controller/EntityQueueEntityController.php +++ /dev/null @@ -1,142 +0,0 @@ -getParameter($entity_type_id); - $subqueues = EntitySubqueue::loadMultiple(); - $list_builder = $this->entityTypeManager()->getListBuilder('entity_queue'); - - $build['#type'] = 'container'; - $build['#attributes']['id'] = 'entity-queue-list'; - $build['#attached']['library'][] = 'core/drupal.ajax'; - $build['table'] = array( - '#type' => 'table', - '#attributes' => array( - 'class' => array('entity-queue-listing-table'), - ), - '#header' => $list_builder->buildHeader(), - '#rows' => array(), - '#cache' => [], - ); - - foreach ($subqueues as $subqueue) { - $queue = $subqueue->getQueue(); - $queue_settings = $queue->getEntitySettings(); - $target_bundles = !empty($queue_settings['handler_settings']['target_bundles']) ? $queue_settings['handler_settings']['target_bundles'] : []; - if ($queue_settings['target_type'] == $entity_type_id && (empty($target_bundles) || in_array($entity->bundle(), $target_bundles))) { - $row = $list_builder->buildRow($queue); - // Check if entity is in queue - $subqueue_items = $subqueue->get('items')->getValue(); - if(in_array($entity->id(), array_column($subqueue_items, 'target_id'))) { - $row['data']['operations']['data']['#links'] = [ - 'remove' => [ - 'title' => $this->t('Remove from queue'), - 'url' => $subqueue->urlInfo('remove'), - 'attributes' => [ - 'class' => ['use-ajax'], - ], - ], - ]; - } - else { - $row['data']['operations']['data']['#links'] = [ - 'add' => [ - 'title' => $this->t('Add to queue'), - 'url' => $subqueue->urlInfo('add'), - 'attributes' => [ - 'class' => ['use-ajax'], - ], - ], - ]; - } - $build['table']['#rows'][$queue->id()] = $row; - } - } - $build['table']['#empty'] = $this->t('There are no available queues.'); - - return $build; - } - - /** - * Calls a method on an entity subqueue page and reloads the page. - * - * @param \Drupal\entityqueue\EntitySubqueueInterface $entity_subqueue - * The view being acted upon. - * @param string $op - * The operation to perform, e.g., 'add' or 'remove'. - * @param \Symfony\Component\HttpFoundation\Request $request - * The current request. - * - * @return \Drupal\Core\Ajax\AjaxResponse|\Symfony\Component\HttpFoundation\RedirectResponse - * Either returns a rebuilt listing page as an AJAX response, or redirects - * back to the subqueue page. - */ - public function subqueueAjaxOperation(EntitySubqueueInterface $entity_subqueue, $op, Request $request) { - $entity_id = $request->get('entity'); - // Perform the operation. - $entity_subqueue->$op($entity_id)->save(); - //TODO: change to replace command instead of reload. - $response = new AjaxResponse(); - $response->addCommand(new RedirectCommand('')); - return $response; - } - - /** - * Checks access for a specific request. - * - * @param \Drupal\Core\Routing\RouteMatchInterface $route_match - * The route match. - * @param string $entity_type_id - * (optional) The entity type ID. - * - * @return \Drupal\Core\Access\AccessResultInterface - * The access result. - */ - public function access(RouteMatchInterface $route_match, $entity_type_id = NULL) { - /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ - $entity = $route_match->getParameter($entity_type_id); - $lol = $entity; - $subqueues = EntitySubqueue::loadMultiple(); - foreach ($subqueues as $subqueue) { - $queue = $subqueue->getQueue(); - $queue_settings = $queue->getEntitySettings(); - $target_bundles = !empty($queue_settings['handler_settings']['target_bundles']) ? $queue_settings['handler_settings']['target_bundles'] : []; - if ($queue_settings['target_type'] == $entity_type_id && (empty($target_bundles) || in_array($entity->bundle(), $target_bundles))) { - return AccessResult::allowedIf(TRUE); - } - } - - return AccessResult::allowedIf(FALSE); - } - -} diff --git a/src/Controller/EntityQueueUIController.php b/src/Controller/EntityQueueUIController.php index 5c41ac2..3b38a16 100644 --- a/src/Controller/EntityQueueUIController.php +++ b/src/Controller/EntityQueueUIController.php @@ -7,7 +7,14 @@ use Drupal\entityqueue\EntityQueueInterface; use Symfony\Component\HttpFoundation\Request; use Drupal\Core\Ajax\AjaxResponse; use Drupal\Core\Ajax\ReplaceCommand; +use Drupal\Core\Ajax\RedirectCommand; use Drupal\entityqueue\Entity\EntityQueue; +use Drupal\entityqueue\Entity\EntitySubqueue; +use Drupal\entityqueue\EntitySubqueueInterface; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Url; +use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\Access\AccessResult; /** * Returns responses for Views UI routes. @@ -31,6 +38,91 @@ class EntityQueueUIController extends ControllerBase { } /** + * Builds the entity add to subqueues page. + * + * @param \Drupal\Core\Routing\RouteMatchInterface $route_match + * The route match. + * @param string $entity_type_id + * (optional) The entity type ID. + * + * @return array + * Array of page elements to render. + */ + public function entitySubqueueList(RouteMatchInterface $route_match, $entity_type_id = NULL) { + /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ + $entity = $route_match->getParameter($entity_type_id); + + return $this->entityGetAllowedSubqueList($entity); + } + + /** + * Get entity list for subqueues allowed for this entity. + * + * @param \Drupal\Core\Entity\ContentEntityInterface + * The entity. + * + * @return array + * Array of page elements to render. + */ + public function entityGetAllowedSubqueList($entity) { + $subqueues = EntitySubqueue::loadMultiple(); + $list_builder = $this->entityTypeManager()->getListBuilder('entity_queue'); + + $build['#title'] = $this->t('Entityqueues for %title', ['%title' => $entity->label()]); + $build['#type'] = 'container'; + $build['#attributes']['id'] = 'entity-queue-list'; + $build['#attached']['library'][] = 'core/drupal.ajax'; + $build['table'] = array( + '#type' => 'table', + '#attributes' => array( + 'class' => array('entity-queue-listing-table'), + ), + '#header' => $list_builder->buildHeader(), + '#rows' => array(), + '#cache' => [], + ); + + foreach ($subqueues as $subqueue) { + $queue = $subqueue->getQueue(); + $queue_settings = $queue->getEntitySettings(); + $target_bundles = !empty($queue_settings['handler_settings']['target_bundles']) ? $queue_settings['handler_settings']['target_bundles'] : []; + if ($queue_settings['target_type'] == $entity->getEntityTypeId() && (empty($target_bundles) || in_array($entity->bundle(), $target_bundles))) { + $row = $list_builder->buildRow($queue); + // Check if entity is in queue + $subqueue_items = $subqueue->get('items')->getValue(); + if(in_array($entity->id(), array_column($subqueue_items, 'target_id'))) { + $url = Url::fromRoute('entity.entity_subqueue.remove_item', ['entity_queue' => $queue->id(), 'entity_subqueue' => $subqueue->id(), 'entity' => $entity->id()]); + $row['data']['operations']['data']['#links'] = [ + 'remove-item' => [ + 'title' => $this->t('Remove from queue'), + 'url' => $url, + 'attributes' => [ + 'class' => ['use-ajax'], + ], + ], + ]; + } + else { + $url = Url::fromRoute('entity.entity_subqueue.add_item', ['entity_queue' => $queue->id(), 'entity_subqueue' => $subqueue->id(), 'entity' => $entity->id()]); + $row['data']['operations']['data']['#links'] = [ + 'add-item' => [ + 'title' => $this->t('Add to queue'), + 'url' => $url, + 'attributes' => [ + 'class' => ['use-ajax'], + ], + ], + ]; + } + $build['table']['#rows'][$queue->id()] = $row; + } + } + $build['table']['#empty'] = $this->t('There are no available queues.'); + + return $build; + } + + /** * Returns a form to add a new subqeue. * * @param \Drupal\entityqueue\EntityQueueInterface $entity_queue @@ -73,4 +165,64 @@ class EntityQueueUIController extends ControllerBase { // Otherwise, redirect back to the page. return $this->redirect('entity.entity_queue.collection'); } + + /** + * Calls a method on an entity subqueue page and reloads the page. + * + * @param \Drupal\entityqueue\EntitySubqueueInterface $entity_subqueue + * The view being acted upon. + * @param string $op + * The operation to perform, e.g., 'add-item' or 'remove-item'. + * @param \Symfony\Component\HttpFoundation\Request $request + * The current request. + * + * @return \Drupal\Core\Ajax\AjaxResponse|\Symfony\Component\HttpFoundation\RedirectResponse + * Either returns a rebuilt listing page as an AJAX response, or redirects + * back to the subqueue page. + */ + public function subqueueAjaxOperation(EntitySubqueueInterface $entity_subqueue, $op, Request $request) { + $entity_id = $request->get('entity'); + $entity = \Drupal::entityTypeManager()->getStorage($entity_subqueue->getQueue()->getTargetEntityTypeId())->load($entity_id); + // Perform the operation. + $entity_subqueue->$op($entity_id)->save(); + // If the request is via AJAX, return the rendered list as JSON. + if ($request->request->get('js')) { + $list = $this->entityGetAllowedSubqueList($entity); + $response = new AjaxResponse(); + $response->addCommand(new ReplaceCommand('#entity-queue-list', $list)); + return $response; + } + else { + $response = new AjaxResponse(); + $response->addCommand(new RedirectCommand('')); + return $response; + } + } + + /** + * Checks access for a specific request. + * + * @param \Drupal\Core\Routing\RouteMatchInterface $route_match + * The route match. + * @param string $entity_type_id + * (optional) The entity type ID. + * + * @return \Drupal\Core\Access\AccessResultInterface + * The access result. + */ + public function access(RouteMatchInterface $route_match, $entity_type_id = NULL) { + /** @var \Drupal\Core\Entity\ContentEntityInterface $entity */ + $entity = $route_match->getParameter($entity_type_id); + $subqueues = EntitySubqueue::loadMultiple(); + foreach ($subqueues as $subqueue) { + $queue = $subqueue->getQueue(); + $queue_settings = $queue->getEntitySettings(); + $target_bundles = !empty($queue_settings['handler_settings']['target_bundles']) ? $queue_settings['handler_settings']['target_bundles'] : []; + if ($queue_settings['target_type'] == $entity_type_id && (empty($target_bundles) || in_array($entity->bundle(), $target_bundles))) { + return AccessResult::allowed(); + } + } + + return AccessResult::forbidden(); + } } diff --git a/src/Entity/EntitySubqueue.php b/src/Entity/EntitySubqueue.php index dfb3dc5..4d1fcfb 100644 --- a/src/Entity/EntitySubqueue.php +++ b/src/Entity/EntitySubqueue.php @@ -50,8 +50,8 @@ use Drupal\user\UserInterface; * "canonical" = "/admin/structure/entityqueue/{entity_queue}", * "edit-form" = "/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}", * "delete-form" = "/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}/delete", - * "add" = "/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}/{entity}/add", - * "remove" = "/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}/{entity}/remove" + * "add-item" = "/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}/{entity}/add-item", + * "remove-item" = "/admin/structure/entityqueue/{entity_queue}/{entity_subqueue}/{entity}/remove-item" * }, * constraints = { * "QueueSize" = {} @@ -281,7 +281,7 @@ class EntitySubqueue extends ContentEntityBase implements EntitySubqueueInterfac /** * Adds an entity to a subqueue */ - public function add($entity_id) { + public function addItem($entity_id) { $this->get('items')->appendItem($entity_id); return $this; } @@ -289,7 +289,7 @@ class EntitySubqueue extends ContentEntityBase implements EntitySubqueueInterfac /** * Removes an entity from a subqueue */ - public function remove($entity_id) { + public function removeItem($entity_id) { $subqueue_items = $this->get('items')->getValue(); foreach ($subqueue_items as $key => $item) { if ($item['target_id'] == $entity_id) { @@ -333,12 +333,7 @@ class EntitySubqueue extends ContentEntityBase implements EntitySubqueueInterfac // The 'entity_queue' parameter is needed by the subqueue routes, so we need // to add it manually. $url->setRouteParameter('entity_queue', $this->bundle()); - if (in_array($rel, ['add', 'remove'])) { - $route_match = \Drupal::routeMatch(); - $entity_type = $route_match->getParameter('entity_type_id'); - $entity = $route_match->getParameter($entity_type); - $url->setRouteParameter('entity', $entity->id()); - } + return $url; } diff --git a/src/Plugin/Derivative/EntityqueueLocalTask.php b/src/Plugin/Derivative/EntityqueueLocalTask.php index 1e4a062..467c613 100644 --- a/src/Plugin/Derivative/EntityqueueLocalTask.php +++ b/src/Plugin/Derivative/EntityqueueLocalTask.php @@ -65,7 +65,7 @@ class EntityqueueLocalTask extends DeriverBase implements ContainerDeriverInterf 'title' => $this->t('Entityqueue'), 'route_name' => $entityqueue_route_name, 'base_route' => "entity.$entity_type_id.canonical", - 'weight' => 999, + 'weight' => 21, // move after edit, delete, revisions ... etc tabs. ) + $base_plugin_definition; } } diff --git a/src/Routing/RouteSubscriber.php b/src/Routing/RouteSubscriber.php index 56ea2b5..a025d5a 100644 --- a/src/Routing/RouteSubscriber.php +++ b/src/Routing/RouteSubscriber.php @@ -59,13 +59,13 @@ class RouteSubscriber extends RouteSubscriberBase { $route = new Route( $path, array( - '_controller' => '\Drupal\entityqueue\Controller\EntityQueueEntityController::entitySubqueueList', + '_controller' => '\Drupal\entityqueue\Controller\EntityQueueUIController::entitySubqueueList', 'entity_type_id' => $entity_type_id, '_title' => 'Entityqueues', ), array( '_permission' => 'administer entityqueue+manipulate entityqueues+manipulate all entityqueues', - '_custom_access' => 'Drupal\entityqueue\Controller\EntityQueueEntityController::access', + '_custom_access' => 'Drupal\entityqueue\Controller\EntityQueueUIController::access', ), array( 'parameters' => array(