diff --git a/message_subscribe_email/config/optional/field.field.flagging.email_node.subscribe_flagging.yml b/message_subscribe_email/config/optional/field.field.flagging.email_node.subscribe_flagging.yml new file mode 100644 index 0000000..c493d4f --- /dev/null +++ b/message_subscribe_email/config/optional/field.field.flagging.email_node.subscribe_flagging.yml @@ -0,0 +1,20 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.flagging.subscribe_flagging + - flag.flag.email_node +id: flagging.email_node.subscribe_flagging +field_name: subscribe_flagging +entity_type: flagging +bundle: email_node +label: 'Subscription flagging' +description: 'The subscribe flagging that this is tied to.' +required: true +translatable: true +default_value: { } +default_value_callback: '' +settings: + handler: 'default:flagging' + handler_settings: { } +field_type: entity_reference diff --git a/message_subscribe_email/config/optional/field.field.flagging.email_og.subscribe_flagging.yml b/message_subscribe_email/config/optional/field.field.flagging.email_og.subscribe_flagging.yml new file mode 100644 index 0000000..65dc811 --- /dev/null +++ b/message_subscribe_email/config/optional/field.field.flagging.email_og.subscribe_flagging.yml @@ -0,0 +1,20 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.flagging.subscribe_flagging + - flag.flag.email_og +id: flagging.email_og.subscribe_flagging +field_name: subscribe_flagging +entity_type: flagging +bundle: email_og +label: 'Subscription flagging' +description: 'The subscribe flagging that this is tied to.' +required: true +translatable: true +default_value: { } +default_value_callback: '' +settings: + handler: 'default:flagging' + handler_settings: { } +field_type: entity_reference diff --git a/message_subscribe_email/config/optional/field.field.flagging.email_term.subscribe_flagging.yml b/message_subscribe_email/config/optional/field.field.flagging.email_term.subscribe_flagging.yml new file mode 100644 index 0000000..5fb0ec3 --- /dev/null +++ b/message_subscribe_email/config/optional/field.field.flagging.email_term.subscribe_flagging.yml @@ -0,0 +1,20 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.flagging.subscribe_flagging + - flag.flag.email_term +id: flagging.email_term.subscribe_flagging +field_name: subscribe_flagging +entity_type: flagging +bundle: email_term +label: 'Subscription flagging' +description: 'The subscribe flagging that this is tied to.' +required: true +translatable: true +default_value: { } +default_value_callback: '' +settings: + handler: 'default:flagging' + handler_settings: { } +field_type: entity_reference diff --git a/message_subscribe_email/config/optional/field.field.flagging.email_user.subscribe_flagging.yml b/message_subscribe_email/config/optional/field.field.flagging.email_user.subscribe_flagging.yml new file mode 100644 index 0000000..50802d3 --- /dev/null +++ b/message_subscribe_email/config/optional/field.field.flagging.email_user.subscribe_flagging.yml @@ -0,0 +1,20 @@ +langcode: en +status: true +dependencies: + config: + - field.storage.flagging.subscribe_flagging + - flag.flag.email_user +id: flagging.email_user.subscribe_flagging +field_name: subscribe_flagging +entity_type: flagging +bundle: email_user +label: 'Subscription flagging' +description: 'The subscribe flagging that this is tied to.' +required: true +translatable: true +default_value: { } +default_value_callback: '' +settings: + handler: 'default:flagging' + handler_settings: { } +field_type: entity_reference diff --git a/message_subscribe_email/config/optional/field.storage.flagging.subscribe_flagging.yml b/message_subscribe_email/config/optional/field.storage.flagging.subscribe_flagging.yml new file mode 100644 index 0000000..25fedf1 --- /dev/null +++ b/message_subscribe_email/config/optional/field.storage.flagging.subscribe_flagging.yml @@ -0,0 +1,18 @@ +langcode: en +status: true +dependencies: + module: + - flag +id: flagging.subscribe_flagging +field_name: subscribe_flagging +entity_type: flagging +type: entity_reference +settings: + target_type: flagging +module: core +locked: true +cardinality: 1 +translatable: true +indexes: { } +persist_with_no_fields: false +custom_storage: false diff --git a/message_subscribe_email/message_subscribe_email.install b/message_subscribe_email/message_subscribe_email.install index fd0f0b6..7e4b35b 100644 --- a/message_subscribe_email/message_subscribe_email.install +++ b/message_subscribe_email/message_subscribe_email.install @@ -5,6 +5,9 @@ * Install hooks for the message_subscribe_email module. */ +use Drupal\field\Entity\FieldConfig; +use Drupal\field\Entity\FieldStorageConfig; + /** * Implements hook_install(). * @@ -46,3 +49,39 @@ function message_subscribe_email_install() { } } } + +/** + * Add an entity reference to the original subscribe flagging. + */ +function message_subscribe_email_update_8100() { + FieldStorageConfig::create([ + 'entity_type' => 'flagging', + 'field_name' => 'subscribe_flagging', + 'type' => 'entity_reference', + 'settings' => [ + 'target_type' => 'flagging', + ], + 'locked' => TRUE, + ])->setCardinality(1)->save(); + + $emailPrefix = \Drupal::config('message_subscribe_email.settings')->get('flag_prefix') . '_'; + $flags = \Drupal::entityTypeManager()->getStorage('flag')->loadMultiple(); + foreach ($flags as $flag) { + if (strpos($flag->id(), $emailPrefix) === 0) { + FieldConfig::create([ + 'entity_type' => 'flagging', + 'bundle' => $flag->id(), + 'field_name' => 'subscribe_flagging', + 'type' => 'entity_reference', + 'cardinality' => 1, + ]) + ->setLabel('Subscription flagging') + ->setDescription('The subscribe flagging that this is tied to.') + ->setRequired(TRUE) + ->setSetting('target_type', 'flagging') + ->setSetting('handler', 'default') + ->setSetting('handler_settings', []) + ->save(); + } + } +} diff --git a/message_subscribe_email/message_subscribe_email.module b/message_subscribe_email/message_subscribe_email.module index cf4d275..165316b 100644 --- a/message_subscribe_email/message_subscribe_email.module +++ b/message_subscribe_email/message_subscribe_email.module @@ -9,6 +9,7 @@ use Drupal\Core\Access\AccessResult; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Session\AccountInterface; +use Drupal\flag\FlaggingInterface; use Drupal\flag\FlagInterface; /** @@ -79,8 +80,8 @@ function message_subscribe_email_message_subscribe_get_subscribers_alter(array & ->condition('flag_id', $flag_ids, 'IN') ->condition('uid', array_keys($uids), 'IN') // Ensure to grab the correct flagging. - ->condition('entity_type', $entity_type) - ->condition('entity_id', $entity_ids, 'IN') + ->condition('flagged_entity__target_type', $entity_type) + ->condition('flagged_entity__target_id', $entity_ids, 'IN') ->groupBy('uid') ->execute() ->fetchAllAssoc('uid'); @@ -128,3 +129,26 @@ function message_subscribe_email_message_subscribe_admin_settings_form_submit(ar ->set('flag_prefix', $form_state->getValue('message_subscribe_email_flag_prefix')) ->save(); } + +/** + * Implements hook_ENTITY_TYPE_presave(). + */ +function message_subscribe_email_flagging_presave(FlaggingInterface $entity) { + $subscribePrefix = \Drupal::config('message_subscribe.settings')->get('flag_prefix') . '_'; + $emailPrefix = \Drupal::config('message_subscribe_email.settings')->get('flag_prefix') . '_'; + + // Automatically set the reference to the subscribe flagging on creation. + if ($entity->isNew() && strpos($entity->bundle(), $emailPrefix) === 0) { + $storage = \Drupal::entityTypeManager()->getStorage('flagging'); + $bundle = str_replace($emailPrefix, $subscribePrefix, $entity->bundle()); + $result = $storage->getQuery() + ->condition('flag_id', $bundle) + ->condition('flagged_entity__target_id', $entity->getFlaggableId()) + ->condition('flagged_entity__target_type', $entity->getFlaggableType()) + ->condition('uid', $entity->getOwnerId()) + ->execute(); + if (!empty($result)) { + $entity->subscribe_flagging->target_id = reset($result); + } + } +} diff --git a/message_subscribe_email/message_subscribe_email.post_update.php b/message_subscribe_email/message_subscribe_email.post_update.php new file mode 100644 index 0000000..afa7cb8 --- /dev/null +++ b/message_subscribe_email/message_subscribe_email.post_update.php @@ -0,0 +1,72 @@ +get('flag_prefix') . '_'; + $emailPrefix = \Drupal::config('message_subscribe_email.settings')->get('flag_prefix') . '_'; + $storage = \Drupal::entityTypeManager()->getStorage('flagging'); + + $ids = $storage->getQuery() + ->condition('flag_id', $emailPrefix . '%', 'LIKE') + ->notExists('subscribe_flagging') + ->range(0, 100) + ->execute(); + + if (!isset($sandbox['current'])) { + $sandbox['current'] = 0; + $sandbox['max'] = $storage->getQuery() + ->condition('flag_id', $emailPrefix . '%', 'LIKE') + ->notExists('subscribe_flagging') + ->count() + ->execute(); + } + + foreach ($ids as $id) { + $sandbox['current']++; + $flagging = $storage->load($id); + $bundle = str_replace($emailPrefix, $subscribePrefix, $flagging->bundle()); + $flaggedEntity = $flagging->flagged_entity->entity; + + // Clean up any flaggings where the flagged entity no longer exists. + if (empty($flaggedEntity)) { + $flagging->delete(); + $sandbox['deleted']++; + continue; + } + + // Look up the corresponding subscribe flagging. + $result = $storage->getQuery() + ->condition('flag_id', $bundle) + ->condition('flagged_entity__target_id', $flaggedEntity->id()) + ->condition('flagged_entity__target_type', $flaggedEntity->getEntityTypeId()) + ->condition('uid', $flagging->uid->target_id) + ->execute(); + + // Populate the new field, if it could be found. + if (!empty($result)) { + $flagging->subscribe_flagging->target_id = reset($result); + $flagging->save(); + } + // Otherwise, clean up the rogue email flag. It can't exist without its + // subscribe counterpart. + else { + $flagging->delete(); + $sandbox['deleted']++; + } + } + + $sandbox['#finished'] = empty($sandbox['max']) ? 1 : ($sandbox['current'] / $sandbox['max']); + if ($sandbox['#finished'] >= 1) { + return t('Updated @updated flagging items and deleted @deleted orphaned flagging items.', ['@updated' => $sandbox['max'], '@deleted' => $sandbox['deleted']]); + } + elseif (function_exists('drush_print')) { + drush_print('Completed ' . $sandbox['current'] . ' / ' . $sandbox['max'] . ' (' . number_format($sandbox['current'] / $sandbox['max'] * 100, 2) . '%)'); + } +}