-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #335 from moreonion/m2t-send
New module for sending m2t emails in a cron-job
- Loading branch information
Showing
6 changed files
with
489 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
name = Match to target send | ||
description = Send M2T messages asynchronously | ||
core = 7.x | ||
package = Campaignion | ||
|
||
dependencies[] = psr0:psr0 | ||
dependencies[] = campaignion:campaignion_email_to_target | ||
dependencies[] = little_helpers:little_helpers | ||
dependencies[] = ultimate_cron:ultimate_cron | ||
dependencies[] = variable:variable | ||
dependencien[] = webform:webform |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
<?php | ||
|
||
use Drupal\campaignion_m2t_send\Submission; | ||
|
||
/** | ||
* Implements hook_install(). | ||
* | ||
* Migrate flags stored in webform_submitted_data. | ||
*/ | ||
function campaignion_m2t_send_install() { | ||
$types = _campaignion_m2t_send_content_types(); | ||
$sql = <<<SQL | ||
INSERT INTO {campaignion_m2t_send} | ||
SELECT nid, sid, cid, no, NULL, NULL | ||
FROM {node} n | ||
INNER JOIN {webform_submissions} s USING (nid) | ||
INNER JOIN {webform_component} c USING(nid) | ||
INNER JOIN {webform_submitted_data} d USING(nid, sid, cid) | ||
WHERE n.type IN(:types) AND c.type='e2t_selector' | ||
SQL; | ||
db_query($sql, [':types' => $types]); | ||
$nids = db_select('campaignion_m2t_send', 'm') | ||
->fields('m', ['nid']) | ||
->groupBy('nid') | ||
->execute() | ||
->fetchCol(); | ||
$nodes = entity_load('node', $nids); | ||
|
||
foreach (Submission::iterate($nodes) as $submission) { | ||
foreach (array_keys($submission->webform->componentsByType('e2t_selector')) as $cid) { | ||
foreach ($submission->valuesByCid($cid) as $no => $data) { | ||
$m = unserialize($data); | ||
if ($m['sent'] ?? NULL) { | ||
db_update('campaignion_m2t_send') | ||
->condition('nid', $submission->nid) | ||
->condition('sid', $submission->sid) | ||
->condition('cid', $cid) | ||
->condition('no', $no) | ||
->fields(['sent_at' => 0, 'target_email' => $m['target']['email']]) | ||
->execute(); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Implements hook_schema(). | ||
*/ | ||
function campaignion_m2t_send_schema() { | ||
$tables['campaignion_m2t_send'] = [ | ||
'description' => 'Stores the send status of email to target emails.', | ||
'fields' => [ | ||
'nid' => [ | ||
'description' => 'The node identifier of a webform.', | ||
'type' => 'int', | ||
'unsigned' => TRUE, | ||
'not null' => TRUE, | ||
'default' => 0, | ||
], | ||
'sid' => [ | ||
'description' => 'The unique identifier for this submission.', | ||
'type' => 'int', | ||
'unsigned' => TRUE, | ||
'not null' => TRUE, | ||
'default' => 0, | ||
], | ||
'cid' => [ | ||
'description' => 'The identifier for this component within this node, starts at 0 for each node.', | ||
'type' => 'int', | ||
'size' => 'small', | ||
'unsigned' => TRUE, | ||
'not null' => TRUE, | ||
'default' => 0, | ||
], | ||
'no' => [ | ||
'description' => 'Usually this value is 0, but if a field has multiple values (such as a time or date), it may require multiple rows in the database.', | ||
'type' => 'varchar', | ||
'length' => 128, | ||
'not null' => TRUE, | ||
'default' => '0', | ||
], | ||
'target_email' => [ | ||
'description' => 'Email address of the target the email was sent to.', | ||
'type' => 'varchar', | ||
'length' => 256, | ||
'not null' => FALSE, | ||
], | ||
'sent_at' => [ | ||
'desrciption' => 'The timestamp for when the email was sent (if)', | ||
'type' => 'int', | ||
'not null' => FALSE, | ||
], | ||
], | ||
'primary key' => ['nid', 'sid', 'cid', 'no'], | ||
'indexes' => [ | ||
'node' => ['nid'], | ||
'submission' => ['sid'], | ||
'component' => ['nid', 'sid', 'cid'], | ||
'unsent' => ['nid', 'sent_at'], | ||
'target' => ['target_email'], | ||
], | ||
]; | ||
return $tables; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
<?php | ||
|
||
/** | ||
* @file | ||
* Hook and callback implementations for this module. | ||
*/ | ||
|
||
use Drupal\campaignion_email_to_target\Channel\EmailNoSend; | ||
use Drupal\campaignion_m2t_send\SendMessagesCron; | ||
use Drupal\little_helpers\Services\Container; | ||
use Drupal\little_helpers\Webform\Submission; | ||
|
||
/** | ||
* Implements hook_little_helpers_services(). | ||
*/ | ||
function campaignion_m2t_send_little_helpers_services() { | ||
$info['campaignion_m2t_send.SendMessagesCron'] = [ | ||
'class' => SendMessagesCron::class, | ||
'arguments' => [ | ||
'!campaignion_m2t_send_enabled_nodes', | ||
'!campaignion_m2t_send_cron_time_limit', | ||
], | ||
]; | ||
return $info; | ||
} | ||
|
||
/** | ||
* Implements hook_cronapi(). | ||
*/ | ||
function campaignion_m2t_send_cronapi($op, $job = NULL) { | ||
$items['campaignion_m2t_send'] = [ | ||
'description' => 'Send M2T messages of selected nodes', | ||
'rule' => '*+@ 8-23 * * *', | ||
'weight' => 100, | ||
'callback' => '_campaignion_m2t_send_run', | ||
'arguments' => ['campaignion_m2t_send.SendMessagesCron'], | ||
]; | ||
return $items; | ||
} | ||
|
||
/** | ||
* Helper function to load a cron service and invoke it. | ||
*/ | ||
function _campaignion_m2t_send_run($service) { | ||
Container::get()->loadService($service)->run(); | ||
} | ||
|
||
/** | ||
* Helper function to get all M2T content types. | ||
* | ||
* @return str[] Array of node type machine names. | ||
*/ | ||
function _campaignion_m2t_send_content_types() { | ||
$types = &drupal_static(__FUNCTION__); | ||
if ($types === NULL) { | ||
$info = array_filter(module_invoke_all('campaignion_action_info'), function ($i) { | ||
return ($i['channel'] ?? NULL) == EmailNoSend::class; | ||
}); | ||
$types = array_keys($info); | ||
} | ||
return $types; | ||
} | ||
|
||
/** | ||
* Implements hook_webform_submission_insert(). | ||
*/ | ||
function campaignion_m2t_send_webform_submission_insert($node, $submission) { | ||
if (!in_array($node->type, _campaignion_m2t_send_content_types())) { | ||
return; | ||
} | ||
$s = new Submission($node, $submission); | ||
foreach ($s->webform->componentsByType('e2t_selector') as $component) { | ||
$values = $s->valuesByCid($component['cid']); | ||
db_delete('campaignion_m2t_send') | ||
->condition('nid', $node->nid) | ||
->condition('sid', $submission->sid) | ||
->condition('cid', $component['cid']) | ||
->condition('no', array_keys($values), 'NOT IN') | ||
->execute(); | ||
foreach ($values as $no => $value) { | ||
db_merge('campaignion_m2t_send')->key([ | ||
'nid' => $node->nid, | ||
'sid' => $submission->sid, | ||
'cid' => $component['cid'], | ||
'no' => $no, | ||
])->execute(); | ||
} | ||
} | ||
} | ||
|
||
/** | ||
* Implements hook_webform_submission_load(). | ||
*/ | ||
function campaignion_m2t_send_webform_submission_load(&$submissions) { | ||
$data_sql = <<<SQL | ||
SELECT nid, sid, cid, no, data | ||
FROM {webform_submitted_data} d | ||
INNER JOIN {campaignion_m2t_send} m USING(nid, sid, cid, no) | ||
WHERE sid IN(:sids) AND sent_at IS NULL | ||
SQL; | ||
foreach (db_query($data_sql, [':sids' => array_keys($submissions)]) as $d) { | ||
$submissions[$d->sid]->m2t_unsent_messages[] = $d; | ||
} | ||
} | ||
|
||
/** | ||
* Implements hook_webform_submission_update(). | ||
*/ | ||
function campaignion_m2t_send_webform_submission_update($node, $submission) { | ||
campaignion_m2t_send_webform_submission_insert($node, $submission); | ||
} | ||
|
||
/** | ||
* Implements hook_webform_submission_delete(). | ||
*/ | ||
function campaignion_m2t_send_webform_submission_delete($node, $submission) { | ||
db_delete('campaignion_m2t_send') | ||
->condition('sid', $submission->sid) | ||
->execute(); | ||
} | ||
|
||
/** | ||
* Implements hook_node_delete(). | ||
*/ | ||
function campaignion_m2t_send_node_delete($node) { | ||
db_delete('campaignion_m2t_send') | ||
->condition('nid', $node->nid) | ||
->execute(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
<?php | ||
|
||
/** | ||
* @file | ||
* Information about configuration variables defined by this module. | ||
*/ | ||
|
||
/** | ||
* Implements hook_variable_info(). | ||
*/ | ||
function campaignion_m2t_send_variable_info($options) { | ||
$v['campaignion_m2t_send_cron_time_limit'] = [ | ||
'title' => t('Time limit for M2T send cron-jobs'), | ||
'description' => t('When a m2t send cron-job has been running for more than this amount of seconds no new batch will be started during this cron-run.'), | ||
'type' => 'number', | ||
'default' => 20, | ||
'localize' => FALSE, | ||
]; | ||
$v['campaignion_m2t_send_enabled_nodes'] = [ | ||
'title' => t('Enabled nodes'), | ||
'description' => t('Only send emails for these nodes.'), | ||
'type' => 'unknown', | ||
'default' => [], | ||
]; | ||
return $v; | ||
} |
Oops, something went wrong.