Skip to content

Commit

Permalink
Merge pull request #14 from JohnFF/maintenance/eileen_updates
Browse files Browse the repository at this point in the history
Maintenance/eileen updates Massive refresh by Eileen. Contains a minor interface bug fix. Most work is around regenerating values, removing some boilerplate, standards compliance.
  • Loading branch information
JohnFF authored Feb 8, 2020
2 parents 43c358e + e023206 commit 3b6f525
Show file tree
Hide file tree
Showing 24 changed files with 944 additions and 499 deletions.
1 change: 0 additions & 1 deletion .gitignore

This file was deleted.

59 changes: 39 additions & 20 deletions CRM/Emailamender.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,20 @@

class CRM_Emailamender {

/**
* Singleton instance.
*
* @var \CRM_Emailamender
*/
private static $singleton;
private $_aTopLevelFilterSettings;
private $_aSecondLevelFilterSettings;
private $_aCompoundTopLevelDomains;
private $_iCorrectedEmailAddressActivityTypeId;

public function __construct() {
$this->_aTopLevelFilterSettings = CRM_Core_BAO_Setting::getItem('uk.org.futurefirst.networks.emailamender', 'emailamender.top_level_domain_corrections');
$this->_aSecondLevelFilterSettings = CRM_Core_BAO_Setting::getItem('uk.org.futurefirst.networks.emailamender', 'emailamender.second_level_domain_corrections');
$this->_aCompoundTopLevelDomains = CRM_Core_BAO_Setting::getItem('uk.org.futurefirst.networks.emailamender', 'emailamender.compound_top_level_domains');
$this->iCorrectedEmailAddressActivityTypeId = CRM_Core_BAO_Setting::getItem('uk.org.futurefirst.networks.emailamender', 'emailamender.email_amended_activity_type_id');
$this->_aTopLevelFilterSettings = (array) Civi::settings()->get('emailamender.top_level_domain_corrections');
$this->_aSecondLevelFilterSettings = (array) Civi::settings()->get('emailamender.second_level_domain_corrections');
$this->_aCompoundTopLevelDomains = (array) Civi::settings()->get('emailamender.compound_top_level_domains');
}

/**
Expand Down Expand Up @@ -78,10 +82,7 @@ private static function reassemble_email($aEmailPieces, $aDomainPartPieces) {
* @return bool
*/
public function is_autocorrect_enabled() {
if ('false' == CRM_Core_BAO_Setting::getItem('uk.org.futurefirst.networks.emailamender', 'emailamender.email_amender_enabled')) {
return FALSE;
}
return TRUE;
return Civi::settings()->get('emailamender.email_amender_enabled');
}

/**
Expand All @@ -90,20 +91,23 @@ public function is_autocorrect_enabled() {
* @param int $iEmailId
* @param int $iContactId
* @param string $sRawEmail
*
* @return bool correction took place
*
* @throws \CiviCRM_API3_Exception
*/
public function check_for_corrections($iEmailId, $iContactId, $sRawEmail) {
public function fixEmailAddress($iEmailId, $iContactId, $sRawEmail) {

// 1. Check that the email address has only one '@' - shouldn't need to do this but just in case.
if (substr_count($sRawEmail, "@") != 1) {
if (substr_count($sRawEmail, '@') !== 1) {
return FALSE;
}

// 2. Explode the string into the local part and the domain part.
self::parse_email_byref($sRawEmail, $aEmailPieces, $aDomainPartPieces);

// 3. Load the settings and initialise.
$iSecondLevelDomainFragmentIndex = self::get_second_domain_part_index($aEmailPieces[1]);
$iSecondLevelDomainFragmentIndex = $this->get_second_domain_part_index($aEmailPieces[1]);

// 4. Break it up and process it.
$bTopLevelChanged = self::perform_replacement($aDomainPartPieces[0], $this->_aTopLevelFilterSettings);
Expand All @@ -118,28 +122,30 @@ public function check_for_corrections($iEmailId, $iContactId, $sRawEmail) {
$sCleanedEmail = self::reassemble_email($aEmailPieces, $aDomainPartPieces);

// 7. Update the email address.
$updateParam = array(
'version' => 3,
$updateParam = [
'id' => $iEmailId,
'email' => $sCleanedEmail,
// Take it off hold, taken from CRM_Core_BAO_Email.
'on_hold' => FALSE,
'hold_date' => NULL,
'reset_date' => date('YmdHis'),
);

$updateEmailOutput = civicrm_api('Email', 'update', $updateParam);
];

if ($updateEmailOutput['is_error']) {
try {
civicrm_api3('Email', 'create', $updateParam);
// Recalculate display name.
civicrm_api3('Contact', 'create', ['id' => $iContactId]);
}
catch (CiviCRM_API3_Exception $e) {
CRM_Core_Session::setStatus(ts("Error when correcting email - contact ID $iContactId"), ts('Email Address Corrector'), 'error');
return FALSE;
throw $e;
}

// 8. Record the change by an activity.
$createActivityOutput = civicrm_api('Activity', 'create', array(
'version' => '3',
'sequential' => '1',
'activity_type_id' => $this->iCorrectedEmailAddressActivityTypeId,
'activity_type_id' => 'corrected_email_address',
'source_contact_id' => $iContactId,
'target_contact_id' => $iContactId,
'assignee_contact_id' => $iContactId,
Expand All @@ -155,4 +161,17 @@ public function check_for_corrections($iEmailId, $iContactId, $sRawEmail) {
return TRUE;
}

/**
* Get singleton instance.
*
* @return \CRM_Emailamender
*/
public static function singleton() {
if (self::$singleton) {
return self::$singleton;
}
self::$singleton = new CRM_Emailamender();
return self::$singleton;
}

}
2 changes: 1 addition & 1 deletion CRM/Emailamender/Equivalentmatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public static function processHook($email, $contactID, &$result) {
$aEmailParts = explode('@', $email);

// load settings and init
$aDomainEquivalents = CRM_Core_BAO_Setting::getItem('uk.org.futurefirst.networks.emailamender', 'emailamender.equivalent_domains');
$aDomainEquivalents = Civi::settings()->get('emailamender.equivalent_domains');

// Try equivalent e-mail domains, if there are any
$aEquivalentDomainsToTry = self::getEquivalentDomainsFor($aEmailParts[1], $aDomainEquivalents);
Expand Down
19 changes: 9 additions & 10 deletions CRM/Emailamender/Form/Task/Correctemailaddresses.php
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
<?php

require_once 'CRM/Core/Form.php';

/**
* Form controller class
*
* @see http://wiki.civicrm.org/confluence/display/CRMDOC43/QuickForm+Reference
*/
class CRM_Emailamender_Form_Task_Correctemailaddresses extends CRM_Contact_Form_Task {

public function buildQuickForm() {

$this->assign('contactIdCount', count($this->_contactIds));

$this->addButtons(array(
array(
$this->addButtons([
[
'type' => 'submit',
'name' => ts('Correct Email Addresses'),
'isDefault' => TRUE,
),
));
],
]);

// export form elements
$this->assign('elementNames', $this->getRenderableElementNames());
Expand All @@ -34,15 +33,15 @@ public function postProcess() {
foreach ($this->_contactIds as $eachContactId) {
$contactCount++;

$updateParam = array(
$updateParam = [
"version" => 3,
"contact_id" => $eachContactId,
);
];

$emailAddresses = civicrm_api('Email', 'get', $updateParam);

foreach ($emailAddresses['values'] as $eachEmailAddress) {
if ($emailAmender->check_for_corrections($eachEmailAddress['id'], $eachEmailAddress['contact_id'], $eachEmailAddress['email'])) {
if ($emailAmender->fixEmailAddress($eachEmailAddress['id'], $eachEmailAddress['contact_id'], $eachEmailAddress['email'])) {
$correctionCount++;
}
}
Expand All @@ -63,7 +62,7 @@ public function getRenderableElementNames() {
// auto-rendered in the loop -- such as "qfKey" and "buttons". These
// items don't have labels. We'll identify renderable by filtering on
// the 'label'.
$elementNames = array();
$elementNames = [];
foreach ($this->_elements as $element) {
/** @var HTML_QuickForm_Element $element */
$label = $element->getLabel();
Expand Down
15 changes: 7 additions & 8 deletions CRM/Emailamender/Page/EmailAmenderSettings.php
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
<?php

require_once 'CRM/Core/Page.php';

class CRM_Emailamender_Page_EmailAmenderSettings extends CRM_Core_Page {

function run() {
// Example: Set the page-title dynamically; alternatively, declare a static title in xml/Menu/*.xml
CRM_Utils_System::setTitle(ts('Email Amender Settings'));

$this->assign('email_amender_enabled', CRM_Core_BAO_Setting::getItem( 'uk.org.futurefirst.networks.emailamender', 'emailamender.email_amender_enabled'));
$this->assign('email_amender_enabled', Civi::settings()->get('emailamender.email_amender_enabled'));

$this->assign('top_level_filter_settings', Civi::settings()->get('emailamender.top_level_domain_corrections'));
$this->assign('second_level_filter_settings', Civi::settings()->get('emailamender.second_level_domain_corrections'));
$this->assign('compound_top_level_domains', Civi::settings()->get('emailamender.compound_top_level_domains'));

$this->assign('top_level_filter_settings', CRM_Core_BAO_Setting::getItem( 'uk.org.futurefirst.networks.emailamender', 'emailamender.top_level_domain_corrections'));
$this->assign('second_level_filter_settings', CRM_Core_BAO_Setting::getItem( 'uk.org.futurefirst.networks.emailamender', 'emailamender.second_level_domain_corrections'));
$this->assign('compound_top_level_domains', CRM_Core_BAO_Setting::getItem( 'uk.org.futurefirst.networks.emailamender', 'emailamender.compound_top_level_domains'));

$this->assign('equivalent_domain_settings', CRM_Core_BAO_Setting::getItem( 'uk.org.futurefirst.networks.emailamender', 'emailamender.equivalent_domains'));
$this->assign('equivalent_domain_settings', Civi::settings()->get('emailamender.equivalent_domains'));

parent::run();
}
Expand Down
6 changes: 3 additions & 3 deletions CRM/Emailamender/Upgrader.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public function upgrade_0001() {
$this->ctx->log->info('Applying update 0001');

// Check if the setting is already present
$aDomainEquivalents = CRM_Core_BAO_Setting::getItem('uk.org.futurefirst.networks.emailamender', 'uk.org.futurefirst.networks.emailamender.equivalent_domains');
$aDomainEquivalents = Civi::settings()->get('emailamender.equivalent_domains');
if ($aDomainEquivalents) {
return TRUE;
}
Expand All @@ -31,10 +31,10 @@ public function upgrade_0001() {
'gmail.co.uk' => 'GMail UK',
'googlemail.co.uk' => 'GMail UK',
);
CRM_Core_BAO_Setting::setItem($aDomainEquivalents, 'uk.org.futurefirst.networks.emailamender', 'uk.org.futurefirst.networks.emailamender.equivalent_domains');
Civi::settings()->set('equivalent_domains', $aDomainEquivalents);

// Check if the setting is now present (as setItem returns void)
$aDomainEquivalents = CRM_Core_BAO_Setting::getItem('uk.org.futurefirst.networks.emailamender', 'uk.org.futurefirst.networks.emailamender.equivalent_domains');
$aDomainEquivalents = Civi::settings()->get('equivalent_domains');
if ($aDomainEquivalents) {
return TRUE;
}
Expand Down
4 changes: 2 additions & 2 deletions CRM/Emailamender/Upgrader/Base.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ public function getRevisions() {
public function getCurrentRevision() {
// return CRM_Core_BAO_Extension::getSchemaVersion($this->extensionName);
$key = $this->extensionName . ':version';
return CRM_Core_BAO_Setting::getItem('Extension', $key);
return Civi::settings()->get($key);
}

public function setCurrentRevision($revision) {
Expand All @@ -231,7 +231,7 @@ public function setCurrentRevision($revision) {
// CRM_Core_BAO_Extension::setSchemaVersion($this->extensionName, $revision);

$key = $this->extensionName . ':version';
CRM_Core_BAO_Setting::setItem($revision, 'Extension', $key);
Civi::settings()->set($key, $revision);
return TRUE;
}

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Email-Amender
A CiviCRM extension that automatically corrects email addresses as they're added. Includes a handy interface to add new correction settings.
33 changes: 33 additions & 0 deletions api/v3/EmailAmender/BatchUpdate.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

/**
* EmailAmender.BatchUpdate API specification
* This is used for documentation and validation.
*
* @param array $spec description of fields supported by this API call
*
* @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
*/
function _civicrm_api3_email_amender_batch_update_spec(&$spec) {
}

/**
* EmailAmender.BatchUpdate API specification
*
* @param array $params
*
* @return array API result descriptor
* * @see civicrm_api3_create_success
*
* @throws API_Exception
*@throws \CiviCRM_API3_Exception
*
*/
function civicrm_api3_email_amender_batch_update($params) {
$candidates = civicrm_api3('EmailAmender', 'find_candidates', $params)['values'];
$result = [];
foreach ($candidates as $candidate) {
$result += civicrm_api3('EmailAmender', 'fix_email', $candidate)['values'];
}
return civicrm_api3_create_success($result, $params);
}
51 changes: 51 additions & 0 deletions api/v3/EmailAmender/FindCandidates.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

/**
* EmailAmender.find_candidatesAPI specification
* This is used for documentation and validation.
*
* @param array $spec description of fields supported by this API call
*
* @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
*/
function _civicrm_api3_email_amender_find_candidates_spec(&$spec) {

}

/**
* EmailAmender.find_candidatesAPI specification
*
* @param array $params
*
* @return array API result descriptor
*
* @throws \CiviCRM_API3_Exception
* @throws \API_Exception
*
* @see civicrm_api3_create_success
*/
function civicrm_api3_email_amender_find_candidates($params) {
$topLevel = Civi::settings()->get('emailamender.top_level_domain_corrections');
$secondLevel = Civi::settings()->get('emailamender.second_level_domain_corrections');

$options = _civicrm_api3_get_options_from_params($params);
$topLevelDomainList = CRM_Utils_Type::escape(implode('|', array_filter(array_keys($topLevel))), 'String');
$secondLevelDomainList = CRM_Utils_Type::escape(implode('|', array_filter(array_keys($secondLevel))), 'String');
// Can't use api due to lack of regex support.
// Also - I'm not hunting out subdomains at this stage - it's great that John handled
// edge cases like [email protected] but it feels like it can stay out of scope of this
// api at this stage.
$values = CRM_Core_DAO::executeQuery("
SELECT id, contact_id, email FROM civicrm_email
WHERE email REGEXP '\.({$topLevelDomainList})$'
OR email REGEXP '@({$secondLevelDomainList})\\\.'
LIMIT " . $options['limit']
);
$return = [];
while ($values->fetch()) {
$return[$values->id] = ['email' => $values->email, 'id' => $values->id, 'contact_id' => $values->contact_id];
}

return civicrm_api3_create_success($return);
}

34 changes: 34 additions & 0 deletions api/v3/EmailAmender/FixEmail.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

/**
* EmailAmender.fix_emailAPI specification
* This is used for documentation and validation.
*
* @param array $spec description of fields supported by this API call
*
* @see http://wiki.civicrm.org/confluence/display/CRM/API+Architecture+Standards
*/
function _civicrm_api3_email_amender_fix_email_spec(&$spec) {

}

/**
* EmailAmender.fix_emailAPI specification
*
* @param array $params
*
* @return array API result descriptor
*
* @throws \CiviCRM_API3_Exception
*
* @see civicrm_api3_create_success
*/
function civicrm_api3_email_amender_fix_email($params) {
$emailAmender = CRM_Emailamender::singleton();
$return = [];
if ($emailAmender->fixEmailAddress($params['id'], $params['contact_id'], $params['email'])) {
$return[$params['id']] = ['id' => $params['id'], 'contact_id' => $params['contact_id']];
}

return civicrm_api3_create_success($return);
}
Loading

0 comments on commit 3b6f525

Please sign in to comment.