diff --git a/.travis.yml b/.travis.yml index 9e68280..4ef72a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -51,6 +51,13 @@ before_script: - travis_retry git clone --branch 8.x-1.x --depth 1 https://github.com/Gizra/message_notify.git - cd .. + # Patch flag. + # @todo Remove this once https://www.drupal.org/node/2802653 lands. + - cd modules/flag + - curl https://www.drupal.org/files/issues/2802653-10.patch > patch.txt + - git apply patch.txt + - cd - + # Install Composer dependencies on 8.1.x and above. - test ${DRUPAL_CORE} == "8.0.x" || composer self-update && composer install diff --git a/message_subscribe_email/config/optional/views.view.subscribe_node_email.yml b/message_subscribe_email/config/optional/views.view.subscribe_node_email.yml index eecf101..25848b1 100644 --- a/message_subscribe_email/config/optional/views.view.subscribe_node_email.yml +++ b/message_subscribe_email/config/optional/views.view.subscribe_node_email.yml @@ -251,7 +251,7 @@ display: plugin_id: flag_link filters: status: - value: true + value: '1' table: node_field_data field: status plugin_id: boolean diff --git a/message_subscribe_email/config/optional/views.view.subscribe_user_email.yml b/message_subscribe_email/config/optional/views.view.subscribe_user_email.yml index c0f4f6e..b792d13 100644 --- a/message_subscribe_email/config/optional/views.view.subscribe_user_email.yml +++ b/message_subscribe_email/config/optional/views.view.subscribe_user_email.yml @@ -241,7 +241,7 @@ display: plugin_id: flag_link filters: status: - value: true + value: '1' table: users_field_data field: status plugin_id: boolean diff --git a/message_subscribe_email/message_subscribe_email.module b/message_subscribe_email/message_subscribe_email.module index 0c9242b..ea1ee9e 100644 --- a/message_subscribe_email/message_subscribe_email.module +++ b/message_subscribe_email/message_subscribe_email.module @@ -4,33 +4,32 @@ * Code for the message subscribe email feature. */ +use Drupal\Core\Access\AccessResult; +use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Session\AccountInterface; use Drupal\flag\FlagInterface; /** - * Implements hook_flag_access(). - * - * @todo Flag access is broken. See https://www.drupal.org/node/2584647. + * Implements hook_flag_action_access(). */ -function message_subscribe_email_flag_access(FlagInterface $flag, $action, AccountInterface $account) { - return; - if (strpos($flag->name, 'email_') === 0) { - - $entity_type = FLAG_API_VERSION == 3 ? $flag->entity_type : $flag->content_type; +function message_subscribe_email_flag_action_access($action, FlagInterface $flag, AccountInterface $account, EntityInterface $flaggable = NULL) { + // The 'unflag' action is always allowed here, so only check 'flag'. + if ($action === 'flag' && $flaggable && strpos($flag->id(), 'email_') === 0) { // Get the other flags on that same content. - $user_flags = flag_get_user_flags($entity_type, $content_id, $account->uid); + /** @var \Drupal\flag\FlaggingInterface[] $user_flaggings */ + $user_flaggings = \Drupal::service('flag')->getAllEntityFlaggings($flaggable, $account); + $user_flags = []; + foreach ($user_flaggings as $flagging) { + $user_flags[$flagging->getFlagId()] = $flagging; + } - $name = str_replace('email_', '', $flag->name); - // @FIXME -// // @FIXME -// // This looks like another module's variable. You'll need to rewrite this call -// // to ensure that it uses the correct configuration object. -// $prefix = variable_get('flag_prefix', 'subscribe') . '_'; + // Find the corresponding subscribe_* flag. + $name = str_replace('email_', '', $flag->id()); + $prefix = \Drupal::config('message_subscribe.settings')->get('flag_prefix') . '_'; - // Disable access to the flag when the subscribe flag is unflagged, but - // allow unflagging. - return $action == 'unflag' || !empty($user_flags[$prefix . $name]); + // Disable access to the flag when the subscribe flag is unflagged. + return AccessResult::forbiddenIf(empty($user_flags[$prefix . $name])); } } diff --git a/message_subscribe_email/src/EventSubscriber/FlagEvents.php b/message_subscribe_email/src/EventSubscriber/FlagEvents.php index e2400a8..0095a15 100644 --- a/message_subscribe_email/src/EventSubscriber/FlagEvents.php +++ b/message_subscribe_email/src/EventSubscriber/FlagEvents.php @@ -26,7 +26,7 @@ class FlagEvents implements EventSubscriberInterface { /** * The flag service. * - * @var \Drupal\flag\FlagServiceInterface $flag_service + * @var \Drupal\flag\FlagServiceInterface */ protected $flagService; diff --git a/message_subscribe_email/tests/src/Kernel/MessageSubscribeEmailNotificationsTest.php b/message_subscribe_email/tests/src/Kernel/MessageSubscribeEmailNotificationsTest.php index 033ac89..a888b07 100644 --- a/message_subscribe_email/tests/src/Kernel/MessageSubscribeEmailNotificationsTest.php +++ b/message_subscribe_email/tests/src/Kernel/MessageSubscribeEmailNotificationsTest.php @@ -69,4 +69,27 @@ public function testEmailNotifications() { $this->assertEquals($expected_uids, $uids, 'All expected subscribers were fetched.'); } + /** + * Verify flag action access for the email_* flags. + */ + public function testFlagActionAccess() { + $node = $this->nodes[1]; + $user = $this->users[1]; + $email_flag = $this->flagService->getFlagById('email_node'); + $subscribe_flag = $this->flagService->getFlagById('subscribe_node'); + + // When the item is flagged, flag and unflag access should be available. + $access = $email_flag->actionAccess('flag', $user, $node); + $this->assertTrue($access->isAllowed()); + $access = $email_flag->actionAccess('unflag', $user); + $this->assertTrue($access->isAllowed()); + + // Unflag the entity, and now only the unflag action should be available. + $this->flagService->unflag($subscribe_flag, $node, $user); + $access = $email_flag->actionAccess('flag', $user, $node); + $this->assertFalse($access->isAllowed()); + $access = $email_flag->actionAccess('unflag', $user, $node); + $this->assertTrue($access->isAllowed()); + } + } diff --git a/message_subscribe_ui/config/optional/views.view.subscribe_node.yml b/message_subscribe_ui/config/optional/views.view.subscribe_node.yml index 9277afc..f32da71 100644 --- a/message_subscribe_ui/config/optional/views.view.subscribe_node.yml +++ b/message_subscribe_ui/config/optional/views.view.subscribe_node.yml @@ -201,7 +201,7 @@ display: plugin_id: flag_link filters: status: - value: true + value: '1' table: node_field_data field: status plugin_id: boolean diff --git a/message_subscribe_ui/config/optional/views.view.subscribe_user.yml b/message_subscribe_ui/config/optional/views.view.subscribe_user.yml index 2d515ac..80d216b 100644 --- a/message_subscribe_ui/config/optional/views.view.subscribe_user.yml +++ b/message_subscribe_ui/config/optional/views.view.subscribe_user.yml @@ -191,7 +191,7 @@ display: plugin_id: flag_link filters: status: - value: true + value: '1' table: users_field_data field: status plugin_id: boolean diff --git a/message_subscribe_ui/src/Controller/SubscriptionController.php b/message_subscribe_ui/src/Controller/SubscriptionController.php index d000a5f..f1e939d 100644 --- a/message_subscribe_ui/src/Controller/SubscriptionController.php +++ b/message_subscribe_ui/src/Controller/SubscriptionController.php @@ -111,7 +111,7 @@ public function tabAccess(AccountInterface $user, FlagInterface $flag = NULL) { return AccessResult::allowed(); } - if (!$flag->hasActionAccess('unflag', $user) || $user->id() != $this->currentUser->id()) { + if (!$flag->actionAccess('unflag', $user) || $user->id() != $this->currentUser->id()) { return AccessResult::forbidden(); } @@ -139,7 +139,7 @@ public function tabTitle(FlagInterface $flag) { * @param \Drupal\flag\FlagInterface $flag * The flag to display subscriptions for. * - * @return array A render array. + * @return array * A render array. */ public function tab(UserInterface $user, FlagInterface $flag = NULL) { diff --git a/src/SubscribersInterface.php b/src/SubscribersInterface.php index 925c14d..dbdfaea 100644 --- a/src/SubscribersInterface.php +++ b/src/SubscribersInterface.php @@ -138,7 +138,7 @@ public function getBasicContext(EntityInterface $entity, $skip_detailed_context * (optional) The user account to filter available flags. If not set, all * flags for the given entity and bundle will be returned. * - * @return \Drupal\flag\FlagInterface[] $flags + * @return \Drupal\flag\FlagInterface[] * An array of the structure [fid] = flag_object. * * @see \Drupal\flag\FlagServiceInterface::getFlags()