Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug/mailchip ajax cleanup #5267

Merged
merged 33 commits into from
Jun 16, 2020
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
f3df571
added new mailchimp endpoint
DawoudIO Jun 9, 2020
8ca99a6
moved mailchimp to a new tab with ajax loading
DawoudIO Jun 9, 2020
5b6efeb
using member loop up api for more details about the email
DawoudIO Jun 9, 2020
cd54417
Merge branch 'master' into bug/mailchip-ajax-cleanup
DawoudIO Jun 9, 2020
f8244a9
added MailChimp PostMail get APIs
DawoudIO Jun 9, 2020
1ebbe6d
added mailchimp ajax calls
DawoudIO Jun 9, 2020
b62d447
locale support + loading message
DawoudIO Jun 9, 2020
a2e8fba
re-added commented display mailchimp status
DawoudIO Jun 9, 2020
2e8a6f8
display Not Subscribed for mailchimp if no data is found
DawoudIO Jun 9, 2020
405c3c2
Merge branch 'bug/mailchip-ajax-cleanup' of https://github.com/Church…
DawoudIO Jun 9, 2020
f017455
fixed bug in getting mailing list members by using list max size
DawoudIO Jun 9, 2020
62d65d1
cleaner / faster member list retieve
DawoudIO Jun 9, 2020
48162e9
Created New MailChimp APIs for get missing and unsubscribed members
DawoudIO Jun 9, 2020
64c61b4
using MailChimpMiddleware
DawoudIO Jun 9, 2020
a554f6f
checking is trully active on every API
DawoudIO Jun 9, 2020
9fa6bcc
cashing isActive status
DawoudIO Jun 9, 2020
9f96f3b
All 4 MailChimp APIs are now part of the new path
DawoudIO Jun 9, 2020
83b51ad
matching new API path
DawoudIO Jun 9, 2020
ea1b24c
updated with new MailChimp APIs
DawoudIO Jun 9, 2020
541b6e9
added list/ to the list APIs
DawoudIO Jun 9, 2020
50dcc5d
Merge branch 'master' into bug/mailchip-ajax-cleanup
DawoudIO Jun 15, 2020
6922833
removed old getEmailsNotInMailChimp page
DawoudIO Jun 15, 2020
d3da5e6
removed old missing from mailchimp page
DawoudIO Jun 15, 2020
86766d0
check list Id is valid before doing work
DawoudIO Jun 15, 2020
f99f832
added mailchimp list delta pages
DawoudIO Jun 15, 2020
07e0ff8
updated json return object
DawoudIO Jun 15, 2020
8f29a88
return 1st and last names
DawoudIO Jun 15, 2020
c58233a
added list delta links
DawoudIO Jun 15, 2020
34459cd
return status of the members in the list (all should be active)
DawoudIO Jun 15, 2020
a634767
added status, all should be active
DawoudIO Jun 15, 2020
49a1fbe
refactor for common code for searching emails
DawoudIO Jun 15, 2020
243db13
updated mailchimp collection
DawoudIO Jun 15, 2020
3272963
Merge branch 'master' into bug/mailchip-ajax-cleanup
DawoudIO Jun 16, 2020
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
584 changes: 583 additions & 1 deletion postman/Collections/Private API.postman_collection.json

Large diffs are not rendered by default.

132 changes: 65 additions & 67 deletions src/ChurchCRM/Service/MailChimpService.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,103 +6,101 @@
use \DrewM\MailChimp\MailChimp;
use ChurchCRM\Utils\LoggerUtils;
use ChurchCRM\Utils\ExecutionTime;

class ListEmailFilter {
private $email;

function __construct($emailAddress)
{
$this->email = $emailAddress;
}
public function isEmailInList($list) {
foreach ($list['members'] as $listMember) {
if (strcmp(strtolower($listMember['email_address']), strtolower($this->email)) == 0) {
return true;
}
}
return false;
}
}
use PHPMailer\PHPMailer\Exception;

class MailChimpService
{
private $hasKey = false;
private $isActive = false;
private $myMailchimp;
private $lists;

public function __construct()
{
if (!empty(SystemConfig::getValue('sMailChimpApiKey'))) {
$this->isActive = true;
$this->hasKey = true;
$this->myMailchimp = new MailChimp(SystemConfig::getValue('sMailChimpApiKey'));
}
}

public function isActive()
{
return $this->isActive;
if ($this->isActive) {
return true;
}
if ($this->hasKey) {
$rootAPI = $this->myMailchimp->get("");
Copy link
Contributor Author

Choose a reason for hiding this comment

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

ensure we have an active mailchimp with subscribers in it

if ( $rootAPI["total_subscribers"] > 0 ) {
$this->isActive = true;
return true;
}
}
return false;
}
private function getListsFromCache(){
if (!isset($_SESSION['MailChimpLists'])){
LoggerUtils::getAppLogger()->debug("Updating MailChimp List Cache");
$time = new ExecutionTime;
$lists = $this->myMailchimp->get("lists")['lists'];
LoggerUtils::getAppLogger()->debug("MailChimp list enumeration took: ". $time->getMiliseconds(). " ms. Found ".count($lists)." lists");
foreach($lists as &$list) {
$listmembers = $this->myMailchimp->get('lists/'.$list['id'].'/members',['count' => 100000]);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The number of records to return. Default value is 10. Maximum value is 1000

This was the issue as 100000 was kicking back 0 subs

$list['members'] = $listmembers['members'];

private function getListsFromCache()
{
if (!isset($_SESSION['MailChimpLists'])) {
LoggerUtils::getAppLogger()->debug("Updating MailChimp List Cache");
$time = new ExecutionTime;
$lists = $this->myMailchimp->get("lists")['lists'];
LoggerUtils::getAppLogger()->debug("MailChimp list enumeration took: " . $time->getMiliseconds() . " ms. Found " . count($lists) . " lists");
foreach ($lists as &$list) {
$list['members'] = [];
$listmembers = $this->myMailchimp->get('lists/' . $list['id'] . '/members',
[
Copy link
Contributor Author

Choose a reason for hiding this comment

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

extra filters

'count' => $list['stats']["member_count"],
"fields" => "members.email_address",
"status" => "subscribed"
]);
foreach ($listmembers['members'] as $member) {
array_push($list['members'], strtolower($member["email_address"]));
}
LoggerUtils::getAppLogger()->debug("MailChimp list ". $list['id'] . " membership ". count($list['members']));

}
LoggerUtils::getAppLogger()->debug("MailChimp list and membership update took: " . $time->getMiliseconds() . " ms");
$_SESSION['MailChimpLists'] = $lists;
} else {
LoggerUtils::getAppLogger()->debug("Using cached MailChimp List");
}
LoggerUtils::getAppLogger()->debug("MailChimp list and membership update took: ". $time->getMiliseconds(). " ms");
$_SESSION['MailChimpLists'] = $lists;
}
else{
LoggerUtils::getAppLogger()->debug("Using cached MailChimp List");
}
return $_SESSION['MailChimpLists'];
return $_SESSION['MailChimpLists'];
}

public function isEmailInMailChimp($email)
{
if (!$this->isActive) {
return 'Mailchimp is not active';
if (empty($email)) {
return new Exception(gettext('No email passed in'));
}
if ($email == '') {
return 'No email';

if (!$this->isActive()) {
return new Exception(gettext('Mailchimp is not active'));
}

try {
$lists = $this->getListsFromCache();
$lists = array_filter($lists, array(new ListEmailFilter($email),'isEmailInList'));
$listNames = array_map(function ($list) { return $list['name']; }, $lists);
$listMemberships = implode(', ', $listNames);
LoggerUtils::getAppLogger()->debug($email. "is a member of ".$listMemberships);

return $listMemberships;
} catch (\Mailchimp_Invalid_ApiKey $e) {
return 'Invalid ApiKey';
} catch (\Mailchimp_List_NotSubscribed $e) {
return '';
} catch (\Mailchimp_Email_NotExists $e) {
return '';
} catch (\Exception $e) {
return $e;
$lists = $this->getListsFromCache();
$listsStatus = [];
foreach ($lists as $list) {
$data = $this->myMailchimp->get("lists/" . $list["id"] . "/members/" . md5($email));
LoggerUtils::getAppLogger()->debug($email . " is " . $data["status"] . " to " . $list["name"]);
array_push($listsStatus, ["name" => $list["name"], "status" => $data["status"], "stats" => $data["stats"]]);
}
return $listsStatus;
}

public function getLists()
{
if (!$this->isActive) {
return 'Mailchimp is not active';
if (!$this->isActive()) {
return new Exception(gettext('Mailchimp is not active'));
}
try {
$result = $this->getListsFromCache();

return $result;
} catch (\Mailchimp_Invalid_ApiKey $e) {
return 'Invalid ApiKey';
} catch (\Exception $e) {
return $e->getMessage();
return $this->getListsFromCache();
}

public function getListMembers($listId) {
$mailchimpLists = $this->getLists();
foreach ($mailchimpLists as $mailchimpList) {
if ($listId == $mailchimpList["id"]) {
LoggerUtils::getAppLogger()->debug("MailChimp list ". $listId . " has ". count($mailchimpList["members"]) . " members");
return $mailchimpList["members"];
}
}
}
}
22 changes: 22 additions & 0 deletions src/ChurchCRM/Slim/Middleware/MailChimpMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace ChurchCRM\Slim\Middleware;

use Slim\Http\Request;
use Slim\Http\Response;
use ChurchCRM\Service\MailChimpService;

class MailChimpMiddleware {

public function __invoke( Request $request, Response $response, callable $next )
{
$mailchimpService = new MailChimpService();

if (! $mailchimpService->isActive()) {
return $response->withStatus(412)->withJson(["message" => gettext('Mailchimp is not active')]);
}
$request = $request->withAttribute("mailchimpService", $mailchimpService);
return $next( $request, $response );
}

}
32 changes: 24 additions & 8 deletions src/PersonView.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,11 +306,7 @@ class="initials-image profile-user-img img-responsive img-rounded profile-user-i
if ($sEmail != '') {
?>
<li><i class="fa-li fa fa-envelope"></i><?= gettext('Email') ?>: <span><a href="mailto:<?= $sUnformattedEmail ?>"><?= $sEmail ?></a></span></li>
<?php if ($mailchimp->isActive()) {
?>
<li><i class="fa-li fa fa-send"></i>MailChimp: <span><?= $mailchimp->isEmailInMailChimp($sEmail); ?></span></li>
<?php
}
}
if ($sWorkPhone) {
?>
Expand All @@ -320,11 +316,7 @@ class="initials-image profile-user-img img-responsive img-rounded profile-user-i
<?php if ($per_WorkEmail != '') {
?>
<li><i class="fa-li fa fa-envelope"></i><?= gettext('Work/Other Email') ?>: <span><a href="mailto:<?= $per_WorkEmail ?>"><?= $per_WorkEmail ?></a></span></li>
<?php if ($mailchimp->isActive()) {
?>
<li><i class="fa-li fa fa-send"></i>MailChimp: <span><?= $mailchimp->isEmailInMailChimp($per_WorkEmail); ?></span></li>
<?php
}
}

if ($per_FacebookID > 0) {
Expand Down Expand Up @@ -428,6 +420,9 @@ class="initials-image profile-user-img img-responsive img-rounded profile-user-i
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active"><a href="#timeline" aria-controls="timeline" role="tab" data-toggle="tab"><?= gettext('Timeline') ?></a></li>
<li role="presentation"><a href="#family" aria-controls="family" role="tab" data-toggle="tab"><?= gettext('Family') ?></a></li>
<?php if ($mailchimp->isActive()) { ?>
<li role="presentation"><a href="#mailchimp" aria-controls="mailchimp" role="tab" data-toggle="tab" id="mailchimptab"><?= gettext('Mailchimp') ?></a></li>
<?php } ?>
<li role="presentation"><a href="#groups" aria-controls="groups" role="tab" data-toggle="tab"><?= gettext('Assigned Groups') ?></a></li>
<li role="presentation"><a href="#properties" aria-controls="properties" role="tab" data-toggle="tab"><?= gettext('Assigned Properties') ?></a></li>
<li role="presentation"><a href="#volunteer" aria-controls="volunteer" role="tab" data-toggle="tab"><?= gettext('Volunteer Opportunities') ?></a></li>
Expand Down Expand Up @@ -578,6 +573,27 @@ class="initials-image profile-user-img img-responsive img-rounded profile-user-i
<?php
} ?>
</div>
<div role="tab-pane fade" class="tab-pane" id="mailchimp">
<table class="table">
<tr>
<th><?= gettext("Type")?></th>
<th><?= gettext("Email")?></th>
<th><?= gettext("Lists")?></th>
</tr>
<tr>
<td>Home</td>
<td><?= $person->getEmail() ?></td>
<td id="<?= md5($person->getEmail())?>"> ... <?= gettext("loading")?> ... </td>
</tr>
<?php if (!empty($person->getWorkEmail())) { ?>
<tr>
<td>Work</td>
<td><?= $person->getWorkEmail() ?></td>
<td id="<?=md5($person->getWorkEmail())?>"> ... <?= gettext("loading")?> ... </td>
</tr>
<?php } ?>
</table>
</div>
<div role="tab-pane fade" class="tab-pane" id="groups">
<div class="main-box clearfix">
<div class="main-box-body clearfix">
Expand Down
1 change: 1 addition & 0 deletions src/api/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
require __DIR__ . '/routes/background.php';
require __DIR__ . '/routes/geocoder.php';
require __DIR__ . '/routes/kiosks.php';
require __DIR__ . '/routes/email/mailchimp.php';
require __DIR__ . '/routes/search.php';
require __DIR__ . '/routes/users/users-admin.php';
require __DIR__ . '/routes/users/user-current.php';
Expand Down
118 changes: 118 additions & 0 deletions src/api/routes/email/mailchimp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
<?php

use ChurchCRM\PersonQuery;
use ChurchCRM\Utils\LoggerUtils;
use ChurchCRM\Slim\Middleware\MailChimpMiddleware;
use ChurchCRM\Slim\Middleware\Request\PersonAPIMiddleware;
use ChurchCRM\Slim\Middleware\Request\FamilyAPIMiddleware;
use Propel\Runtime\ActiveQuery\Criteria;
use Slim\Http\Request;
use Slim\Http\Response;

$app->group('/mailchimp/', function () {
$this->get('{id}/missing', 'getMailchimpEmailNotInCRM');
$this->get('{id}/not-subscribed', 'getMailChimpMissingSubscribed');
$this->get('person/{personId}', 'getPersonStatus')->add(new PersonAPIMiddleware());
$this->get('family/{familyId}', 'getFamilyStatus')->add(new FamilyAPIMiddleware());
})->add(new MailChimpMiddleware());

function getMailchimpEmailNotInCRM(Request $request, Response $response, array $args) {

$listId = $args['id'];

$mailchimpService = $request->getAttribute("mailchimpService");
$mailchimpListMembers = $mailchimpService->getListMembers($listId);

$People = PersonQuery::create()
->filterByEmail(null, Criteria::NOT_EQUAL)
->_or()
->filterByWorkEmail(null, Criteria::NOT_EQUAL)
->find();


foreach($People as $Person)
{
$key = array_search(strtolower($Person->getEmail()), $mailchimpListMembers);
if ($key > 0) {
LoggerUtils::getAppLogger()->debug("found " . $Person->getEmail());
array_splice($mailchimpListMembers, $key, 1);
}
$key = array_search($Person->getWorkEmail(), $mailchimpListMembers);
if ($key > 0) {
array_splice($mailchimpListMembers, $key, 1);
}
}
LoggerUtils::getAppLogger()->debug("MailChimp list ". $listId . " now has ". count($mailchimpListMembers) . " members");

return $response->withJson($mailchimpListMembers);
}

function getMailChimpMissingSubscribed(Request $request, Response $response, array $args) {
$listId = $args['id'];

$mailchimpService = $request->getAttribute("mailchimpService");
$mailchimpListMembers = $mailchimpService->getListMembers($listId);

$People = PersonQuery::create()
->filterByEmail(null, Criteria::NOT_EQUAL)
->_or()
->filterByWorkEmail(null, Criteria::NOT_EQUAL)
->find();

$personsNotInMailchimp = [];
foreach($People as $Person)
{
$found = false;
$key = array_search(strtolower($Person->getEmail()), $mailchimpListMembers);
if ($key > 0 ) {
$found= true;
}
$key = array_search($Person->getWorkEmail(), $mailchimpListMembers);
if ($key > 0) {
$found= true;
}

if (!$found) {
$emails = [];
if (!empty($Person->getEmail())) {
array_push($emails, $Person->getEmail());
}
if (!empty($Person->getWorkEmail())) {
array_push($emails, $Person->getWorkEmail());
}
array_push($personsNotInMailchimp, ["id" => $Person->getId(),
"name" => $Person->getFullName(),
"emails" => $emails
]);
}
}
LoggerUtils::getAppLogger()->debug("MailChimp list ". $listId . " now has ". count($mailchimpListMembers) . " members");

return $response->withJson($personsNotInMailchimp);
}

function getFamilyStatus(Request $request, Response $response, array $args) {
$family = $request->getAttribute("family");
$mailchimpService = $request->getAttribute("mailchimpService");
$emailToLists = [];
if (!empty($family->getEmail())) {
array_push($emailToLists, ["email" => $family->getEmail(), "emailMD5" => md5($family->getEmail()),
"list" => $mailchimpService->isEmailInMailChimp($family->getEmail())]);
}
return $response->withJson($emailToLists);
}

function getPersonStatus(Request $request, Response $response, array $args) {
$person = $request->getAttribute("person");
$mailchimpService = $request->getAttribute("mailchimpService");
$emailToLists = [];
if (!empty($person->getEmail())) {
array_push($emailToLists, ["email" => $person->getEmail(), "emailMD5" => md5($person->getEmail()),
"list" => $mailchimpService->isEmailInMailChimp($person->getEmail())]);
}
if (!empty($person->getWorkEmail())) {
array_push($emailToLists, ["email" => $person->getWorkEmail(), "emailMD5" => md5($person->getWorkEmail()),
"list" => $mailchimpService->isEmailInMailChimp($person->getWorkEmail())]);
}
return $response->withJson($emailToLists);
}
Loading