diff --git a/modules/gvbo/gvbo.info.yml b/modules/gvbo/gvbo.info.yml new file mode 100644 index 0000000..281fc0c --- /dev/null +++ b/modules/gvbo/gvbo.info.yml @@ -0,0 +1,9 @@ +name: 'Group Views Bulk Operations' +description: 'Use Views Bulk Operations together with group permission.' +package: 'Group' +type: 'module' +version: 1.0 +core: '8.x' +dependencies: + - 'group' + - 'views_bulk_operations' diff --git a/modules/gvbo/gvbo.libraries.yml b/modules/gvbo/gvbo.libraries.yml new file mode 100644 index 0000000..5555eaa --- /dev/null +++ b/modules/gvbo/gvbo.libraries.yml @@ -0,0 +1,8 @@ +frontUi: + version: 1.0 + js: + js/frontUi.js: {} + dependencies: + - core/drupal + - core/jquery + - core/jquery.once diff --git a/modules/gvbo/gvbo.services.yml b/modules/gvbo/gvbo.services.yml new file mode 100644 index 0000000..0085bd4 --- /dev/null +++ b/modules/gvbo/gvbo.services.yml @@ -0,0 +1,5 @@ +services: + gvbo.route_subscriber: + class: 'Drupal\gvbo\Routing\GroupViewsBulkOperationsRouteSubscriber' + tags: + - { name: 'event_subscriber' } diff --git a/modules/gvbo/gvbo.views.inc b/modules/gvbo/gvbo.views.inc new file mode 100644 index 0000000..316adf5 --- /dev/null +++ b/modules/gvbo/gvbo.views.inc @@ -0,0 +1,14 @@ + t('Group bulk operations for Group Content'), + 'help' => t("Process Group Content returned by the view with Views Bulk Operations' actions."), + 'field' => [ + 'id' => 'group_views_bulk_operations_bulk_form', + ], + ]; +} diff --git a/modules/gvbo/js/frontUi.js b/modules/gvbo/js/frontUi.js new file mode 100644 index 0000000..de81d9f --- /dev/null +++ b/modules/gvbo/js/frontUi.js @@ -0,0 +1,32 @@ +/** + * @file + * Select-All Button functionality. + */ + +(function ($, Drupal) { + + 'use strict'; + + /** + * @type {Drupal~behavior} + */ + Drupal.behaviors.group_views_bulk_operations = { + attach: function (context, settings) { + $('.vbo-view-form').once('group-vbo-init').each(Drupal.groupViewsBulkOperationsFrontUi); + } + }; + + /** + * Callback used in {@link Drupal.behaviors.group_views_bulk_operations}. + */ + Drupal.groupViewsBulkOperationsFrontUi = function () { + var $vboForm = $(this); + + // Add AJAX functionality to table checkboxes. + var $multiSelectElement = $vboForm.find('.vbo-multipage-selector').first(); + if ($multiSelectElement.length && Drupal.viewsBulkOperationsSelection.display_id.length) { + Drupal.viewsBulkOperationsSelection.display_id = Drupal.viewsBulkOperationsSelection.display_id + '/' + $multiSelectElement.data('group-id'); + } + }; + +})(jQuery, Drupal); diff --git a/modules/gvbo/src/Access/GroupViewsBulkOperationsAccessTrait.php b/modules/gvbo/src/Access/GroupViewsBulkOperationsAccessTrait.php new file mode 100644 index 0000000..6fa7711 --- /dev/null +++ b/modules/gvbo/src/Access/GroupViewsBulkOperationsAccessTrait.php @@ -0,0 +1,40 @@ +has($display_id)) { + $plugin = $display_handlers->get($display_id)->getPlugin('access'); + + if ($plugin instanceof GroupPermission) { + return TRUE; + } + } + + return FALSE; + } + +} diff --git a/modules/gvbo/src/Form/GroupViewsBulkOperationsConfigureAction.php b/modules/gvbo/src/Form/GroupViewsBulkOperationsConfigureAction.php new file mode 100644 index 0000000..307efdd --- /dev/null +++ b/modules/gvbo/src/Form/GroupViewsBulkOperationsConfigureAction.php @@ -0,0 +1,40 @@ +get('views_bulk_operations'); + $definition = $this->actionManager->getDefinition($form_data['action_id']); + + if (!empty($definition['confirm_form_route_name'])) { + /** @var \Drupal\Core\Url $url */ + $url = $form_state->getRedirect(); + + $parameters = $url->getRouteParameters(); + $view = Views::getView($parameters['view_id']); + + if ($view && $this->useGroupPermission($view, $parameters['display_id'])) { + $url->setRouteParameter('group', $this->getRouteMatch()->getRawParameter('group')); + $form_state->setRedirectUrl($url); + } + } + } + +} diff --git a/modules/gvbo/src/Plugin/views/field/GroupViewsBulkOperationsBulkForm.php b/modules/gvbo/src/Plugin/views/field/GroupViewsBulkOperationsBulkForm.php new file mode 100644 index 0000000..5ba8d90 --- /dev/null +++ b/modules/gvbo/src/Plugin/views/field/GroupViewsBulkOperationsBulkForm.php @@ -0,0 +1,152 @@ +routeMatch = $routeMatch; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('views_bulk_operations.data'), + $container->get('plugin.manager.views_bulk_operations_action'), + $container->get('views_bulk_operations.processor'), + $container->get('user.private_tempstore'), + $container->get('current_user'), + $container->get('request_stack'), + $container->get('current_route_match') + ); + } + + /** + * {@inheritdoc} + */ + public function viewsForm(array &$form, FormStateInterface $form_state) { + parent::viewsForm($form, $form_state); + + $wrapper = &$form['header'][$this->options['id']]; + + if (isset($wrapper['multipage'])) { + $form['#attached']['library'][] = 'gvbo/frontUi'; + + $group = $this->routeMatch->getRawParameter('group'); + + if ($group) { + $wrapper['multipage']['#attributes']['data-group-id'] = $group; + } + } + } + + /** + * {@inheritdoc} + */ + public function viewsFormSubmit(array &$form, FormStateInterface $form_state) { + parent::viewsFormSubmit($form, $form_state); + + $redirect = $form_state->getRedirect(); + + if (!($redirect instanceof Url)) { + return; + } + + $current_parameters = $this->routeMatch->getParameters()->all(); + $redirect_parameters = $redirect->getRouteParameters(); + + $required_parameters = [ + 'view_id', + 'display_id', + ]; + + $valid = TRUE; + + foreach ($required_parameters as $key) { + if (!(isset($redirect_parameters[$key]) && isset($current_parameters[$key]) && $redirect_parameters[$key] === $current_parameters[$key])) { + $valid = FALSE; + break; + } + } + + if ($valid && isset($current_parameters['group']) && $this->useGroupPermission($this->view, $redirect_parameters['display_id'])) { + /** @var \Drupal\group\Entity\GroupInterface $entity */ + $entity = $current_parameters['group']; + + $redirect->setRouteParameter('group', $entity->id()); + $form_state->setRedirectUrl($redirect); + } + } + +} diff --git a/modules/gvbo/src/Routing/GroupViewsBulkOperationsRouteSubscriber.php b/modules/gvbo/src/Routing/GroupViewsBulkOperationsRouteSubscriber.php new file mode 100644 index 0000000..36cf6cd --- /dev/null +++ b/modules/gvbo/src/Routing/GroupViewsBulkOperationsRouteSubscriber.php @@ -0,0 +1,34 @@ +get($route_name); + $route->setPath($route->getPath() . '/{group}'); + $route->setDefault('group', NULL); + + if ($route_name === 'views_bulk_operations.execute_configurable') { + $route->setDefault('_form', '\Drupal\gvbo\Form\GroupViewsBulkOperationsConfigureAction'); + } + } + } + +} diff --git a/src/Context/GroupRouteContextTrait.php b/src/Context/GroupRouteContextTrait.php index 99e9a41..781347f 100644 --- a/src/Context/GroupRouteContextTrait.php +++ b/src/Context/GroupRouteContextTrait.php @@ -69,8 +69,22 @@ trait GroupRouteContextTrait { $route_match = $this->getCurrentRouteMatch(); // See if the route has a group parameter and try to retrieve it. - if (($group = $route_match->getParameter('group')) && $group instanceof GroupInterface) { - return $group; + if (($group = $route_match->getParameter('group'))) { + if (is_numeric($group)) { + try { + $group = $this->getEntityTypeManager() + ->getStorage('group') + ->load($group); + } catch (InvalidPluginDefinitionException $e) { + return NULL; + } catch (PluginNotFoundException $e) { + return NULL; + } + } + + if ($group instanceof GroupInterface) { + return $group; + } } // Create a new group to use as context if on the group add form. elseif ($route_match->getRouteName() == 'entity.group.add_form') {