- Moves ImportExport under Subscribers namespace
- Updates tests
This commit is contained in:
135
lib/Subscribers/ImportExport/BootstrapMenu.php
Normal file
135
lib/Subscribers/ImportExport/BootstrapMenu.php
Normal file
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
namespace MailPoet\Subscribers\ImportExport;
|
||||
|
||||
use MailPoet\Models\CustomField;
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
class BootStrapMenu {
|
||||
function __construct($action = null) {
|
||||
$this->action = $action;
|
||||
}
|
||||
|
||||
function getSegments($withConfirmedSubscribers = false) {
|
||||
$segments = ($this->action === 'import') ?
|
||||
Segment::getSegmentsForImport() :
|
||||
Segment::getSegmentsForExport($withConfirmedSubscribers);
|
||||
return array_map(function ($segment) {
|
||||
return array(
|
||||
'id' => $segment['id'],
|
||||
'name' => $segment['name'],
|
||||
'subscriberCount' => $segment['subscribers']
|
||||
);
|
||||
}, $segments);
|
||||
}
|
||||
|
||||
function getSubscriberFields() {
|
||||
return array(
|
||||
'email' => __('Email'),
|
||||
'first_name' => __('First name'),
|
||||
'last_name' => __('Last name'),
|
||||
'status' => __('Status')
|
||||
/*
|
||||
'confirmed_ip' => __('IP address')
|
||||
'confirmed_at' => __('Subscription date')
|
||||
*/
|
||||
);
|
||||
}
|
||||
|
||||
function formatSubscriberFields($subscriberFields) {
|
||||
return array_map(function ($fieldId, $fieldName) {
|
||||
return array(
|
||||
'id' => $fieldId,
|
||||
'name' => $fieldName,
|
||||
'type' => ($fieldId === 'confirmed_at') ? 'date' : null,
|
||||
'custom' => false
|
||||
);
|
||||
}, array_keys($subscriberFields), $subscriberFields);
|
||||
}
|
||||
|
||||
function getSubscriberCustomFields() {
|
||||
return CustomField::findArray();
|
||||
}
|
||||
|
||||
function formatSubscriberCustomFields($subscriberCustomFields) {
|
||||
return array_map(function ($field) {
|
||||
return array(
|
||||
'id' => $field['id'],
|
||||
'name' => $field['name'],
|
||||
'type' => $field['type'],
|
||||
'custom' => true
|
||||
);
|
||||
}, $subscriberCustomFields);
|
||||
}
|
||||
|
||||
function formatFieldsForSelect2(
|
||||
$subscriberFields,
|
||||
$subscriberCustomFields) {
|
||||
$actions = ($this->action === 'import') ?
|
||||
array(
|
||||
array(
|
||||
'id' => 'ignore',
|
||||
'name' => __('Ignore column...'),
|
||||
),
|
||||
array(
|
||||
'id' => 'create',
|
||||
'name' => __('Create new column...')
|
||||
),
|
||||
) :
|
||||
array(
|
||||
array(
|
||||
'id' => 'select',
|
||||
'name' => __('Select all...'),
|
||||
),
|
||||
array(
|
||||
'id' => 'deselect',
|
||||
'name' => __('Deselect all...')
|
||||
),
|
||||
);
|
||||
$select2Fields = array(
|
||||
array(
|
||||
'name' => __('Actions'),
|
||||
'children' => $actions
|
||||
),
|
||||
array(
|
||||
'name' => __('System columns'),
|
||||
'children' => $this->formatSubscriberFields($subscriberFields)
|
||||
)
|
||||
);
|
||||
if($subscriberCustomFields) {
|
||||
array_push($select2Fields, array(
|
||||
'name' => __('User columns'),
|
||||
'children' => $this->formatSubscriberCustomFields(
|
||||
$subscriberCustomFields
|
||||
)
|
||||
));
|
||||
}
|
||||
return $select2Fields;
|
||||
}
|
||||
|
||||
function bootstrap() {
|
||||
$subscriberFields = $this->getSubscriberFields();
|
||||
$subscriberCustomFields = $this->getSubscriberCustomFields();
|
||||
$data['segments'] = json_encode($this->getSegments());
|
||||
$data['subscriberFieldsSelect2'] = json_encode(
|
||||
$this->formatFieldsForSelect2(
|
||||
$subscriberFields,
|
||||
$subscriberCustomFields
|
||||
)
|
||||
);
|
||||
if($this->action === 'import') {
|
||||
$data['subscriberFields'] = json_encode(
|
||||
array_merge(
|
||||
$this->formatSubscriberFields($subscriberFields),
|
||||
$this->formatSubscriberCustomFields($subscriberCustomFields)
|
||||
)
|
||||
);
|
||||
$data['maxPostSizeBytes'] = Helpers::getMaxPostSize('bytes');
|
||||
$data['maxPostSize'] = Helpers::getMaxPostSize();
|
||||
} else {
|
||||
$data['segmentsWithConfirmedSubscribers'] =
|
||||
json_encode($this->getSegments($withConfirmedSubscribers = true));
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
}
|
128
lib/Subscribers/ImportExport/Export/Export.php
Normal file
128
lib/Subscribers/ImportExport/Export/Export.php
Normal file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
namespace MailPoet\Subscribers\ImportExport\Export;
|
||||
|
||||
use MailPoet\Config\Env;
|
||||
use MailPoet\Subscribers\ImportExport\BootStrapMenu;
|
||||
use MailPoet\Models\Segment;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Models\SubscriberSegment;
|
||||
use MailPoet\Util\XLSXWriter;
|
||||
|
||||
class Export {
|
||||
public function __construct($data) {
|
||||
$this->exportConfirmedOption = $data['exportConfirmedOption'];
|
||||
$this->exportFormatOption = $data['exportFormatOption'];
|
||||
$this->groupBySegmentOption = $data['groupBySegmentOption'];
|
||||
$this->segments = $data['segments'];
|
||||
$this->subscribersWithoutSegment = array_search(0, $this->segments);
|
||||
$this->subscriberFields = $data['subscriberFields'];
|
||||
$this->profilerStart = microtime(true);
|
||||
$this->exportFile = sprintf(
|
||||
Env::$temp_path . '/mailpoet_export_%s.%s',
|
||||
substr(md5(time()), 0, 4),
|
||||
$this->exportFormatOption
|
||||
);
|
||||
$this->exportFileURL = sprintf(
|
||||
'%s/%s/%s/%s',
|
||||
plugins_url(),
|
||||
Env::$plugin_name,
|
||||
Env::$temp_name,
|
||||
basename($this->exportFile)
|
||||
);
|
||||
}
|
||||
|
||||
function process() {
|
||||
$subscribers = SubscriberSegment::
|
||||
left_outer_join(
|
||||
Subscriber::$_table,
|
||||
array(
|
||||
Subscriber::$_table . '.id',
|
||||
'=',
|
||||
SubscriberSegment::$_table . '.subscriber_id'
|
||||
))
|
||||
->left_outer_join(
|
||||
Segment::$_table,
|
||||
array(
|
||||
Segment::$_table . '.id',
|
||||
'=',
|
||||
SubscriberSegment::$_table . '.segment_id'
|
||||
))
|
||||
->select(Segment::$_table . '.name', 'segment_name')
|
||||
->orderByAsc('segment_name')
|
||||
->filter('filterWithCustomFields')
|
||||
->whereIn(SubscriberSegment::$_table . '.segment_id', $this->segments);
|
||||
if(!$this->groupBySegmentOption) $subscribers = $subscribers->groupBy(Subscriber::$_table . '.id');
|
||||
if($this->exportConfirmedOption) $subscribers = $subscribers->where(Subscriber::$_table . '.status', 'confirmed');
|
||||
$subscribers = $subscribers->findArray();
|
||||
$formattedSubscriberFields = $this->formatSubscriberFields($this->subscriberFields);
|
||||
try {
|
||||
if($this->exportFormatOption === 'csv') {
|
||||
$CSVFile = fopen($this->exportFile, 'w');
|
||||
$formatCSV = function ($row) {
|
||||
return '"' . str_replace('"', '\"', $row) . '"';
|
||||
};
|
||||
// add UTF-8 BOM (3 bytes, hex EF BB BF) at the start of the file for Excel to automatically recognize the encoding
|
||||
fwrite($CSVFile, chr(0xEF) . chr(0xBB) . chr(0xBF));
|
||||
if($this->groupBySegmentOption) $formattedSubscriberFields[] = __('List');
|
||||
fwrite($CSVFile, implode(",", array_map($formatCSV, $formattedSubscriberFields)) . "\n");
|
||||
foreach ($subscribers as $subscriber) {
|
||||
$row = array_map(function ($field) use ($subscriber) {
|
||||
return $subscriber[$field];
|
||||
}, $this->subscriberFields);
|
||||
if($this->groupBySegmentOption) $row[] = $subscriber['segment_name'];
|
||||
fwrite($CSVFile, implode(",", array_map($formatCSV, $row)) . "\n");
|
||||
}
|
||||
fclose($CSVFile);
|
||||
} else {
|
||||
$writer = new XLSXWriter();
|
||||
$writer->setAuthor('MailPoet (www.mailpoet.com)');
|
||||
$headerRow = array($formattedSubscriberFields);
|
||||
$segment = null;
|
||||
$rows = array();
|
||||
foreach ($subscribers as $subscriber) {
|
||||
if($segment && $segment != $subscriber['segment_name'] && $this->groupBySegmentOption) {
|
||||
$writer->writeSheet(array_merge($headerRow, $rows), ucwords($segment));
|
||||
$rows = array();
|
||||
}
|
||||
// detect RTL language and set Excel to properly display the sheet
|
||||
if(!$writer->rtl && preg_grep('/\p{Arabic}|\p{Hebrew}/u', $subscriber)) {
|
||||
$writer->rtl = true;
|
||||
}
|
||||
$rows[] = array_map(function ($field) use ($subscriber) {
|
||||
return $subscriber[$field];
|
||||
}, $this->subscriberFields);
|
||||
$segment = $subscriber['segment_name'];
|
||||
}
|
||||
$writer->writeSheet(array_merge($headerRow, $rows), 'MailPoet');
|
||||
$writer->writeToFile($this->exportFile);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return array(
|
||||
'result' => false,
|
||||
'error' => $e->getMessage()
|
||||
);
|
||||
}
|
||||
return array(
|
||||
'result' => true,
|
||||
'data' => array(
|
||||
'totalExported' => count($subscribers),
|
||||
'exportFileURL' => $this->exportFileURL
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function formatSubscriberFields($subscriberFields) {
|
||||
$bootStrapMenu = new BootStrapMenu();
|
||||
$translatedFields = $bootStrapMenu->getSubscriberFields();
|
||||
return array_map(function ($field) use ($translatedFields) {
|
||||
return (isset($translatedFields[$field])) ?
|
||||
ucfirst($translatedFields[$field]) :
|
||||
ucfirst($field);
|
||||
}, $subscriberFields);
|
||||
}
|
||||
|
||||
function timeExecution() {
|
||||
$profilerEnd = microtime(true);
|
||||
return ($profilerEnd - $this->profilerStart) / 60;
|
||||
}
|
||||
}
|
296
lib/Subscribers/ImportExport/Import/Import.php
Normal file
296
lib/Subscribers/ImportExport/Import/Import.php
Normal file
@@ -0,0 +1,296 @@
|
||||
<?php
|
||||
namespace MailPoet\Subscribers\ImportExport\Import;
|
||||
|
||||
use MailPoet\Subscribers\ImportExport\BootStrapMenu;
|
||||
use MailPoet\Models\Subscriber;
|
||||
use MailPoet\Models\SubscriberCustomField;
|
||||
use MailPoet\Models\SubscriberSegment;
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
class Import {
|
||||
public function __construct($data) {
|
||||
$this->subscribersData = $data['subscribers'];
|
||||
$this->segments = $data['segments'];
|
||||
$this->updateSubscribers = $data['updateSubscribers'];
|
||||
$this->subscriberFields = $this->getSubscriberFields(
|
||||
array_keys($this->subscribersData)
|
||||
);
|
||||
$this->subscriberCustomFields = $this->getCustomSubscriberFields(
|
||||
array_keys($this->subscribersData)
|
||||
);
|
||||
$this->subscribersCount = count(reset($this->subscribersData));
|
||||
$this->currentTime = date('Y-m-d H:i:s');
|
||||
$this->profilerStart = microtime(true);
|
||||
}
|
||||
|
||||
function process() {
|
||||
$subscriberFields = $this->subscriberFields;
|
||||
$subscriberCustomFields = $this->subscriberCustomFields;
|
||||
$subscribersData = $this->subscribersData;
|
||||
$subscribersData = $this->filterSubscriberStatus($subscribersData);
|
||||
list($subscribersData, $subscriberFields) = $this->extendSubscribersAndFields(
|
||||
$subscribersData, $subscriberFields
|
||||
);
|
||||
list($existingSubscribers, $newSubscribers) =
|
||||
$this->filterExistingAndNewSubscribers($subscribersData);
|
||||
$createdSubscribers = $updatedSubscribers = array();
|
||||
try {
|
||||
if($newSubscribers) {
|
||||
$createdSubscribers =
|
||||
$this->createOrUpdateSubscribers(
|
||||
'create',
|
||||
$newSubscribers,
|
||||
$subscriberFields,
|
||||
$subscriberCustomFields
|
||||
);
|
||||
}
|
||||
if($existingSubscribers && $this->updateSubscribers) {
|
||||
$updatedSubscribers =
|
||||
$this->createOrUpdateSubscribers(
|
||||
'update',
|
||||
$existingSubscribers,
|
||||
$subscriberFields,
|
||||
$subscriberCustomFields
|
||||
);
|
||||
if($createdSubscribers) {
|
||||
// subtract added from updated subscribers when DB operation takes <1s
|
||||
$updatedSubscribers = array_diff_key(
|
||||
$updatedSubscribers,
|
||||
$createdSubscribers,
|
||||
$subscriberCustomFields
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (\PDOException $e) {
|
||||
return array(
|
||||
'result' => false,
|
||||
'error' => $e->getMessage()
|
||||
);
|
||||
}
|
||||
$segments = new BootStrapMenu('import');
|
||||
return array(
|
||||
'result' => true,
|
||||
'data' => array(
|
||||
'created' => count($createdSubscribers),
|
||||
'updated' => count($updatedSubscribers),
|
||||
'segments' => $segments->getSegments()
|
||||
),
|
||||
'profile' => $this->timeExecution()
|
||||
);
|
||||
}
|
||||
|
||||
function filterExistingAndNewSubscribers($subscribersData) {
|
||||
$existingRecords = array_filter(
|
||||
array_map(function ($subscriberEmails) {
|
||||
return Subscriber::selectMany(array('email'))
|
||||
->whereIn('email', $subscriberEmails)
|
||||
->findArray();
|
||||
}, array_chunk($subscribersData['email'], 200))
|
||||
);
|
||||
if(!$existingRecords) {
|
||||
return array(
|
||||
false,
|
||||
$subscribersData
|
||||
);
|
||||
}
|
||||
$existingRecords = Helpers::flattenArray($existingRecords);
|
||||
$newRecords = array_keys(
|
||||
array_diff(
|
||||
$subscribersData['email'],
|
||||
$existingRecords
|
||||
)
|
||||
);
|
||||
if(!$newRecords) {
|
||||
return array(
|
||||
$subscribersData,
|
||||
false
|
||||
);
|
||||
}
|
||||
$newSubscribers =
|
||||
array_filter(
|
||||
array_map(function ($subscriber) use ($newRecords) {
|
||||
return array_map(function ($index) use ($subscriber) {
|
||||
return $subscriber[$index];
|
||||
}, $newRecords);
|
||||
}, $subscribersData)
|
||||
);
|
||||
|
||||
$existingSubscribers =
|
||||
array_map(function ($subscriber) use ($newRecords) {
|
||||
return array_values( // reindex array
|
||||
array_filter( // remove NULL entries
|
||||
array_map(function ($index, $data) use ($newRecords) {
|
||||
if(!in_array($index, $newRecords)) return $data;
|
||||
}, array_keys($subscriber), $subscriber)
|
||||
)
|
||||
);
|
||||
}, $subscribersData);
|
||||
return array(
|
||||
$existingSubscribers,
|
||||
$newSubscribers
|
||||
);
|
||||
}
|
||||
|
||||
function extendSubscribersAndFields($subscribersData, $subscriberFields) {
|
||||
$subscribersData['created_at'] = $this->filterSubscriberCreatedAtDate();
|
||||
$subscriberFields[] = 'created_at';
|
||||
return array(
|
||||
$subscribersData,
|
||||
$subscriberFields
|
||||
);
|
||||
}
|
||||
|
||||
function getSubscriberFields($subscriberFields) {
|
||||
return array_values(
|
||||
array_filter(
|
||||
array_map(function ($field) {
|
||||
if(!is_int($field)) return $field;
|
||||
}, $subscriberFields)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getCustomSubscriberFields($subscriberFields) {
|
||||
return array_values(
|
||||
array_filter(
|
||||
array_map(function ($field) {
|
||||
if(is_int($field)) return $field;
|
||||
}, $subscriberFields)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function filterSubscriberCreatedAtDate() {
|
||||
return array_fill(0, $this->subscribersCount, $this->currentTime);
|
||||
}
|
||||
|
||||
function filterSubscriberStatus($subscribersData) {
|
||||
if(!in_array('status', $this->subscriberFields)) return;
|
||||
$statuses = array(
|
||||
'subscribed' => array(
|
||||
'subscribed',
|
||||
'confirmed',
|
||||
1,
|
||||
'1',
|
||||
'true'
|
||||
),
|
||||
'unsubscribed' => array(
|
||||
'unsubscribed',
|
||||
-1,
|
||||
'-1',
|
||||
'false'
|
||||
)
|
||||
);
|
||||
$subscribersData['status'] = array_map(function ($state) use ($statuses) {
|
||||
if(in_array(strtolower($state), $statuses['subscribed'])) {
|
||||
return 'confirmed';
|
||||
}
|
||||
if(in_array(strtolower($state), $statuses['unsubscribed'])) {
|
||||
return 'unsubscribed';
|
||||
}
|
||||
return 'confirmed'; // make "subscribed" a default status
|
||||
}, $subscribersData['status']);
|
||||
return $subscribersData;
|
||||
}
|
||||
|
||||
function createOrUpdateSubscribers(
|
||||
$action,
|
||||
$subscribersData,
|
||||
$subscriberFields,
|
||||
$subscriberCustomFields
|
||||
) {
|
||||
$subscribersCount = count(reset($subscribersData)) - 1;
|
||||
$subscribers = array_map(function ($index) use ($subscribersData, $subscriberFields) {
|
||||
return array_map(function ($field) use ($index, $subscribersData) {
|
||||
return $subscribersData[$field][$index];
|
||||
}, $subscriberFields);
|
||||
}, range(0, $subscribersCount));
|
||||
$currentTime = ($action === 'update') ? date('Y-m-d H:i:s') : $this->currentTime;
|
||||
foreach (array_chunk($subscribers, 200) as $data) {
|
||||
if($action == 'create') {
|
||||
Subscriber::createMultiple(
|
||||
$subscriberFields,
|
||||
$data
|
||||
);
|
||||
}
|
||||
if($action == 'update') {
|
||||
Subscriber::updateMultiple(
|
||||
$subscriberFields,
|
||||
$data,
|
||||
$currentTime
|
||||
);
|
||||
}
|
||||
}
|
||||
$result = Helpers::arrayColumn( // return id=>email array of results
|
||||
Subscriber::selectMany(
|
||||
array(
|
||||
'id',
|
||||
'email'
|
||||
))
|
||||
->where(($action === 'create') ? 'created_at' : 'updated_at', $currentTime)
|
||||
->findArray(),
|
||||
'email', 'id'
|
||||
);
|
||||
if($subscriberCustomFields) {
|
||||
$this->createOrUpdateCustomFields(
|
||||
($action === 'create') ? 'create' : 'update',
|
||||
$result,
|
||||
$subscribersData,
|
||||
$subscriberCustomFields
|
||||
);
|
||||
}
|
||||
$this->addSubscribersToSegments(
|
||||
array_keys($result),
|
||||
$this->segments
|
||||
);
|
||||
return $result;
|
||||
}
|
||||
|
||||
function createOrUpdateCustomFields(
|
||||
$action,
|
||||
$dbSubscribers,
|
||||
$subscribersData,
|
||||
$subscriberCustomFields
|
||||
) {
|
||||
$subscribers = array_map(
|
||||
function ($column) use ($dbSubscribers, $subscribersData) {
|
||||
$count = range(0, count($subscribersData[$column]) - 1);
|
||||
return array_map(
|
||||
function ($index, $value)
|
||||
use ($dbSubscribers, $subscribersData, $column) {
|
||||
$subscriberId = array_search(
|
||||
$subscribersData['email'][$index],
|
||||
$dbSubscribers
|
||||
);
|
||||
return array(
|
||||
$column,
|
||||
$subscriberId,
|
||||
$value
|
||||
);
|
||||
}, $count, $subscribersData[$column]);
|
||||
}, $subscriberCustomFields)[0];
|
||||
foreach (array_chunk($subscribers, 200) as $data) {
|
||||
if($action === 'create') {
|
||||
SubscriberCustomField::createMultiple(
|
||||
$data
|
||||
);
|
||||
}
|
||||
if($action === 'update') {
|
||||
SubscriberCustomField::updateMultiple(
|
||||
$data
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addSubscribersToSegments($subscribers, $segments) {
|
||||
foreach (array_chunk($subscribers, 200) as $data) {
|
||||
SubscriberSegment::createMultiple($segments, $data);
|
||||
}
|
||||
}
|
||||
|
||||
function timeExecution() {
|
||||
$profilerEnd = microtime(true);
|
||||
return ($profilerEnd - $this->profilerStart) / 60;
|
||||
}
|
||||
}
|
156
lib/Subscribers/ImportExport/Import/MailChimp.php
Normal file
156
lib/Subscribers/ImportExport/Import/MailChimp.php
Normal file
@@ -0,0 +1,156 @@
|
||||
<?php
|
||||
namespace MailPoet\Subscribers\ImportExport\Import;
|
||||
|
||||
use MailPoet\Util\Helpers;
|
||||
|
||||
class MailChimp {
|
||||
function __construct($APIKey, $lists = false) {
|
||||
$this->APIKey = $this->getAPIKey($APIKey);
|
||||
$this->maxPostSize = Helpers::getMaxPostSize('bytes');
|
||||
$this->dataCenter = $this->getDataCenter($this->APIKey);
|
||||
$this->listsURL = 'https://%s.api.mailchimp.com/2.0/lists/list?apikey=%s';
|
||||
$this->exportURL = 'https://%s.api.mailchimp.com/export/1.0/list/?apikey=%s&id=%s';
|
||||
}
|
||||
|
||||
function getLists() {
|
||||
if(!$this->APIKey || !$this->dataCenter) {
|
||||
return $this->processError('API');
|
||||
}
|
||||
|
||||
$connection = @fopen(sprintf($this->listsURL, $this->dataCenter, $this->APIKey), 'r');
|
||||
|
||||
if(!$connection) {
|
||||
return $this->processError('connection');
|
||||
} else {
|
||||
$response = '';
|
||||
while (!feof($connection)) {
|
||||
$buffer = fgets($connection, 4096);
|
||||
if(trim($buffer) !== '') {
|
||||
$response .= $buffer;
|
||||
}
|
||||
}
|
||||
fclose($connection);
|
||||
}
|
||||
|
||||
$response = json_decode($response);
|
||||
|
||||
if(!$response) {
|
||||
return $this->processError('API');
|
||||
}
|
||||
|
||||
foreach ($response->data as $list) {
|
||||
$lists[] = array(
|
||||
'id' => $list->id,
|
||||
'name' => $list->name
|
||||
);
|
||||
}
|
||||
|
||||
return array(
|
||||
'result' => true,
|
||||
'data' => $lists
|
||||
);
|
||||
}
|
||||
|
||||
function getSubscribers($lists = array()) {
|
||||
if(!$this->APIKey || !$this->dataCenter) {
|
||||
return $this->processError('API');
|
||||
}
|
||||
|
||||
if(!$lists) {
|
||||
return $this->processError('lists');
|
||||
}
|
||||
|
||||
$bytesFetched = 0;
|
||||
foreach ($lists as $list) {
|
||||
$url = sprintf($this->exportURL, $this->dataCenter, $this->APIKey, $list);
|
||||
$connection = @fopen($url, 'r');
|
||||
if(!$connection) {
|
||||
return $this->processError('connection');
|
||||
} else {
|
||||
$i = 0;
|
||||
$header = array();
|
||||
while (!feof($connection)) {
|
||||
$buffer = fgets($connection, 4096);
|
||||
if(trim($buffer) !== '') {
|
||||
$obj = json_decode($buffer);
|
||||
if($i === 0) {
|
||||
$header = $obj;
|
||||
if(is_object($header) && isset($header->error)) {
|
||||
return $this->processError('lists');
|
||||
}
|
||||
if(!isset($headerHash)) {
|
||||
$headerHash = md5(implode(',', $header));
|
||||
} else {
|
||||
if(md5(implode(',', $header) !== $headerHash)) {
|
||||
return $this->processError('headers');
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$subscribers[] = $obj;
|
||||
}
|
||||
$i++;
|
||||
}
|
||||
|
||||
$bytesFetched += strlen($buffer);
|
||||
if($bytesFetched > $this->maxPostSize) {
|
||||
return $this->processError('size');
|
||||
|
||||
}
|
||||
}
|
||||
fclose($connection);
|
||||
}
|
||||
}
|
||||
|
||||
if(!count($subscribers)) {
|
||||
return $this->processError('subscribers');
|
||||
|
||||
}
|
||||
|
||||
return array(
|
||||
'result' => true,
|
||||
'data' => array(
|
||||
'subscribers' => $subscribers,
|
||||
'invalid' => false,
|
||||
'duplicate' => false,
|
||||
'header' => $header,
|
||||
'count' => count($subscribers)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function getDataCenter($APIKey) {
|
||||
// double parantheses: http://phpsadness.com/sad/51
|
||||
return ($APIKey) ? end((explode('-', $APIKey))) : false;
|
||||
}
|
||||
|
||||
function getAPIKey($APIKey) {
|
||||
return (preg_match('/[a-zA-Z0-9]{32}-[a-zA-Z0-9]{3,}/', $APIKey)) ? $APIKey : false;
|
||||
}
|
||||
|
||||
function processError($error) {
|
||||
switch ($error) {
|
||||
case 'API':
|
||||
$errorMessage = __('Invalid API key.');
|
||||
break;
|
||||
case 'connection':
|
||||
$errorMessage = __('Could not connect to your MailChimp account.');
|
||||
break;
|
||||
case 'headers':
|
||||
$errorMessage = __('The selected lists do not have matching columns (headers).');
|
||||
break;
|
||||
case 'size':
|
||||
$errorMessage = __('Information received from MailChimp is too large for processing. Please limit the number of lists.');
|
||||
break;
|
||||
case 'subscribers':
|
||||
$errorMessage = __('Did not find any active subscribers.');
|
||||
break;
|
||||
case 'lists':
|
||||
$errorMessage = __('Did not find any valid lists');
|
||||
break;
|
||||
}
|
||||
return array(
|
||||
'result' => false,
|
||||
'error' => $errorMessage
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user