From de32a81cd984e25a4375edfaf6d3bd1bab0b8ae5 Mon Sep 17 00:00:00 2001 From: Pavel Ruban <job.pavelruban@gmail.com> Date: Wed, 16 Apr 2025 01:42:15 +0000 Subject: [PATCH 1/6] Issue #3519161: Fix routes conflict with grequest, fix access checks plugin name issues in entity link and menu local task alter, fix missing gnode request form class. # Conflicts: # gnode_request.routing.yml --- gnode_request.module | 12 ++- src/Entity/Form/GroupNodeRequestForm.php | 90 +++++++++++++++++++ .../views/field/MembershipEntityLink.php | 18 ++-- 3 files changed, 112 insertions(+), 8 deletions(-) create mode 100644 src/Entity/Form/GroupNodeRequestForm.php diff --git a/gnode_request.module b/gnode_request.module index 67fbc7d..e70be6a 100644 --- a/gnode_request.module +++ b/gnode_request.module @@ -17,7 +17,8 @@ function gnode_request_entity_type_build(array &$entity_types) { ->setFormClass('group-node-approve', 'Drupal\gnode_request\Entity\Form\GroupNodeApproveForm') ->setLinkTemplate('group-node-approve', '/group/{group}/content/{group_relationship}/approve-node') ->setFormClass('group-node-reject', 'Drupal\gnode_request\Entity\Form\GroupNodeRejectForm') - ->setLinkTemplate('group-node-reject', '/group/{group}/content/{group_relationship}/reject-node'); + ->setLinkTemplate('group-node-reject', '/group/{group}/content/{group_relationship}/reject-node') + ->setFormClass('group-request-node', 'Drupal\gnode_request\Entity\Form\GroupNodeRequestForm'); } /** @@ -27,7 +28,14 @@ function gnode_request_menu_local_tasks_alter(&$data, $route_name) { $route_matcher = \Drupal::service('current_route_match'); $group = $route_matcher->getParameter('group'); - if ($group instanceof GroupInterface && !$group->getGroupType()->hasPlugin('group_node_request')) { + if ($group instanceof GroupInterface) { + foreach ($group->getGroupType()->getInstalledPlugins()->getIterator() as $plugin) { + // Plugin group_node_request isn't a case, every bundle has own plugin id, e.g. group_node_request:booking. + if ($plugin->getBaseId() === 'group_node_request') { + return; + } + } + unset($data['tabs'][0]['views_view:view.group_pending_nodes.page_1']); } } diff --git a/src/Entity/Form/GroupNodeRequestForm.php b/src/Entity/Form/GroupNodeRequestForm.php new file mode 100644 index 0000000..f7b28db --- /dev/null +++ b/src/Entity/Form/GroupNodeRequestForm.php @@ -0,0 +1,90 @@ +<?php + +namespace Drupal\gnode_request\Entity\Form; + +use Drupal\Component\Datetime\TimeInterface; +use Drupal\Core\Entity\EntityRepositoryInterface; +use Drupal\Core\Entity\EntityTypeBundleInfoInterface; +use Drupal\Core\Form\FormStateInterface; +use Drupal\gnode_request\GnodeRequestManager; +use Symfony\Component\DependencyInjection\ContainerInterface; + +/** + * Provides a form for requesting a group membership. + */ +class GroupNodeRequestForm extends GroupRelationshipBaseForm { + + /** + * Membership request manager. + * + * @var \Drupal\gnode_request\GnodeRequestManager + */ + protected $gnodeRequestManager; + + /** + * Constructs a request membership form. + * + * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository + * The entity repository service. + * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info + * The entity type bundle service. + * @param \Drupal\Component\Datetime\TimeInterface $time + * The time service. + * @param \Drupal\gnode_request\GnodeRequestManager $gnode_request_manager + * Membership request manager. + */ + public function __construct(EntityRepositoryInterface $entity_repository, EntityTypeBundleInfoInterface $entity_type_bundle_info, TimeInterface $time, GnodeRequestManager $gnode_request_manager) { + parent::__construct($entity_repository, $entity_type_bundle_info, $time); + $this->gnodeRequestManager = $gnode_request_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container) { + return new static( + $container->get('entity.repository'), + $container->get('entity_type.bundle.info'), + $container->get('datetime.time'), + $container->get('gnode_request.gnode_request_manager') + ); + } + + /** + * {@inheritdoc} + */ + protected function actions(array $form, FormStateInterface $form_state) { + $actions = parent::actions($form, $form_state); + $actions['submit']['#value'] = $this->t('Request group membership'); + $actions['cancel'] = [ + '#type' => 'link', + '#title' => $this->t('Cancel'), + '#url' => $this->getCancelUrl(), + ]; + + return $actions; + } + + /** + * {@inheritdoc} + */ + public function buildForm(array $form, FormStateInterface $form_state) { + $form = parent::buildForm($form, $form_state); + $form['#attached']['library'][] = 'core/drupal.form'; + // Make field not accessible, because we set it programmatically. + $form['entity_id']['#access'] = FALSE; + return $form; + } + + /** + * {@inheritdoc} + */ + public function save(array $form, FormStateInterface $form_state) { + $return = parent::save($form, $form_state); + + $this->messenger()->addMessage($this->t('Your request is waiting for approval')); + $form_state->setRedirectUrl($this->getCancelUrl()); + return $return; + } + +} diff --git a/src/Plugin/views/field/MembershipEntityLink.php b/src/Plugin/views/field/MembershipEntityLink.php index 2657756..9a62d30 100644 --- a/src/Plugin/views/field/MembershipEntityLink.php +++ b/src/Plugin/views/field/MembershipEntityLink.php @@ -15,9 +15,11 @@ abstract class MembershipEntityLink extends EntityLink { * {@inheritdoc} */ protected function renderLink(ResultRow $row) { - $plugin_id = 'group_node_request'; + $base_plugin_id = 'group_node_request'; + /** @var \Drupal\group\Entity\GroupRelationship $group_relationship */ $group_relationship = $row->_entity; + $plugin_id = $group_relationship->getPlugin()->getPluginId(); $group = $group_relationship->getGroup(); $link = NULL; @@ -25,15 +27,19 @@ abstract class MembershipEntityLink extends EntityLink { if (!$group->getGroupType()->hasPlugin($plugin_id)) { return $link; } + // Check if current group relationship is type of group_node_request. - if ($group_relationship->getPluginId() !== $plugin_id) { + if ($group_relationship->getPlugin()->getBaseId() !== $base_plugin_id) { return $link; } - $user = $group_relationship->getEntity(); - - if (!empty($group->getMember($user))) { - $link = $this->t('Already member'); + $node = $group_relationship->getEntity(); + // Check if group already have the node as a member. + $nodes = $group->getRelatedEntities(str_replace('_request', '', $group_relationship->getPluginId())); + if (array_filter($nodes, function ($n) use ($node) { + return $node->id() === $n->id(); + })) { + $link = $this->t('Already in group'); } elseif ($group_relationship->get(GroupNodeRequest::STATUS_FIELD)->value === GroupNodeRequest::REQUEST_PENDING && $group->hasPermission('administer group node requests', $this->currentUser)) { $this->options['alter']['query'] = $this->getDestinationArray(); -- GitLab From cd56bb99e5e6a34a597b0c26c57c66850bf90109 Mon Sep 17 00:00:00 2001 From: ekes <ekes@iskra.net> Date: Wed, 16 Apr 2025 17:28:58 +0200 Subject: [PATCH 2/6] D11 compatibility. --- config/optional/views.view.group_pending_nodes.yml | 1 - .../Validation/Constraint/GroupNodeRequestValidator.php | 9 +-------- tests/src/Kernel/GroupNodeRequestAccessTest.php | 2 +- tests/src/Kernel/GroupNodeRequestConfigTest.php | 1 - 4 files changed, 2 insertions(+), 11 deletions(-) diff --git a/config/optional/views.view.group_pending_nodes.yml b/config/optional/views.view.group_pending_nodes.yml index 926098e..f8181b2 100644 --- a/config/optional/views.view.group_pending_nodes.yml +++ b/config/optional/views.view.group_pending_nodes.yml @@ -520,7 +520,6 @@ display: default_argument_type: fixed default_argument_options: argument: '3' - default_argument_skip_url: false summary_options: base_path: '' count: true diff --git a/src/Plugin/Validation/Constraint/GroupNodeRequestValidator.php b/src/Plugin/Validation/Constraint/GroupNodeRequestValidator.php index 64ac29b..7657f31 100644 --- a/src/Plugin/Validation/Constraint/GroupNodeRequestValidator.php +++ b/src/Plugin/Validation/Constraint/GroupNodeRequestValidator.php @@ -11,17 +11,10 @@ use Symfony\Component\Validator\ConstraintValidator; */ class GroupNodeRequestValidator extends ConstraintValidator { - /** - * Type-hinting in parent Symfony class is off, let's fix that. - * - * @var \Symfony\Component\Validator\Context\ExecutionContextInterface - */ - protected $context; - /** * {@inheritdoc} */ - public function validate($group_relationship, Constraint $constraint) { + public function validate($group_relationship, Constraint $constraint): void { assert($group_relationship instanceof GroupRelationshipInterface); assert($constraint instanceof GroupNodeRequest); diff --git a/tests/src/Kernel/GroupNodeRequestAccessTest.php b/tests/src/Kernel/GroupNodeRequestAccessTest.php index 556a364..351ac53 100644 --- a/tests/src/Kernel/GroupNodeRequestAccessTest.php +++ b/tests/src/Kernel/GroupNodeRequestAccessTest.php @@ -103,7 +103,7 @@ class GroupNodeRequestAccessTest extends GroupKernelTestBase { $storage->save($storage->createFromPlugin($this->groupTypeB, 'group_node_request:page')); $storage->save($storage->createFromPlugin($this->groupTypeB, 'group_node_request:article')); - $this->setCurrentUser($this->createUser([], $this->permissions)); + $this->setCurrentUser($this->createUser($this->permissions)); } /** diff --git a/tests/src/Kernel/GroupNodeRequestConfigTest.php b/tests/src/Kernel/GroupNodeRequestConfigTest.php index dca262d..7f3cce7 100644 --- a/tests/src/Kernel/GroupNodeRequestConfigTest.php +++ b/tests/src/Kernel/GroupNodeRequestConfigTest.php @@ -21,7 +21,6 @@ class GroupNodeRequestConfigTest extends EntityKernelTestBase { 'group', 'options', 'entity', - 'variationcache', 'flexible_permissions', 'state_machine', 'gnode_request', -- GitLab From c0bb15bf86c6c5206c2b8952283cedf39f2172b8 Mon Sep 17 00:00:00 2001 From: ekes <ekes@iskra.net> Date: Fri, 18 Apr 2025 14:15:05 +0200 Subject: [PATCH 3/6] Restrict access to group content by group. --- gnode_request.routing.yml | 2 ++ .../src/Functional/GroupNodeRequestFormTest.php | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/gnode_request.routing.yml b/gnode_request.routing.yml index 18505ab..1f6957e 100644 --- a/gnode_request.routing.yml +++ b/gnode_request.routing.yml @@ -3,6 +3,7 @@ entity.group_relationship.group_approve_node: defaults: _controller: '\Drupal\gnode_request\Controller\GroupNodeRequestController::approveMembership' requirements: + _group_owns_content: 'TRUE' _group_permission: 'administer group node requests' _pending_group_node_request: 'TRUE' options: @@ -17,6 +18,7 @@ entity.group_relationship.group_reject_node: defaults: _controller: '\Drupal\gnode_request\Controller\GroupNodeRequestController::rejectMembership' requirements: + _group_owns_content: 'TRUE' _group_permission: 'administer group node requests' _pending_group_node_request: 'TRUE' options: diff --git a/tests/src/Functional/GroupNodeRequestFormTest.php b/tests/src/Functional/GroupNodeRequestFormTest.php index 62fe424..12d2119 100644 --- a/tests/src/Functional/GroupNodeRequestFormTest.php +++ b/tests/src/Functional/GroupNodeRequestFormTest.php @@ -59,10 +59,13 @@ class GroupNodeRequestFormTest extends GroupBrowserTestBase { */ protected function setUp(): void { parent::setUp(); + $this->group = $this->createGroup(['type' => 'default']); + $this->group2 = $this->createGroup(['type' => 'default']); $group_type = $this->group->getGroupType(); $this->groupContentType = $this->createContentType(['type' => 'page']); $this->otherContentType = $this->createContentType(); + $plugin_id = 'group_node_request:page'; $this->gnodeRequestManager = $this->container->get('gnode_request.gnode_request_manager'); @@ -132,10 +135,17 @@ class GroupNodeRequestFormTest extends GroupBrowserTestBase { $group_node_request = $this->gnodeRequestManager->create($this->group, $node); $group_node_request->save(); + $this->drupalGet("/group/{$this->group->id()}/content/{$group_node_request->id()}/approve-node"); + $this->assertSession()->statusCodeEquals(403); + $manager_account = $this->createUser(); $this->group->addMember($manager_account); + $this->group2->addMember($manager_account); $this->drupalLogin($manager_account); + $this->drupalGet("/group/{$this->group2->id()}/content/{$group_node_request->id()}/approve-node"); + $this->assertSession()->statusCodeEquals(403); + $this->drupalGet("/group/{$this->group->id()}/content/{$group_node_request->id()}/approve-node"); $this->assertSession()->statusCodeEquals(200); @@ -166,10 +176,16 @@ class GroupNodeRequestFormTest extends GroupBrowserTestBase { $group_node_request = $this->gnodeRequestManager->create($this->group, $node); $group_node_request->save(); + $this->drupalGet("/group/{$this->group->id()}/content/{$group_node_request->id()}/reject-node"); + $this->assertSession()->statusCodeEquals(403); + $manager_account = $this->createUser(); $this->group->addMember($manager_account); $this->drupalLogin($manager_account); + $this->drupalGet("/group/{$this->group->id()}/content/{$group_node_request->id()}/reject-node"); + $this->assertSession()->statusCodeEquals(403); + $this->drupalGet("/group/{$this->group->id()}/content/{$group_node_request->id()}/reject-node"); $this->assertSession()->statusCodeEquals(200); -- GitLab From 5ef85a1c5cf2a4b4f436822a6f614b27a47b8c34 Mon Sep 17 00:00:00 2001 From: ekes <ekes@iskra.net> Date: Fri, 18 Apr 2025 14:15:54 +0200 Subject: [PATCH 4/6] Differentiate workflow from grequest modules. --- gnode_request.workflows.yml | 6 +++--- .../Group/RelationHandler/GroupNodeRequestPostInstall.php | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gnode_request.workflows.yml b/gnode_request.workflows.yml index 41b3e24..eac3f1b 100644 --- a/gnode_request.workflows.yml +++ b/gnode_request.workflows.yml @@ -1,6 +1,6 @@ -request: - id: request - label: 'Group membership request' +gnode_request: + id: gnode_request + label: 'Group node request' group: group_node_request states: new: diff --git a/src/Plugin/Group/RelationHandler/GroupNodeRequestPostInstall.php b/src/Plugin/Group/RelationHandler/GroupNodeRequestPostInstall.php index 0ebfe9e..b66d0b1 100644 --- a/src/Plugin/Group/RelationHandler/GroupNodeRequestPostInstall.php +++ b/src/Plugin/Group/RelationHandler/GroupNodeRequestPostInstall.php @@ -74,7 +74,7 @@ class GroupNodeRequestPostInstall implements PostInstallInterface { 'label' => $this->t('Request status'), 'required' => TRUE, 'settings' => [ - 'workflow' => 'request', + 'workflow' => 'gnode_request', 'workflow_callback' => '', ], ])->save(); -- GitLab From 5e8c35b862a26c7c47ae0474a9744390c9449e5a Mon Sep 17 00:00:00 2001 From: ekes <ekes@iskra.net> Date: Fri, 18 Apr 2025 14:16:24 +0200 Subject: [PATCH 5/6] Differentiate views field from grequest action. --- src/Plugin/views/field/ApproveMembership.php | 2 +- src/Plugin/views/field/RejectMembership.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Plugin/views/field/ApproveMembership.php b/src/Plugin/views/field/ApproveMembership.php index a7e696a..faad34b 100644 --- a/src/Plugin/views/field/ApproveMembership.php +++ b/src/Plugin/views/field/ApproveMembership.php @@ -22,7 +22,7 @@ class ApproveMembership extends MembershipEntityLink { * {@inheritdoc} */ protected function getDefaultLabel() { - return $this->t('Approve membership'); + return $this->t('Approve'); } } diff --git a/src/Plugin/views/field/RejectMembership.php b/src/Plugin/views/field/RejectMembership.php index c30ea9f..d162bdf 100644 --- a/src/Plugin/views/field/RejectMembership.php +++ b/src/Plugin/views/field/RejectMembership.php @@ -22,7 +22,7 @@ class RejectMembership extends MembershipEntityLink { * {@inheritdoc} */ protected function getDefaultLabel() { - return $this->t('Reject membership'); + return $this->t('Reject'); } } -- GitLab From 9b0c868fd48f18a69a8667be022bb0f52bae909f Mon Sep 17 00:00:00 2001 From: ekes <ekes@iskra.net> Date: Fri, 18 Apr 2025 15:40:49 +0200 Subject: [PATCH 6/6] Remove form to request membership. An existing node can be added with the create default create relationship form. The location where this would be useful would be a view field, but this would then want to be in a list of nodes not in a group. The form requiring the group that it is to go into. --- src/Entity/Form/GroupNodeRequestForm.php | 90 ------------- .../GroupNodeRequestOperationProvider.php | 80 ----------- src/Plugin/views/field/RequestMembership.php | 126 ------------------ 3 files changed, 296 deletions(-) delete mode 100644 src/Entity/Form/GroupNodeRequestForm.php delete mode 100644 src/Plugin/Group/RelationHandler/GroupNodeRequestOperationProvider.php delete mode 100644 src/Plugin/views/field/RequestMembership.php diff --git a/src/Entity/Form/GroupNodeRequestForm.php b/src/Entity/Form/GroupNodeRequestForm.php deleted file mode 100644 index f7b28db..0000000 --- a/src/Entity/Form/GroupNodeRequestForm.php +++ /dev/null @@ -1,90 +0,0 @@ -<?php - -namespace Drupal\gnode_request\Entity\Form; - -use Drupal\Component\Datetime\TimeInterface; -use Drupal\Core\Entity\EntityRepositoryInterface; -use Drupal\Core\Entity\EntityTypeBundleInfoInterface; -use Drupal\Core\Form\FormStateInterface; -use Drupal\gnode_request\GnodeRequestManager; -use Symfony\Component\DependencyInjection\ContainerInterface; - -/** - * Provides a form for requesting a group membership. - */ -class GroupNodeRequestForm extends GroupRelationshipBaseForm { - - /** - * Membership request manager. - * - * @var \Drupal\gnode_request\GnodeRequestManager - */ - protected $gnodeRequestManager; - - /** - * Constructs a request membership form. - * - * @param \Drupal\Core\Entity\EntityRepositoryInterface $entity_repository - * The entity repository service. - * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info - * The entity type bundle service. - * @param \Drupal\Component\Datetime\TimeInterface $time - * The time service. - * @param \Drupal\gnode_request\GnodeRequestManager $gnode_request_manager - * Membership request manager. - */ - public function __construct(EntityRepositoryInterface $entity_repository, EntityTypeBundleInfoInterface $entity_type_bundle_info, TimeInterface $time, GnodeRequestManager $gnode_request_manager) { - parent::__construct($entity_repository, $entity_type_bundle_info, $time); - $this->gnodeRequestManager = $gnode_request_manager; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('entity.repository'), - $container->get('entity_type.bundle.info'), - $container->get('datetime.time'), - $container->get('gnode_request.gnode_request_manager') - ); - } - - /** - * {@inheritdoc} - */ - protected function actions(array $form, FormStateInterface $form_state) { - $actions = parent::actions($form, $form_state); - $actions['submit']['#value'] = $this->t('Request group membership'); - $actions['cancel'] = [ - '#type' => 'link', - '#title' => $this->t('Cancel'), - '#url' => $this->getCancelUrl(), - ]; - - return $actions; - } - - /** - * {@inheritdoc} - */ - public function buildForm(array $form, FormStateInterface $form_state) { - $form = parent::buildForm($form, $form_state); - $form['#attached']['library'][] = 'core/drupal.form'; - // Make field not accessible, because we set it programmatically. - $form['entity_id']['#access'] = FALSE; - return $form; - } - - /** - * {@inheritdoc} - */ - public function save(array $form, FormStateInterface $form_state) { - $return = parent::save($form, $form_state); - - $this->messenger()->addMessage($this->t('Your request is waiting for approval')); - $form_state->setRedirectUrl($this->getCancelUrl()); - return $return; - } - -} diff --git a/src/Plugin/Group/RelationHandler/GroupNodeRequestOperationProvider.php b/src/Plugin/Group/RelationHandler/GroupNodeRequestOperationProvider.php deleted file mode 100644 index f04cd23..0000000 --- a/src/Plugin/Group/RelationHandler/GroupNodeRequestOperationProvider.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php - -namespace Drupal\gnode_request\Plugin\Group\RelationHandler; - -use Drupal\Core\Session\AccountProxyInterface; -use Drupal\Core\StringTranslation\TranslationInterface; -use Drupal\group\Entity\GroupInterface; -use Drupal\group\Plugin\Group\RelationHandler\OperationProviderInterface; -use Drupal\group\Plugin\Group\RelationHandler\OperationProviderTrait; - -/** - * Provides operations for the group_node_request relation plugin. - * - * @todo DELETE? - */ -class GroupNodeRequestOperationProvider implements OperationProviderInterface { - - use OperationProviderTrait; - - /** - * Constructs a new GroupNodeRequestOperationProvider. - * - * @param \Drupal\group\Plugin\Group\RelationHandler\OperationProviderInterface $parent - * The default operation provider. - * @param \Drupal\Core\Session\AccountProxyInterface $current_user - * The current user. - * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation - * The string translation service. - */ - public function __construct(OperationProviderInterface $parent, AccountProxyInterface $current_user, TranslationInterface $string_translation) { - $this->parent = $parent; - $this->currentUser = $current_user; - $this->stringTranslation = $string_translation; - } - - /** - * {@inheritdoc} - */ - public function getGroupOperations(GroupInterface $group) { - $operations = $this->parent->getGroupOperations($group); - - $url = $group->toUrl('group-request-node'); - if ($url->access($this->currentUser())) { - $entity_instances = $this->getRelationships($group); - if (count($entity_instances) == 0) { - $operations['group-request-node'] = [ - 'title' => $this->t('Request group node membership'), - 'url' => $url, - 'weight' => 99, - ]; - } - } - - // @todo With the new VariationCache, we can use the above context. - $operations['#cache']['contexts'] = ['user']; - - return $operations; - } - - /** - * Get relationship for the current plugin in the given group. - * - * @param \Drupal\group\Entity\GroupInterface $group - * Group. - * - * @return array|\Drupal\group\Entity\GroupRelationshipInterface[] - * List of group relationships. - */ - protected function getRelationships(GroupInterface $group) { - // We can use loadByEntityAndGroup, but for this we need load user entity. - // @see https://www.drupal.org/project/group/issues/3310605 - $properties = [ - 'entity_id' => $this->currentUser()->id(), - 'plugin_id' => $this->pluginId, - 'gid' => $group->id(), - ]; - return $this->entityTypeManager()->getStorage('group_relationship')->loadByProperties($properties); - } - -} diff --git a/src/Plugin/views/field/RequestMembership.php b/src/Plugin/views/field/RequestMembership.php deleted file mode 100644 index 00d1b14..0000000 --- a/src/Plugin/views/field/RequestMembership.php +++ /dev/null @@ -1,126 +0,0 @@ -<?php - -namespace Drupal\gnode_request\Plugin\views\field; - -use Drupal\Core\Entity\EntityTypeManagerInterface; -use Drupal\Core\Session\AccountInterface; -use Drupal\gnode_request\Plugin\Group\Relation\GroupNodeRequest; -use Drupal\group\Entity\GroupInterface; -use Drupal\views\Plugin\views\field\FieldPluginBase; -use Drupal\views\ResultRow; -use Symfony\Component\DependencyInjection\ContainerInterface; - -/** - * Provides request membership link. - * - * @ingroup views_field_handlers - * - * @ViewsField("group_request_membership") - */ -final class RequestMembership extends FieldPluginBase { - - /** - * The current user. - * - * @var \Drupal\Core\Session\AccountInterface - */ - protected $currentUser; - - /** - * The entity type manager. - * - * @var \Drupal\Core\Entity\EntityTypeManagerInterface - */ - protected $entityTypeManager; - - /** - * RequestMembership constructor. - * - * @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\Session\AccountInterface $current_user - * The current user. - * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager - * The entity type manager. - */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, AccountInterface $current_user, EntityTypeManagerInterface $entity_type_manager) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->currentUser = $current_user; - $this->entityTypeManager = $entity_type_manager; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { - return new static( - $configuration, - $plugin_id, - $plugin_definition, - $container->get('current_user'), - $container->get('entity_type.manager') - ); - } - - /** - * {@inheritdoc} - */ - public function usesGroupBy() { - return FALSE; - } - - /** - * {@inheritdoc} - */ - public function query() { - // Intentionally override query to do nothing. - } - - /** - * {@inheritdoc} - * - * @throws \Drupal\Core\Entity\EntityMalformedException - */ - public function render(ResultRow $values) { - /** @var \Drupal\group\Entity\Group $group */ - $group = $values->_entity; - if (!($group instanceof GroupInterface) && !empty($values->_relationship_entities['gid'])) { - $group = $values->_relationship_entities['gid']; - } - - $build = NULL; - if (empty($group) || !$group->getGroupType()->hasPlugin('group_node_request')) { - return $build; - } - - $user = $this->entityTypeManager->getStorage('user')->load($this->currentUser->id()); - if (empty($user)) { - return $build; - } - $membership_requests = $group->getRelationshipsByEntity($user, 'group_node_request'); - if (!empty($group->getMember($this->currentUser))) { - $build['#markup'] = $this->t('Already member'); - } - elseif (empty($membership_requests)) { - $link = $group->toLink($this->t('Request Membership'), 'group-request-node'); - if($link->getUrl()->access($this->currentUser)){ - $build = $link->toString(); - } - } - else { - $membership_request = reset($membership_requests); - if ($membership_request->get(GroupNodeRequest::STATUS_FIELD)->value == GroupNodeRequest::REQUEST_PENDING) { - $build['#markup'] = $this->t('Pending membership request'); - } - else { - $build['#markup'] = $this->t('Rejected membership request'); - } - } - return $build; - } - -} -- GitLab