From b22c5479fa881a1af5e7affcdf26fad2c7baec38 Mon Sep 17 00:00:00 2001 From: Pieter Frenssen Date: Mon, 29 Apr 2019 21:01:14 +0200 Subject: [PATCH 1/7] Provide a cache tag to invalidate a group's membership listings. This also includes a block to display the member count of a group as a demonstration of the cache tag. --- config/schema/og.schema.yml | 11 + og.module | 31 ++ src/Entity/OgMembership.php | 32 ++ src/Plugin/Block/MemberCountBlock.php | 167 ++++++++ templates/og-member-count.html.twig | 21 + .../Plugin/Block/MemberCountBlockTest.php | 372 ++++++++++++++++++ 6 files changed, 634 insertions(+) create mode 100644 src/Plugin/Block/MemberCountBlock.php create mode 100644 templates/og-member-count.html.twig create mode 100644 tests/src/Kernel/Plugin/Block/MemberCountBlockTest.php diff --git a/config/schema/og.schema.yml b/config/schema/og.schema.yml index 4f08e369b..ad6c5f4fb 100644 --- a/config/schema/og.schema.yml +++ b/config/schema/og.schema.yml @@ -193,3 +193,14 @@ condition.plugin.og_group_type: type: sequence sequence: type: string + +block.settings.og_member_count: + type: block_settings + label: 'Group member count block' + mapping: + count_blocked_users: + type: boolean + label: 'Count blocked users' + count_pending_users: + type: boolean + label: 'Count pending users' diff --git a/og.module b/og.module index 05d8a66c9..f111b7b67 100755 --- a/og.module +++ b/og.module @@ -303,6 +303,37 @@ function og_entity_type_alter(array &$entity_types) { } } +/** + * Implements hook_theme(). + */ +function og_theme($existing, $type, $theme, $path) { + return [ + 'og_member_count' => [ + 'variables' => [ + 'count' => 0, + 'group' => NULL, + ], + ], + ]; +} + +/** + * Prepares variables for member count templates. + * + * Default template: og-member-count.html.twig. + * + * @param array $variables + * An associative array containing: + * - count: An integer representing the number of members in the group. + * - group: The group, which is a content entity. + */ +function template_preprocess_og_member_count(array &$variables) { + /** @var \Drupal\Core\Entity\ContentEntityInterface $group */ + $group = $variables['group']; + + $variables['group_label'] = $group->label(); +} + /** * Invalidates group content cache tags for the groups this entity belongs to. * diff --git a/src/Entity/OgMembership.php b/src/Entity/OgMembership.php index 15352b41f..be2a039ee 100644 --- a/src/Entity/OgMembership.php +++ b/src/Entity/OgMembership.php @@ -2,6 +2,7 @@ namespace Drupal\og\Entity; +use Drupal\Core\Cache\Cache; use Drupal\Core\Entity\ContentEntityBase; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityStorageInterface; @@ -482,6 +483,37 @@ public function save() { return $result; } + /** + * {@inheritdoc} + */ + protected function invalidateTagsOnSave($update) { + parent::invalidateTagsOnSave($update); + + // A membership was created or updated: invalidate the membership list cache + // tags of its group. An updated membership may start to appear in a group's + // membership listings because it now meets those listings' filtering + // requirements. A newly created membership may start to appear in listings + // because it did not exist before. + $tags = Cache::buildTags('og-group-membership-list', $this->getGroup()->getCacheTagsToInvalidate()); + Cache::invalidateTags($tags); + } + + /** + * {@inheritdoc} + */ + protected static function invalidateTagsOnDelete(EntityTypeInterface $entity_type, array $entities) { + parent::invalidateTagsOnDelete($entity_type, $entities); + + // A membership was deleted: invalidate the membership list cache tags of + // its group membership lists, so that any lists that contain the membership + // will be recalculated. + $tags = []; + foreach ($entities as $entity) { + $tags = Cache::mergeTags(Cache::buildTags('og-group-membership-list', $entity->getGroup()->getCacheTagsToInvalidate()), $tags); + } + Cache::invalidateTags($tags); + } + /** * {@inheritdoc} */ diff --git a/src/Plugin/Block/MemberCountBlock.php b/src/Plugin/Block/MemberCountBlock.php new file mode 100644 index 000000000..abdc61de4 --- /dev/null +++ b/src/Plugin/Block/MemberCountBlock.php @@ -0,0 +1,167 @@ +ogContext = $og_context; + $this->membershipManager = $membership_manager; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('og.context'), + $container->get('og.membership_manager') + ); + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return [ + 'count_blocked_users' => FALSE, + 'count_pending_users' => FALSE, + ]; + } + + /** + * {@inheritdoc} + */ + public function blockForm($form, FormStateInterface $form_state) { + $form['count_blocked_users'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Count blocked users'), + '#default_value' => $this->configuration['count_blocked_users'], + ]; + + $form['count_pending_users'] = [ + '#type' => 'checkbox', + '#title' => $this->t('Count pending users'), + '#default_value' => $this->configuration['count_pending_users'], + ]; + + return $form; + } + + /** + * {@inheritdoc} + */ + public function blockSubmit($form, FormStateInterface $form_state) { + foreach (array_keys($this->defaultConfiguration()) as $setting) { + $this->configuration[$setting] = $form_state->getValue($setting); + } + } + + /** + * {@inheritdoc} + */ + public function build() { + // Do not render anything if there is no group in the current context. + $group = $this->ogContext->getGroup(); + if (empty($group)) { + return []; + } + + $states = [OgMembershipInterface::STATE_ACTIVE]; + + if ($this->configuration['count_blocked_users']) { + $states[] = OgMembershipInterface::STATE_BLOCKED; + } + + if ($this->configuration['count_pending_users']) { + $states[] = OgMembershipInterface::STATE_PENDING; + } + + $membership_ids = $this->membershipManager->getGroupMembershipIdsByRoleNames($group, [OgRoleInterface::AUTHENTICATED], $states); + + return [ + 'list' => [ + '#theme' => 'og_member_count', + '#count' => count($membership_ids), + '#group' => $group, + '#attributes' => ['class' => ['tralalala']], + ], + ]; + } + + /** + * {@inheritdoc} + */ + public function getCacheTags() { + $tags = parent::getCacheTags(); + + if ($group = $this->ogContext->getGroup()) { + $tags = Cache::mergeTags(Cache::buildTags('og-group-membership-list', $group->getCacheTagsToInvalidate()), $tags); + } + + return $tags; + } + + /** + * {@inheritdoc} + */ + public function getCacheContexts() { + return Cache::mergeContexts(parent::getCacheContexts(), ['og_group_context']); + } + +} diff --git a/templates/og-member-count.html.twig b/templates/og-member-count.html.twig new file mode 100644 index 000000000..bc478e29a --- /dev/null +++ b/templates/og-member-count.html.twig @@ -0,0 +1,21 @@ +{# +/** + * @file + * Default theme implementation to show the member count of a group. + * + * Available variables: + * - count: The number of members in the group. + * - group_label: The group label. + * + * @see \Drupal\og\Plugin\Block\MemberCountBlock + * + * @ingroup themeable + */ +#} +

