jenkins-bot has submitted this change and it was merged. ( https://gerrit.wikimedia.org/r/373976 )
Change subject: Delete wmf_communication\Job stuff ...................................................................... Delete wmf_communication\Job stuff Totally re-inventing the wheel, now that CiviCRM's mailing batch features are more accessible via API. Also, was only used in the one-offs script to send 'sorry' letters Change-Id: Ie7a48b938ebae6f5f3330133c547e047686408ae --- D sites/all/modules/wmf_communication/Job.php D sites/all/modules/wmf_communication/MailingTemplate.php D sites/all/modules/wmf_communication/Recipient.php D sites/all/modules/wmf_communication/tests/Job.test D sites/all/modules/wmf_communication/tests/TestThankyouTemplate.php D sites/all/modules/wmf_communication/tests/templates/subject/thank_you.it.subject D sites/all/modules/wmf_communication/tests/wmf_communication_tests.info D sites/all/modules/wmf_communication/tests/wmf_communication_tests.module M sites/all/modules/wmf_communication/wmf_communication.drush.inc M sites/all/modules/wmf_communication/wmf_communication.info D sites/all/modules/wmf_communication/wmf_communication.install M sites/all/modules/wmf_communication/wmf_communication.module 12 files changed, 0 insertions(+), 630 deletions(-) Approvals: jenkins-bot: Verified Eileen: Looks good to me, approved diff --git a/sites/all/modules/wmf_communication/Job.php b/sites/all/modules/wmf_communication/Job.php deleted file mode 100644 index 74aeebc..0000000 --- a/sites/all/modules/wmf_communication/Job.php +++ /dev/null @@ -1,150 +0,0 @@ -<?php namespace wmf_communication; - -use \Exception; - -/** - * Entity representing a single mailing job batch run - * - * A job can be created in small, decoupled steps, and intermediate values - * examined in the database. - * - * For example, here is the lifecycle of a typical job: - * - * // Create an empty mailing job, which will render letters using the - * // specified template. - * $job = Job::create( 'RecurringDonationsSnafuMay2013Template' ); - * - * foreach ( $recipients as $contact_id => $email ) { - * $job - * // Trigger the batch run. Execution - * $job->run(); - */ -class Job { - protected $id; - protected $template; - - /** - * Pull a job from the database. - * - * @param integer $id The job's database ID - */ - static function getJob( $id ) { - $job = new Job(); - $job->id = $id; - - watchdog( 'wmf_communication', - "Retrieving mailing job :id from the database.", - array( ':id' => $id ), - WATCHDOG_INFO - ); - $row = db_select( 'wmf_communication_job' ) - ->fields( 'wmf_communication_job' ) - ->condition( 'id', $id ) - ->execute() - ->fetchAssoc(); - - if ( !$row ) { - throw new Exception( 'No such job found: ' . $id ); - } - - $templateClass = $row['template_class']; - if ( !class_exists( $templateClass ) ) { - throw new Exception( 'Could not find mailing template class: ' . $templateClass ); - } - $job->template = new $templateClass; - if ( !( $job->template instanceof IMailingTemplate ) ) { - throw new Exception( 'Mailing template class must implement IMailingTemplate' ); - } - - return $job; - } - - /** - * Reserve an empty Job record and sequence number. - * - * @param string $templateClass mailing template classname - * - * TODO: other job-wide parameters and generic storage - */ - static function create( $templateClass ) { - $jobId = db_insert( 'wmf_communication_job' ) - ->fields( array( - 'template_class' => $templateClass, - ) ) - ->execute(); - - watchdog( 'wmf_communication', - "Created a new job id :id, of type :template_class.", - array( - ':id' => $jobId, - ':template_class' => $templateClass, - ), - WATCHDOG_INFO - ); - return Job::getJob( $jobId ); - } - - /** - * Find all queued recipients and send letters. - */ - function run() { - watchdog( 'wmf_communication', - "Running mailing job ID :id...", - array( ':id' => $this->id ), - WATCHDOG_INFO - ); - - $mailer = Mailer::getDefault(); - $successful = 0; - $failed = 0; - - while ( $recipients = Recipient::getQueuedBatch( $this->id ) ) { - foreach ( $recipients as $recipient ) { - $bodyTemplate = $this->template->getBodyTemplate( $recipient ); - - $email = array( - 'from_name' => $this->template->getFromName(), - 'from_address' => $this->template->getFromAddress(), - 'reply_to' => $this->template->getFromAddress(), - 'to_name' => $recipient->getName(), - 'to_address' => $recipient->getEmail(), - 'subject' => $this->template->getSubject( $recipient ), - 'plaintext' => $bodyTemplate->render( 'txt' ), - 'html' => $bodyTemplate->render( 'html' ), - ); - - $success = $mailer->send( $email ); - - if ( $success ) { - $successful++; - $recipient->setSuccessful(); - } else { - $failed++; - $recipient->setFailed(); - } - } - } - - if ( ( $successful + $failed ) === 0 ) { - watchdog( 'wmf_communication', - "The mailing job (ID :id) was empty, or already completed.", - array( ':id' => $this->id ), - WATCHDOG_WARNING - ); - } else { - watchdog( 'wmf_communication', - "Completed mailing job (ID :id), :successful letters successfully sent, and :failed failed.", - array( - ':id' => $this->id, - ':successful' => $successful, - ':failed' => $failed, - ), - WATCHDOG_INFO - ); - } - } - - function getId() { - return $this->id; - } -} diff --git a/sites/all/modules/wmf_communication/MailingTemplate.php b/sites/all/modules/wmf_communication/MailingTemplate.php deleted file mode 100644 index 237f22f..0000000 --- a/sites/all/modules/wmf_communication/MailingTemplate.php +++ /dev/null @@ -1,102 +0,0 @@ -<?php namespace wmf_communication; - -/** - * Template provider, responsible for the subject and body templates - * - * Ordinarily, you can extend the AbstractMailingTemplate. - */ -interface IMailingTemplate { - /** - * @return string Subject header for the letter - */ - function getSubject( $recipient ); - - /** - * @return Templating template for generating the letter body - */ - function getBodyTemplate( $recipient ); -} - -/** - * Base template provider for normal mailing jobs - * - * Most mailings will extend this class and simply define the two abstract methods, - * which return a subject message key and the base template name. - * - * Anything which will be customized on a per-recipient basis should be controlled by this - * class (or in your subclass). - */ -abstract class AbstractMailingTemplate implements IMailingTemplate { - - /** - * Get the root directory to search for templates - * - * @return string path - */ - abstract function getTemplateDir(); - - /** - * Get the base template name - * - * This name is transformed into a template file path by the Templating factory. - * - * @return string base name, such as 'thank_you' - */ - abstract function getTemplateName(); - - /** - * Job is sent from this email address - * - * @return string email address - */ - function getFromAddress() { - return variable_get( 'thank_you_from_address', null ); - } - - /** - * Job is sent as this name - * - * @return string full name for From string - */ - function getFromName() { - return variable_get( 'thank_you_from_name', null ); - } - - /** - * Get the rendered subject line - * - * @param Recipient $recipient the addressee - * - * @return string subject - */ - function getSubject( $recipient ) { - return trim( $this->getBodyTemplate( $recipient )->render( 'subject' ) ); - } - - /** - * Get a template appropriate for this recipient - * - * Merges contact information into the template variables. - * - * @param Recipient $recipient the addressee - * - * @return Templating prepared template - */ - function getBodyTemplate( $recipient ) { - $templateParams = array( - 'name' => $recipient->getName(), - 'first_name' => $recipient->getFirstName(), - 'last_name' => $recipient->getLastName(), - 'email' => $recipient->getEmail(), - 'locale' => $recipient->getLanguage(), - ); - $templateParams = array_merge( $templateParams, $recipient->getVars() ); - - return new Templating( - $this->getTemplateDir(), - $this->getTemplateName(), - $recipient->getLanguage(), - $templateParams - ); - } -} diff --git a/sites/all/modules/wmf_communication/Recipient.php b/sites/all/modules/wmf_communication/Recipient.php deleted file mode 100644 index 704093c..0000000 --- a/sites/all/modules/wmf_communication/Recipient.php +++ /dev/null @@ -1,167 +0,0 @@ -<?php namespace wmf_communication; - -use \Exception; - -/** - * Link metadata between a mailing job and a CiviCRM contact - * - * This object contains all the information needed to generate and send a - * letter, including template parameters. It can be queried for the current - * delivery status. - */ -class Recipient { - protected $contactId; - protected $jobId; - protected $status; - - /** - * @var array additional parameters passed to the letter body template - */ - protected $vars = array(); - - /** - * Get recipients for this job, in the "queued" status, up to $batchSize. - * - * Call this repeatedly until empty set is returned. - * - * @param integer $jobId - * @param integer $batchSize maximum number to return - * @param integer $queuedState fetch recipients in the given state - * - * @return array of Recipient - */ - static function getQueuedBatch( $jobId, $batchSize = 100, $queuedState = 'queued' ) { - $result = db_select( 'wmf_communication_recipient' ) - ->fields( 'wmf_communication_recipient' ) - ->condition( 'job_id', $jobId ) - ->condition( 'status', $queuedState ) - ->orderBy( 'queued_id' ) - ->range( 0, $batchSize ) - ->execute(); - - $recipients = array(); - while ( $row = $result->fetchAssoc() ) { - $recipients[] = Recipient::loadFromRow( $row ); - } - return $recipients; - } - - /** - * Add a CiviCRM contact to a mailing job - * - * @param integer $jobId - * @param integer $contactId CiviCRM contact id - * @param array $vars serializable template parameters - */ - static function create( $jobId, $contactId, $vars ) { - watchdog( 'wmf_communication', - "Adding contact :contact_id to job :job_id, with parameters :vars", - array( - 'job_id' => $jobId, - 'contact_id' => $contactId, - 'vars' => json_encode( $vars, JSON_PRETTY_PRINT ), - ), - WATCHDOG_INFO - ); - db_insert( 'wmf_communication_recipient' ) - ->fields( array( - 'job_id' => $jobId, - 'contact_id' => $contactId, - 'status' => 'queued', - 'vars' => json_encode( $vars ), - ) ) - ->execute(); - } - - /** - * Parse database record into a Recipient object - * - * @param array $dbRow associative form of the db record for a single recipient - * - * @return Recipient - */ - static protected function loadFromRow( $dbRow ) { - $recipient = new Recipient(); - - $recipient->contactId = $dbRow['contact_id']; - $recipient->jobId = $dbRow['job_id']; - $recipient->status = $dbRow['status']; - - if ( $dbRow['vars'] ) { - $recipient->vars = json_decode( $dbRow['vars'], true ); - if ( $recipient->vars === null ) { - throw new Exception( 'Could not decode serialized vars, error code: ' . json_last_error() ); - } - } - - // FIXME: Get contact details en masse. - // TODO: Maybe we want to decouple from the civi db, and keep all necessary contact - // info in the recipient table. - $api = civicrm_api_classapi(); - $success = $api->Contact->get( array( - 'id' => $recipient->contactId, - 'return' => 'email,display_name,first_name,last_name,preferred_language', - 'version' => 3, - ) ); - if ( !$success ) { - throw new Exception( $api->errorMsg() ); - } - $values = $api->values(); - if ( $values ) { - $recipient->contact = array_pop( $values ); - } else { - throw new Exception( 'Tried to email a non-existent contact, ' . $recipient->contactId ); - } - - return $recipient; - } - - function getEmail() { - return $this->contact->email; - } - - function getName() { - return $this->contact->display_name; - } - - function getFirstName() { - return $this->contact->first_name; - } - - function getLastName() { - return $this->contact->last_name; - } - - function getLanguage() { - return Translation::normalize_language_code( $this->contact->preferred_language ); - } - - function getVars() { - return $this->vars; - } - - function setFailed() { - $this->setStatus( 'failed' ); - } - - function setSuccessful() { - $this->setStatus( 'successful' ); - } - - /** - * Usually, you will want to use a specific accessor like setFailed, above. - * - * If your job has custom recipient workflow states, set them using this method. - * - * @param string $status - */ - function setStatus( $status ) { - db_update( 'wmf_communication_recipient' ) - ->condition( 'contact_id', $this->contactId ) - ->condition( 'job_id', $this->jobId ) - ->fields( array( - 'status' => $status, - ) ) - ->execute(); - } -} diff --git a/sites/all/modules/wmf_communication/tests/Job.test b/sites/all/modules/wmf_communication/tests/Job.test deleted file mode 100644 index 685a102..0000000 --- a/sites/all/modules/wmf_communication/tests/Job.test +++ /dev/null @@ -1,87 +0,0 @@ -<?php - -use wmf_communication\Job; -use wmf_communication\Mailer; -use wmf_communication\Recipient; - -require_once 'TestThankyouTemplate.php'; - -class JobTest extends DrupalWebTestCase { - protected $profile = 'minimal'; - - public static function getInfo() { - return array( - 'name' => 'Mailing Job', - 'group' => 'Wikimedia', - 'description' => 'Create and run a mailing job', - ); - } - - public function setUp() { - parent::setUp( 'wmf_communication', 'wmf_common' ); - - // FIXME - variable_set( 'thank_you_from_address', 't...@localhost.net' ); - variable_set( 'thank_you_from_name', 'Testus' ); - - Mailer::$defaultSystem = 'drupal'; - - $contact = civicrm_api3('Contact', 'create', array( - 'contact_type' => 'Individual', - 'email' => 't...@example.com', - 'first_name' => 'Foo', - 'last_name' => 'Beer', - 'preferred_language' => 'it', - ) ); - if ($contact['is_error'] ) { - $this->fail($contact['error_message']); - } - $this->contactId = $contact['id']; - - $this->job = Job::create( 'TestThankyouTemplate' ); - - Recipient::create( - $this->job->getId(), - $this->contactId, - array( - 'amount' => 'EUR 22.11', - 'receive_date' => '1999-12-31T23:59:59+0000', - ) - ); - } - - public function testRun() { - $this->job->run(); - - $mails = $this->drupalGetMails(); - $this->assertEqual( count( $mails ), 1, - "One and only one message was sent." ); - - $expected = '[{ - "id":"wmf_communication_generic", - "to":"Foo Beer <t...@example.com>", - "subject":"Grazie dalla Wikimedia Foundation", - "body":"\nThis is a MIME-encoded message.\n--BOUNDARY\nContent-type: text\/plain;charset=utf-8\n\n\tCaro Foo Beer, \n\n\tGrazie per la tua donazione alla Wikimedia Foundation. \u00c8 stata\ndavvero apprezzata di cuore! \n\n\tPer le tue registrazioni: La tua donazione il\n1999-12-31T23:59:59+0000 \u00e8 stata \u20ac 22.11.\n\n\n--BOUNDARY\nContent-type: text\/html;charset=utf-8\n\n<p>Caro Foo Beer,<\/p>\n\n<p>Grazie per la tua donazione alla Wikimedia Foundation. \u00c8 stata davvero apprezzata di\ncuore!<\/p>\n\n<p>Per le tue registrazioni: La tua donazione il 1999-12-31T23:59:59+0000 \u00e8 stata\n\u20ac 22.11.<\/p>\n\n\n--BOUNDARY--", - "headers": { - "From":"Testus <t...@localhost.net>", - "Sender":"t...@localhost.net", - "Return-Path":"Testus <t...@localhost.net>", - "MIME-Version":"1.0", - "Content-Type":"multipart\/alternative;boundary=BOUNDARY" - } - }]'; - if ( preg_match( '/boundary=(.*)$/', $mails[0]['headers']['Content-Type'], $matches ) ) { - $boundary = $matches[1]; - $expected = str_replace( 'BOUNDARY', $boundary, $expected ); - } else { - $this->fail( "Could not parse multi-part email" ); - } - $expected = json_decode( $expected, true ); - $this->assertEqual( $mails, $expected, - "Email headers and content are correct" ); - } - - public function tearDown() { - parent::tearDown(); - } -} diff --git a/sites/all/modules/wmf_communication/tests/TestThankyouTemplate.php b/sites/all/modules/wmf_communication/tests/TestThankyouTemplate.php deleted file mode 100644 index fb3b693..0000000 --- a/sites/all/modules/wmf_communication/tests/TestThankyouTemplate.php +++ /dev/null @@ -1,13 +0,0 @@ -<?php - -use wmf_communication\AbstractMailingTemplate; - -class TestThankyouTemplate extends AbstractMailingTemplate { - function getTemplateName() { - return 'thank_you'; - } - - function getTemplateDir() { - return __DIR__ . "/templates"; - } -} diff --git a/sites/all/modules/wmf_communication/tests/templates/subject/thank_you.it.subject b/sites/all/modules/wmf_communication/tests/templates/subject/thank_you.it.subject deleted file mode 100644 index e0ae050..0000000 --- a/sites/all/modules/wmf_communication/tests/templates/subject/thank_you.it.subject +++ /dev/null @@ -1 +0,0 @@ -Grazie dalla Wikimedia Foundation diff --git a/sites/all/modules/wmf_communication/tests/wmf_communication_tests.info b/sites/all/modules/wmf_communication/tests/wmf_communication_tests.info deleted file mode 100644 index ba832e7..0000000 --- a/sites/all/modules/wmf_communication/tests/wmf_communication_tests.info +++ /dev/null @@ -1,6 +0,0 @@ -name = WMF Communication Test Cases -description = Simpletests -package = Wikimedia -core = 7.x -dependencies[] = wmf_communication -files[] = Job.test diff --git a/sites/all/modules/wmf_communication/tests/wmf_communication_tests.module b/sites/all/modules/wmf_communication/tests/wmf_communication_tests.module deleted file mode 100644 index b3d9bbc..0000000 --- a/sites/all/modules/wmf_communication/tests/wmf_communication_tests.module +++ /dev/null @@ -1 +0,0 @@ -<?php diff --git a/sites/all/modules/wmf_communication/wmf_communication.drush.inc b/sites/all/modules/wmf_communication/wmf_communication.drush.inc index 5b4f13d..ca453d1 100644 --- a/sites/all/modules/wmf_communication/wmf_communication.drush.inc +++ b/sites/all/modules/wmf_communication/wmf_communication.drush.inc @@ -3,13 +3,6 @@ function wmf_communication_drush_command() { $items = array( - 'wmf-send-letters' => array( - 'description' => 'Run a prepared mailing job', - 'arguments' => array( - 'job' => 'Job id', - ), - 'required-arguments' => true, - ), 'silverpop-import-mailings' => array( 'description' => 'Import sent mailings from Silverpop', 'options' => array( @@ -19,20 +12,6 @@ ); return $items; -} - -function wmf_communication_drush_help($section) -{ - switch ($section) { - case 'drush:wmf-send-letters': - return dt('Run a prepared mailing job.'); - } -} - -function drush_wmf_communication_wmf_send_letters() -{ - $options = drush_get_arguments(); - module_invoke('wmf_communication', 'send_letters', $options[1] ); } function drush_wmf_communication_silverpop_import_mailings() diff --git a/sites/all/modules/wmf_communication/wmf_communication.info b/sites/all/modules/wmf_communication/wmf_communication.info index 1d06663..ad41b03 100644 --- a/sites/all/modules/wmf_communication/wmf_communication.info +++ b/sites/all/modules/wmf_communication/wmf_communication.info @@ -5,11 +5,8 @@ configure = admin/config/wmf_communication dependencies[] = wmf_common dependencies[] = wmf_civicrm -files[] = Job.php files[] = Mailer.php -files[] = MailingTemplate.php files[] = MediaWikiMessages.php -files[] = Recipient.php files[] = Templating.php files[] = Translation.php files[] = twigext_l10n/CldrData.php diff --git a/sites/all/modules/wmf_communication/wmf_communication.install b/sites/all/modules/wmf_communication/wmf_communication.install deleted file mode 100644 index a4aefca..0000000 --- a/sites/all/modules/wmf_communication/wmf_communication.install +++ /dev/null @@ -1,74 +0,0 @@ -<?php - -function wmf_communication_schema() { - $schema['wmf_communication_job'] = array( - 'description' => 'Specification of mail job', - 'fields' => array( - 'id' => array( - 'type' => 'serial', - 'unsigned' => true, - 'not null' => true, - ), - 'template_class' => array( - 'description' => 'Template provider, instance of AbstractMailingClass', - 'type' => 'varchar', - 'length' => 128, - 'not null' => true, - ), - ), - 'primary key' => array('id'), - 'indexes' => array( - 'job_template' => array('template_class'), - ), - ); - - $schema['wmf_communication_recipient'] = array( - 'description' => 'Record linking contact and mail job', - 'fields' => array( - 'queued_id' => array( - 'type' => 'serial', - 'unsigned' => true, - 'not null' => true, - ), - 'contact_id' => array( - 'description' => 'Foreign key to civicrm.civicrm_contact', - 'type' => 'int', - 'unsigned' => true, - 'not null' => true, - ), - 'job_id' => array( - 'type' => 'int', - 'unsigned' => true, - 'not null' => true, - ), - 'status' => array( - 'type' => 'varchar', - 'length' => 32, - ), - 'vars' => array( - 'description' => 'Extra parameters to pass during template rendering, specific to this contact. Stored as JSON.', - 'type' => 'text', - ), - ), - 'primary key' => array('queued_id'), - 'indexes' => array( - 'recipient_status' => array('status'), - 'recipient_job' => array('job_id'), - ), - 'unique keys' => array( - 'recipient_contact_job' => array('contact_id', 'job_id'), - ), - 'foreign keys' => array( - 'recipient_job' => array( - 'table' => 'wmf_communication_job', - 'columns' => array('job_id' => 'id'), - ), - 'recipient_contact' => array( - 'table' => 'civicrm.civicrm_contact', - 'columns' => array('contact_id' => 'id'), - ), - ), - ); - - return $schema; -} diff --git a/sites/all/modules/wmf_communication/wmf_communication.module b/sites/all/modules/wmf_communication/wmf_communication.module index 9066755..4c3fdce 100644 --- a/sites/all/modules/wmf_communication/wmf_communication.module +++ b/sites/all/modules/wmf_communication/wmf_communication.module @@ -1,11 +1,6 @@ <?php use wmf_communication\CiviMailBulkStore; -use wmf_communication\Job; use wmf_communication\SilverpopImporter; - -function wmf_communication_send_letters( $jobId ) { - Job::getJob( $jobId )->run(); -} function wmf_communication_permission() { return array( -- To view, visit https://gerrit.wikimedia.org/r/373976 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Ie7a48b938ebae6f5f3330133c547e047686408ae Gerrit-PatchSet: 2 Gerrit-Project: wikimedia/fundraising/crm Gerrit-Branch: master Gerrit-Owner: Ejegg <ej...@ejegg.com> Gerrit-Reviewer: AndyRussG <andrew.green...@gmail.com> Gerrit-Reviewer: Cdentinger <cdentin...@wikimedia.org> Gerrit-Reviewer: Eileen <emcnaugh...@wikimedia.org> Gerrit-Reviewer: Katie Horn <kh...@wikimedia.org> Gerrit-Reviewer: Mepps <me...@wikimedia.org> Gerrit-Reviewer: XenoRyet <dkozlow...@wikimedia.org> Gerrit-Reviewer: jenkins-bot <> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits