Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
"patches": {
"drupal/core": {
"#2865059: Multiple machine name elements from same source": "https://www.drupal.org/files/issues/2865059-13-allow_multiple_machine_name_per_source.patch",
"#736066: ajax.js insert command sometimes wraps content in a div": "https://www.drupal.org/files/issues/736066-296.patch"
"#736066: ajax.js insert command sometimes wraps content in a div": "https://www.drupal.org/files/issues/736066-296.patch",
"#2584729: Hook entity_field_storage_info is broken": "https://www.drupal.org/files/issues/core-entity-sql-content-entity-storage-2583111-1_0.patch"
},
"drupal/ctools": {
"#2667652: Option to expose filters in block on views block display": "https://www.drupal.org/files/issues/ctools-option_to_expose-2667652-3.patch",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was there not a mailchimp patch as well?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yanniboi Yes - this is only needed if you install contacts_mailchimp though, so should it go in the composer.json for the contacts module, or would there need to be a new composer.json specifically for contacts_mailchimp?

Expand Down
34 changes: 34 additions & 0 deletions config/install/contacts.contact_tab.crm_communications_tab.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
langcode: en
status: true
dependencies:
config:
- profile.type.crm_communications
module:
- profile
id: crm_communications_tab
label: Communications
path: communications
layout: contacts_tab_content.stacked
weight: null
relationships:
profile_crm_communications:
id: 'typed_data_entity_relationship:entity:user:profile_crm_communications'
name: profile_crm_communications
source: user
blocks:
contacts_entity_profile_crm_communications:
id: 'contacts_entity:profile-crm_communications'
label: 'Communication Preferences'
provider: contacts
label_display: '0'
mode: view
create: true
operation: contacts_dashboard
view_mode: contacts_dashboard
edit_link: content
edit_id: edit
region: top
context_mapping:
entity: profile_crm_communications
user: user
name: contacts_entity_profile_crm_communications
16 changes: 16 additions & 0 deletions config/install/profile.type.crm_communications.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
langcode: en
status: true
dependencies: { }
id: crm_communications
label: Communications
registration: false
multiple: false
roles:
authenticated: '0'
administrator: '0'
crm_indiv: '0'
crm_org: '0'
student: '0'
weight: 0
use_revisions: false
description: ''
50 changes: 50 additions & 0 deletions contacts.module
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* Module related hook implementations for the contacts module.
*/

use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Url;
use Drupal\Core\Link;
Expand Down Expand Up @@ -723,3 +725,51 @@ function contacts_preprocess_block(&$variables, $hook) {
function contacts_form_user_register_form_alter(&$form, FormStateInterface $form_state, $form_id) {
$form['account']['roles']['#default_value'][] = 'crm_indiv';
}

/**
* Implements hook_entity_bundle_field_info().
*/
function contacts_entity_bundle_field_info(EntityTypeInterface $entity_type, $bundle, array $base_field_definitions) {
// Create the crm_opt_out field.
if ($entity_type->id() == 'profile' && $bundle == 'crm_communications') {
$fields['crm_opt_out'] = BaseFieldDefinition::create('boolean')
->setName('crm_opt_out')
->setLabel('Opt Out')
->setTargetEntityTypeId('profile')
->setTargetBundle('crm_communications')
->setDefaultValue(0)
->setDisplayConfigurable("form", TRUE)
->setDisplayConfigurable("view", TRUE)
->setDisplayOptions("form", [
'type' => 'boolean_checkbox',
'region' => 'content',
'settings' => ['display_label', TRUE],
'weight' => 0,
])
->setDisplayOptions("view", [
'type' => 'boolean',
'region' => 'content',
'settings' => ['display_label', TRUE],
'weight' => 0,
])
->setSettings(['on_label' => 'Yes', 'off_label' => 'No']);

return $fields;
}
}

/**
* Implements hook_entity_field_storage_info().
*/
function contacts_entity_field_storage_info(EntityTypeInterface $entity_type) {
// Ensure backing storage exists for crm_communications.
if ($entity_type->id() == 'profile') {
$storage['crm_opt_out'] = BaseFieldDefinition::create('boolean')
->setName('crm_opt_out')
->setCardinality(1)
->setTargetBundle('crm_communications')
->setTranslatable(TRUE)
->setTargetEntityTypeId('profile');
return $storage;
}
}
8 changes: 8 additions & 0 deletions modules/contacts_mailchimp/contacts_mailchimp.info.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: Contacts MailChimp Integration
description: "MailChimp integration for the Contacts module"
type: module
core: 8.x

dependencies:
- contacts
- mailchimp_lists (>=8.x-1.6)
60 changes: 60 additions & 0 deletions modules/contacts_mailchimp/contacts_mailchimp.module
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

/**
* @file
* Module related hook implementations for the contacts_mailchimp module.
*/

use Drupal\profile\Entity\Profile;
use Drupal\Core\Entity\EntityInterface;

/**
* Implements hook_entity_presave().
*/
function contacts_mailchimp_entity_presave(EntityInterface $entity) {
// Unsubscribe any mailchimp mailinglists if the user has opted out of comms.
$field_name = 'crm_opt_out';

if ($entity->getEntityTypeId() == 'profile' && $entity->bundle() == 'crm_communications' && $entity->hasField($field_name)) {
$opt_out = $entity->get($field_name)->value;

if (isset($entity->original)) {
$original = $entity->original->get($field_name)->value;
}
else {
$original = NULL;
}

// TODO: Investigate making this asynchronous.
if (($original === 0 || $original == NULL) && $opt_out === 1 && $entity->uid->entity->hasField('mail')) {
$email = $entity->uid->entity->mail->value;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not many ways of doing asynchronous in Drupal. We could consider moving it to a cron queue for performance, but its probably fine for now.

$lists = mailchimp_get_lists_for_email($email);
foreach ($lists as $list) {
mailchimp_unsubscribe($list->id, $email);
}
}
}
}

/**
* Implements hook_mailchimp_process_webhook().
*/
function contacts_mailchimp_mailchimp_process_webhook($type, $data) {
// If user unsubscribes from mailchimp, treat it as a full opt-out.
if ($type == 'unsubscribe') {
$ids = \Drupal::entityQuery('profile')
->condition('uid.entity.mail', $data['email'])
->condition('type', 'crm_communications')
->execute();

$profiles = Profile::loadMultiple($ids);

/* @var $profile \Drupal\profile\Entity\Profile */
foreach ($profiles as $profile) {
if ($profile->hasField('crm_opt_out')) {
$profile->set('crm_opt_out', 1);
$profile->save();
}
}
}
}