+ {% trans %} + {{ group_label }} has 1 member. + {% plural count %} + {{ group_label }} has {{ count }} members. + {% endtrans %} +

diff --git a/tests/src/Kernel/Plugin/Block/MemberCountBlockTest.php b/tests/src/Kernel/Plugin/Block/MemberCountBlockTest.php new file mode 100644 index 000000000..649233990 --- /dev/null +++ b/tests/src/Kernel/Plugin/Block/MemberCountBlockTest.php @@ -0,0 +1,372 @@ +installEntitySchema('entity_test'); + $this->installEntitySchema('user'); + $this->installEntitySchema('og_membership'); + $this->installConfig(['system', 'block', 'og']); + $this->installSchema('system', ['sequences']); + + $this->groupTypeManager = $this->container->get('og.group_type_manager'); + $this->entityTypeManager = $this->container->get('entity_type.manager'); + $this->blockStorage = $this->entityTypeManager->getStorage('block'); + $this->blockViewBuilder = $this->entityTypeManager->getViewBuilder('block'); + $this->cacheTagsInvalidator = $this->container->get('cache_tags.invalidator'); + $this->renderer = $this->container->get('renderer'); + $this->renderCache = $this->container->get('render_cache'); + + // The block being tested shows the member count of the currently active + // group, which it gets from OgContext. Mock OgContext using a callback to + // set the active group that will be used during the test. + $og_context = $this->prophesize(OgContextInterface::class); + $og_context->getGroup()->will(new CallbackPromise([$this, 'getActiveGroup'])); + $this->container->set('og.context', $og_context->reveal()); + + // Create a group type. + $this->groupTypeManager->addGroup('entity_test', 'group'); + + // Create two test groups. + for ($i = 0; $i < 2; $i++) { + $this->groups[$i] = EntityTest::create([ + 'type' => 'group', + 'name' => $this->randomString(), + ]); + $this->groups[$i]->save(); + } + + // Create a test block. + $this->block = $this->blockStorage->create([ + 'plugin' => 'og_member_count', + 'region' => 'sidebar_first', + 'id' => 'group_member_count', + 'theme' => $this->config('system.theme')->get('default'), + 'label' => 'Group member count', + 'visibility' => [], + 'weight' => 0, + ]); + $this->block->save(); + } + + /** + * Tests the member count block. + */ + public function testMemberCountBlock() { + // Before the blocks are rendered for the first time, no cache entries + // should exist for them. We have two groups, so let's test both blocks. + $this->assertNotCached(0); + $this->assertNotCached(1); + + // After rendering the first block, only this block should be cached, the + // other should be unaffected. + $this->renderBlock(0); + $this->assertCached(0); + $this->assertNotCached(1); + + $this->renderBlock(1); + $this->assertCached(1); + + // Initially the blocks should have 0 members. + $this->assertMemberCount(0, 0); + $this->assertMemberCount(1, 0); + + // In the default configuration the block should only count active users, + // and ignore blocked and pending users. Also check that making changes to + // the members of the group only invalidates the cache of the related block. + $this->addMember(0, OgMembershipInterface::STATE_BLOCKED); + $this->addMember(0, OgMembershipInterface::STATE_PENDING); + $this->assertNotCached(0); + $this->assertCached(1); + $this->assertMemberCount(0, 0); + + // However adding an active user increases the member count. + $active_membership = $this->addMember(0, OgMembershipInterface::STATE_ACTIVE); + $this->assertMemberCount(0, 1); + + // If we block the active user, the member count should be updated + // accordingly. + $active_membership->setState(OgMembershipInterface::STATE_BLOCKED)->save(); + $this->assertMemberCount(0, 0); + + // Check that both blocks are invalidated when the block settings are + // changed. + $this->updateBlockSetting('count_pending_users', TRUE); + $this->assertNotCached(0); + $this->assertNotCached(1); + + // The block has now been configured to also count pending members. Check if + // the count is updated accordingly. + $this->assertMemberCount(0, 1); + $this->assertMemberCount(1, 0); + + // Turn on the counting of blocked members and check the resulting value. + $this->updateBlockSetting('count_blocked_users', TRUE); + $this->assertMemberCount(0, 3); + $this->assertMemberCount(1, 0); + + // Now delete one of the memberships of the first group. This should + // decrease the counter. + $active_membership->delete(); + $this->assertMemberCount(0, 2); + + // Since the deletion of the user only affected the first group, the block + // of the second group should still be unchanged and happily cached. + $this->assertCached(1); + $this->assertMemberCount(1, 0); + + // For good measure, try to add a user to the second group and check that + // all is in order. + $this->addMember(1, OgMembershipInterface::STATE_ACTIVE); + $this->assertMemberCount(1, 1); + + // The block from the first group should not be affected by this. + $this->assertCached(0); + $this->assertMemberCount(0, 2); + } + + /** + * Renders the block using the passed in group as the currently active group. + * + * @param int $group_key + * The key of the group to set as active group. + * + * @return string + * The content of the block rendered as HTML. + */ + protected function renderBlock($group_key) { + // Clear the static caches of the cache tags invalidators. The invalidators + // will only invalidate cache tags once per request to improve performance. + // Unfortunately they can not distinguish between an actual Drupal page + // request and a PHPUnit test that simulates visiting multiple pages. + // We are pretending that every time this method is called a new page has + // been requested, and the static caches are empty. + $this->cacheTagsInvalidator->resetChecksums(); + + $this->activeGroup = $this->groups[$group_key]; + $render_array = $this->blockViewBuilder->view($this->block); + $html = $this->renderer->renderRoot($render_array); + + // At all times, after a block is rendered, it should be cached. + $this->assertCached($group_key); + + return $html; + } + + /** + * Checks that the block shows the correct member count for the given group. + * + * @param int $group_key + * The key of the group for which to check the block. + * @param int $expected_count + * The number of members that are expected to be shown in the block. + */ + protected function assertMemberCount($group_key, $expected_count) { + $expected_string = (string) $this->formatPlural($expected_count, '@label has 1 member.', '@label has @count members', ['@label' => $this->groups[$group_key]->label()]); + $this->assertTrue(strpos($this->renderBlock($group_key), $expected_string) !== FALSE); + } + + /** + * Adds a member with the given membership state to the given group. + * + * @param int $group_key + * The key of the group to which a member should be added. + * @param string $state + * The membership state to assign to the newly added member. + * + * @return \Drupal\og\OgMembershipInterface + * The membership entity for the newly added member. + */ + protected function addMember($group_key, $state) { + $user = $this->createUser(); + return $this->createOgMembership($this->groups[$group_key], $user, NULL, $state); + } + + /** + * Updates the given setting in the block with the given value. + * + * @param string $setting + * The setting to update. + * @param mixed $value + * The value to set. + * + * @throws \Drupal\Core\Entity\EntityStorageException + * Thrown when the updated block cannot be saved. + */ + protected function updateBlockSetting($setting, $value) { + $settings = $this->block->get('settings'); + $settings[$setting] = $value; + $this->block->set('settings', $settings)->save(); + } + + /** + * Checks that the block is cached for the given group. + * + * @param int $group_key + * The key of the group for which to check the block cache status. + */ + protected function assertCached($group_key) { + $this->doAssertCached('assertNotEmpty', $group_key); + } + + /** + * Checks that the block is not cached for the given group. + * + * @param int $group_key + * The key of the group for which to check the block cache status. + */ + protected function assertNotCached($group_key) { + $this->doAssertCached('assertEmpty', $group_key); + } + + /** + * Checks the cache status of the block for the given group. + * + * @param string $assert_method + * The method to use for asserting that the block is cached or not cached. + * @param int $group_key + * The key of the group for which to check the block cache status. + */ + protected function doAssertCached($assert_method, $group_key) { + // We will switch the currently active context so that the right cache + // contexts are available for the render cache. Keep track of the currently + // active group so we can restore it after checking the cache status. + $original_active_group = $this->activeGroup; + $this->activeGroup = $this->groups[$group_key]; + + // Retrieve the block to render, and apply the required cache contexts that + // are also applied when RendererInterface::renderRoot() is executed. This + // ensures that we pass the same cache information to the render cache as is + // done when actually rendering the HTML root. + $render_array = $this->blockViewBuilder->view($this->block); + $render_array['#cache']['contexts'] = Cache::mergeContexts($render_array['#cache']['contexts'], $this->container->getParameter('renderer.config')['required_cache_contexts']); + + // Retrieve the cached data and perform the assertion. + $cached_data = $this->renderCache->get($render_array); + $this->$assert_method($cached_data); + + // Restore the active group. + $this->activeGroup = $original_active_group; + } + + /** + * Callback providing the active group to be returned by the mocked OgContext. + * + * @return \Drupal\entity_test\Entity\EntityTest + * The active group. + */ + public function getActiveGroup() { + return $this->activeGroup; + } + +} From daf8ad58adedce55d3b22b6939ebda7f017258e8 Mon Sep 17 00:00:00 2001 From: Pieter Frenssen Date: Mon, 29 Apr 2019 21:02:41 +0200 Subject: [PATCH 2/7] Update documentation. --- src/MembershipManagerInterface.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/MembershipManagerInterface.php b/src/MembershipManagerInterface.php index 835b9cadb..a5646e76b 100644 --- a/src/MembershipManagerInterface.php +++ b/src/MembershipManagerInterface.php @@ -193,7 +193,7 @@ public function getGroups(EntityInterface $entity, $group_type_id = NULL, $group * Returns the number of groups associated with a given group content entity. * * Do not use this to retrieve the group membership count for a user entity. - * Use count(Og::GetEntityGroups()) instead. + * Use count(\Drupal\og\MembershipManager::getUserGroupIds()) instead. * * @param \Drupal\Core\Entity\EntityInterface $entity * The group content entity for which to count the associated groups. From f275ab02343fa2d36e4f29bb49a5f79c25c8fd40 Mon Sep 17 00:00:00 2001 From: Pieter Frenssen Date: Mon, 29 Apr 2019 22:02:42 +0200 Subject: [PATCH 3/7] Do not assume the group is always available. --- src/Entity/OgMembership.php | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/Entity/OgMembership.php b/src/Entity/OgMembership.php index be2a039ee..73f9587ac 100644 --- a/src/Entity/OgMembership.php +++ b/src/Entity/OgMembership.php @@ -494,8 +494,10 @@ protected function invalidateTagsOnSave($update) { // membership listings because it now meets those listings' filtering // requirements. A newly created membership may start to appear in listings // because it did not exist before. - $tags = Cache::buildTags('og-group-membership-list', $this->getGroup()->getCacheTagsToInvalidate()); - Cache::invalidateTags($tags); + if ($group = $this->getGroup()) { + $tags = Cache::buildTags('og-group-membership-list', $group->getCacheTagsToInvalidate()); + Cache::invalidateTags($tags); + } } /** @@ -509,7 +511,9 @@ protected static function invalidateTagsOnDelete(EntityTypeInterface $entity_typ // will be recalculated. $tags = []; foreach ($entities as $entity) { - $tags = Cache::mergeTags(Cache::buildTags('og-group-membership-list', $entity->getGroup()->getCacheTagsToInvalidate()), $tags); + if ($group = $entity->getGroup()) { + $tags = Cache::mergeTags(Cache::buildTags('og-group-membership-list', $group->getCacheTagsToInvalidate()), $tags); + } } Cache::invalidateTags($tags); } From 5d0995c05a72414d21d94b3062f41c998a2e00d6 Mon Sep 17 00:00:00 2001 From: Pieter Frenssen Date: Tue, 30 Apr 2019 13:20:08 +0300 Subject: [PATCH 4/7] Use a constant for the group membership list cache tag prefix. --- src/Entity/OgMembership.php | 10 +++++----- src/OgMembershipInterface.php | 5 +++++ src/Plugin/Block/MemberCountBlock.php | 8 ++++---- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/Entity/OgMembership.php b/src/Entity/OgMembership.php index 73f9587ac..95cb6c0d1 100644 --- a/src/Entity/OgMembership.php +++ b/src/Entity/OgMembership.php @@ -495,7 +495,7 @@ protected function invalidateTagsOnSave($update) { // requirements. A newly created membership may start to appear in listings // because it did not exist before. if ($group = $this->getGroup()) { - $tags = Cache::buildTags('og-group-membership-list', $group->getCacheTagsToInvalidate()); + $tags = Cache::buildTags(OgMembershipInterface::GROUP_MEMBERSHIP_LIST_CACHE_TAG_PREFIX, $group->getCacheTagsToInvalidate()); Cache::invalidateTags($tags); } } @@ -506,13 +506,13 @@ protected function invalidateTagsOnSave($update) { protected static function invalidateTagsOnDelete(EntityTypeInterface $entity_type, array $entities) { parent::invalidateTagsOnDelete($entity_type, $entities); - // A membership was deleted: invalidate the membership list cache tags of - // its group membership lists, so that any lists that contain the membership - // will be recalculated. + // A membership was deleted: invalidate the list cache tags of its group + // membership lists, so that any lists that contain the membership will be + // recalculated. $tags = []; foreach ($entities as $entity) { if ($group = $entity->getGroup()) { - $tags = Cache::mergeTags(Cache::buildTags('og-group-membership-list', $group->getCacheTagsToInvalidate()), $tags); + $tags = Cache::mergeTags(Cache::buildTags(OgMembershipInterface::GROUP_MEMBERSHIP_LIST_CACHE_TAG_PREFIX, $group->getCacheTagsToInvalidate()), $tags); } } Cache::invalidateTags($tags); diff --git a/src/OgMembershipInterface.php b/src/OgMembershipInterface.php index 2f6a4911f..5c5f2092a 100644 --- a/src/OgMembershipInterface.php +++ b/src/OgMembershipInterface.php @@ -57,6 +57,11 @@ interface OgMembershipInterface extends ContentEntityInterface, EntityOwnerInter */ const REQUEST_FIELD = 'og_membership_request'; + /** + * The prefix that is used to identify group membership list cache tags. + */ + const GROUP_MEMBERSHIP_LIST_CACHE_TAG_PREFIX = 'og-group-membership-list'; + /** * Gets the membership creation timestamp. * diff --git a/src/Plugin/Block/MemberCountBlock.php b/src/Plugin/Block/MemberCountBlock.php index abdc61de4..eb11ccf97 100644 --- a/src/Plugin/Block/MemberCountBlock.php +++ b/src/Plugin/Block/MemberCountBlock.php @@ -15,9 +15,9 @@ /** * Provides a block that shows the number of members in the current group. * - * This block is mainly intended to demonstrate the 'og-group-membership-list' - * cache tag but can also be used to show the number of members on group pages. - * The way the text is displayed can be changed by overriding the Twig template. + * This block is mainly intended to demonstrate the group membership list cache + * tag but can also be used to show the number of members on group pages. The + * way the text is displayed can be changed by overriding the Twig template. * * @Block( * id = "og_member_count", @@ -151,7 +151,7 @@ public function getCacheTags() { $tags = parent::getCacheTags(); if ($group = $this->ogContext->getGroup()) { - $tags = Cache::mergeTags(Cache::buildTags('og-group-membership-list', $group->getCacheTagsToInvalidate()), $tags); + $tags = Cache::mergeTags(Cache::buildTags(OgMembershipInterface::GROUP_MEMBERSHIP_LIST_CACHE_TAG_PREFIX, $group->getCacheTagsToInvalidate()), $tags); } return $tags; From fbcf76748d67566cb518cc3d5580f4e122c269ac Mon Sep 17 00:00:00 2001 From: Pieter Frenssen Date: Tue, 30 Apr 2019 17:37:14 +0300 Subject: [PATCH 5/7] Do not assign variables inside if statements. --- src/Entity/OgMembership.php | 3 ++- src/Plugin/Block/MemberCountBlock.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Entity/OgMembership.php b/src/Entity/OgMembership.php index 95cb6c0d1..c32aa4835 100644 --- a/src/Entity/OgMembership.php +++ b/src/Entity/OgMembership.php @@ -494,7 +494,8 @@ protected function invalidateTagsOnSave($update) { // membership listings because it now meets those listings' filtering // requirements. A newly created membership may start to appear in listings // because it did not exist before. - if ($group = $this->getGroup()) { + $group = $this->getGroup(); + if (!empty($group)) { $tags = Cache::buildTags(OgMembershipInterface::GROUP_MEMBERSHIP_LIST_CACHE_TAG_PREFIX, $group->getCacheTagsToInvalidate()); Cache::invalidateTags($tags); } diff --git a/src/Plugin/Block/MemberCountBlock.php b/src/Plugin/Block/MemberCountBlock.php index eb11ccf97..d5d5128b5 100644 --- a/src/Plugin/Block/MemberCountBlock.php +++ b/src/Plugin/Block/MemberCountBlock.php @@ -150,7 +150,8 @@ public function build() { public function getCacheTags() { $tags = parent::getCacheTags(); - if ($group = $this->ogContext->getGroup()) { + $group = $this->ogContext->getGroup(); + if (!empty($group)) { $tags = Cache::mergeTags(Cache::buildTags(OgMembershipInterface::GROUP_MEMBERSHIP_LIST_CACHE_TAG_PREFIX, $group->getCacheTagsToInvalidate()), $tags); } From 16f5145747b72458b5e94f3e7a7f05915920e2ce Mon Sep 17 00:00:00 2001 From: Pieter Frenssen Date: Tue, 30 Apr 2019 17:37:50 +0300 Subject: [PATCH 6/7] Pass the membership states used in the count to the theme layer. --- og.module | 1 + src/Plugin/Block/MemberCountBlock.php | 10 ++++------ templates/og-member-count.html.twig | 1 + 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/og.module b/og.module index f111b7b67..695e7d1d5 100755 --- a/og.module +++ b/og.module @@ -311,6 +311,7 @@ function og_theme($existing, $type, $theme, $path) { 'og_member_count' => [ 'variables' => [ 'count' => 0, + 'membership_states' => [], 'group' => NULL, ], ], diff --git a/src/Plugin/Block/MemberCountBlock.php b/src/Plugin/Block/MemberCountBlock.php index d5d5128b5..993b93652 100644 --- a/src/Plugin/Block/MemberCountBlock.php +++ b/src/Plugin/Block/MemberCountBlock.php @@ -135,12 +135,10 @@ public function build() { $membership_ids = $this->membershipManager->getGroupMembershipIdsByRoleNames($group, [OgRoleInterface::AUTHENTICATED], $states); return [ - 'list' => [ - '#theme' => 'og_member_count', - '#count' => count($membership_ids), - '#group' => $group, - '#attributes' => ['class' => ['tralalala']], - ], + '#theme' => 'og_member_count', + '#count' => count($membership_ids), + '#group' => $group, + '#membership_states' => $states, ]; } diff --git a/templates/og-member-count.html.twig b/templates/og-member-count.html.twig index bc478e29a..2db726d1b 100644 --- a/templates/og-member-count.html.twig +++ b/templates/og-member-count.html.twig @@ -5,6 +5,7 @@ * * Available variables: * - count: The number of members in the group. + * - membership_states: An array of membership states included in the count. * - group_label: The group label. * * @see \Drupal\og\Plugin\Block\MemberCountBlock From f2d4a1b026f513ce559ff191f1116abc49d26749 Mon Sep 17 00:00:00 2001 From: Pieter Frenssen Date: Tue, 30 Apr 2019 17:38:15 +0300 Subject: [PATCH 7/7] The attributes are put on the containing block div. --- templates/og-member-count.html.twig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/templates/og-member-count.html.twig b/templates/og-member-count.html.twig index 2db726d1b..6ad68425c 100644 --- a/templates/og-member-count.html.twig +++ b/templates/og-member-count.html.twig @@ -13,7 +13,7 @@ * @ingroup themeable */ #} -

+

{% trans %} {{ group_label }} has 1 member. {% plural count %}