Created
August 6, 2014 15:32
-
-
Save stefanheimes/897396bbfb0c2f19254d to your computer and use it in GitHub Desktop.
This file contains hidden or 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
<?php | |
/** | |
* PHP version 5 | |
* | |
* @copyright MEN AT WORK 2014 | |
* @license LGPL-3.0+ | |
* @filesource | |
*/ | |
/** | |
* Initialize the system | |
*/ | |
define('TL_MODE', 'FE'); | |
require_once('../../initialize.php'); | |
use Avisota\Contao\Entity\MailingList; | |
use Avisota\Contao\Entity\Recipient; | |
use Avisota\Contao\Subscription\SubscriptionManager; | |
use Contao\Doctrine\ORM\EntityHelper; | |
use Doctrine\ORM\NoResultException; | |
use Doctrine\ORM\Query; | |
class AvisotaCsvRecipientImporter | |
{ | |
/** | |
* Import file | |
*/ | |
const strImportFile = 'files/standard/import/recipients.csv'; | |
/** | |
* Mapping from CSV to intern. | |
*/ | |
protected $arrCsvMapping = array | |
( | |
self::LIST_EMAIL => 'email', | |
self::LIST_FORENAME => 'forename', | |
self::LIST_SURNAME => 'surname', | |
self::LIST_GENDER => 'gender', | |
self::LIST_LANGUAGE => '', | |
); | |
/** | |
* Name of the adder of the new rows. | |
* @var string | |
*/ | |
protected $strAddedBy = 'Importer'; | |
/** | |
* Set the auto refresh html markup. | |
* @var bool | |
*/ | |
protected $blnAutoRefresh = true; | |
/** | |
* If a mail is already in the list try to add it to the given | |
* mailing list. | |
* | |
* @var bool | |
*/ | |
protected $blnAddExistingMailToList = true; | |
// OptIn ----------------------------------------------------------------------------------------------------------- | |
/** | |
* Send opt out. | |
* @var bool | |
*/ | |
protected $sendOptOut = false; | |
/** | |
* Mailer for the opt mails. | |
* @var string | |
*/ | |
protected $transportId = '05f247db-1cad-11e4-9cc8-e69d0c26f1ba'; //default swift mailer | |
/** | |
* ID of the opt mail. | |
* @var string | |
*/ | |
protected $mailId = ''; //OptIn Mail DE | |
// Language -------------------------------------------------------------------------------------------------------- | |
/** | |
* Use a custom language and not from the import file. | |
* @var bool | |
*/ | |
protected $useCustomLanguage = true; | |
/** | |
* Use this language tag for everyone. | |
* @var string | |
*/ | |
protected $customLanguage = 'de'; | |
/** | |
* If there is no language use this one. | |
* @var string | |
*/ | |
protected $defaultLanguage = 'en'; | |
// Mail lists ------------------------------------------------------------------------------------------------------ | |
/** | |
* Use this mailing list. | |
* @var string | |
*/ | |
protected $usedMailingList = 'default'; | |
/** | |
* Mapping for the mailing lists. | |
* @var array | |
*/ | |
public $arrMailingLists = array( | |
'default' => array( | |
'de' => '3e515e54-3ca6-11e3-8066-1ab841b66e32' | |
), | |
); | |
/** | |
* Jump to urls. | |
* @var array | |
*/ | |
protected $mailUrl = array( | |
'de' => '', | |
'en' => '', | |
); | |
// Limits ---------------------------------------------------------------------------------------------------------- | |
/** | |
* Insert pe run. | |
* @var int | |
*/ | |
protected $limit = 4; | |
// Converting ------------------------------------------------------------------------------------------------------ | |
/** | |
* Converting language. | |
* @var array | |
*/ | |
public $arrLanConvert = array( | |
'D' => 'de', | |
'E' => 'en' | |
); | |
/** | |
* Mapping for the gender. | |
* @var array | |
*/ | |
protected $arrGender = array( | |
// Male | |
'Herr' => 'male', | |
'Herr.' => 'male', | |
'Herren' => 'male', | |
'Herrn' => 'male', | |
'Mr.' => 'male', | |
'Mr' => 'male', | |
'Mister' => 'male', | |
'male' => 'male', | |
// Female | |
'Frau' => 'female', | |
'Frauen' => 'female', | |
'Mrs.' => 'female', | |
'Mrs' => 'female', | |
'female' => 'female', | |
); | |
// Const ----------------------------------------------------------------------------------------------------------- | |
/** | |
* Vars for the intern mapping, don't touch this. | |
*/ | |
const LIST_EMAIL = 'email'; | |
const LIST_FORENAME = 'forename'; | |
const LIST_SURNAME = 'surname'; | |
const LIST_GENDER = 'gender'; | |
const LIST_LANGUAGE = 'language'; | |
// Vars ------------------------------------------------------------------------------------------------------------ | |
/** | |
* Swift_Mime_Grammar. | |
* @var null|Swift_Mime_Grammar | |
*/ | |
protected $objTester = null; | |
/** | |
* Mailing list id's. | |
* @var array | |
*/ | |
protected $arrLang2Mailing = array(); | |
/** | |
* Entity Accessor for doctrine. | |
* @var \Contao\Doctrine\ORM\EntityAccessor $entityAccessor | |
*/ | |
protected $objEntityAccessor = null; | |
/** | |
* The subscription manager from avisota. | |
* @var \Avisota\Contao\Subscription\SubscriptionManager $subscriptionManager | |
*/ | |
protected $objSubscriptionManager = null; | |
/** | |
* A list with all mailing list for the current use. | |
* | |
* @var array | |
*/ | |
protected $arrAvisotaMailingList = array(); | |
/** | |
* __construct | |
*/ | |
public function __construct() | |
{ | |
// Check if we have a mailing list. | |
if (!isset($this->arrMailingLists[$this->usedMailingList])) | |
{ | |
throw new \Exception('Unknown mailing list:' . $this->usedMailingList); | |
} | |
// Set the default mailing lists. | |
$this->arrLang2Mailing = $this->arrMailingLists[$this->usedMailingList]; | |
// Setup some vars. | |
$this->objTester = new Swift_Mime_Grammar(); | |
$this->objEntityAccessor = $GLOBALS['container']['doctrine.orm.entityAccessor']; | |
$this->objSubscriptionManager = $GLOBALS['container']['avisota.subscription']; | |
\System::loadLanguageFile('avisota_subscription'); | |
} | |
/** | |
* Echo something on the screen. | |
* | |
* @param string $strMsg | |
*/ | |
protected function echoMsg($strMsg) | |
{ | |
echo "<pre>"; | |
var_dump($strMsg); | |
echo "</pre>"; | |
} | |
/** | |
* @param $arrSubscriptions | |
*/ | |
protected function echoSubscriptions($arrSubscriptions) | |
{ | |
} | |
/** | |
* Check if the email is valid. | |
* | |
* @param string $strMail | |
* | |
* @return bool True is || False is not. | |
*/ | |
protected function isValidEMail($strMail) | |
{ | |
if (!preg_match('/^' . $this->objTester->getDefinition('addr-spec') . '$/D', $strMail)) | |
{ | |
$this->echoMsg('Invalid email: ' . $strMail); | |
\System::log('Invalid email: ' . $strMail, __CLASS__ . ' | ' . __FUNCTION__, TL_ERROR); | |
return false; | |
} | |
return true; | |
} | |
/** | |
* Check if the user is already in the database. | |
* | |
* @param string $strMail Email for checking | |
* | |
* @return boolean True is in DB || False nope not found. | |
*/ | |
protected function isMailInDb($strMail) | |
{ | |
// Check if the email already exists | |
$queryBuilder = EntityHelper::getEntityManager()->createQueryBuilder(); | |
$queryBuilder | |
->select('COUNT(r.id)') | |
->from('Avisota\Contao:Recipient', 'r') | |
->where('r.email=?1') | |
->setParameter(1, $strMail); | |
$query = $queryBuilder->getQuery(); | |
if ($query->getResult(Query::HYDRATE_SINGLE_SCALAR) < 1) | |
{ | |
return false; | |
} | |
else | |
{ | |
return true; | |
} | |
} | |
/** | |
* Get the recipient based on the email. | |
* | |
* @param string $strMail | |
* | |
* @return \Avisota\Contao\Entity\Recipient | |
*/ | |
protected function getRecipientByMail($strMail) | |
{ | |
// Check if the email already exists | |
$repository = EntityHelper::getEntityManager()->getRepository('Avisota\Contao:Recipient'); | |
$queryBuilder = $repository->createQueryBuilder('r'); | |
$expr = $queryBuilder->expr(); | |
$queryBuilder | |
->where($expr->eq('r.email', ':mail')) | |
->setParameter('mail', $strMail); | |
$query = $queryBuilder->getQuery(); | |
try | |
{ | |
return $query->getSingleResult(); | |
} | |
catch (NoResultException $e) | |
{ | |
return null; | |
} | |
} | |
/** | |
* Get a list with the given mailing list. | |
* | |
* @param $arrIds | |
* | |
* @return MailingList[] A list with all searched mailing lists. | |
*/ | |
protected function getMailingLists($arrIds) | |
{ | |
$arrReturn = array(); | |
foreach ($arrIds as $strID) | |
{ | |
// Check if global is given. | |
if ($strID == 'global') | |
{ | |
continue; | |
} | |
// get the data. | |
if (!isset($this->arrAvisotaMailingList[$strID])) | |
{ | |
// Check if the email already exists | |
$repository = EntityHelper::getEntityManager()->getRepository('Avisota\Contao:MailingList'); | |
$queryBuilder = $repository->createQueryBuilder('m'); | |
$expr = $queryBuilder->expr(); | |
$queryBuilder | |
->where($expr->eq('m.id', ':mailingListId')) | |
->setParameter('mailingListId', $strID); | |
$query = $queryBuilder->getQuery(); | |
try | |
{ | |
$arrReturn[$strID] = $query->getSingleResult(); | |
} | |
catch (NoResultException $e) | |
{ | |
continue; | |
} | |
} | |
// Add to the array. | |
$arrReturn[] = $this->arrAvisotaMailingList[$strID]; | |
} | |
// Return the result. | |
return $arrReturn; | |
} | |
/** | |
* Show the end. | |
* | |
* @return array | |
*/ | |
protected function showEnd() | |
{ | |
// echo "<pre>"; | |
// var_dump($objSteps); | |
// var_dump($csvSource->getAllData($arrImport)); | |
// echo "</pre>"; | |
$this->echoMsg('FINISHED'); | |
exit(); | |
// return array | |
// ( | |
// 'result' => true, // true or false | |
// 'details' => 'Import succsessfull' // status for logging | |
// ); | |
} | |
/** | |
* Show the next page content. | |
* | |
* @param int $turn Turn ID | |
*/ | |
protected function showNextStep($turn) | |
{ | |
$parameters = array | |
( | |
'turn' => $turn + 1, | |
); | |
$url = sprintf | |
( | |
// TODO: Add path. | |
'%ssystem/modules/newsletter-addon/AvisotaCsvImporter.php?%s', | |
Environment::get('base'), | |
http_build_query($parameters) | |
); | |
if ($this->blnAutoRefresh) | |
{ | |
echo '<html><head><meta http-equiv="refresh" content="8; URL=' . $url . '"></head><body>Still importing...</body></html>'; | |
} | |
else | |
{ | |
echo '<html><head></head><body> Still importing... <a href=' . $url . '>NEXT</a></body></html>'; | |
} | |
exit(); | |
} | |
/** | |
* Read the CSV and return the array. | |
* | |
* @param int $intOffset Start at .... | |
* | |
* @param int $intLimit Get only .... | |
* | |
* @return array|bool | |
*/ | |
protected function readCSV($intOffset = 0, $intLimit = 0) | |
{ | |
$csvSource = new TabimporterSource_csv(); | |
// Setting for the importer. | |
$arrImport = array | |
( | |
'sourceFile' => self::strImportFile, | |
'fieldDelimiter' => 'semicolon', | |
'hasFieldnames' => true | |
); | |
// Get the data from the csv | |
$arrData = $csvSource->getAllData($arrImport); | |
// If no limit is set return all. | |
if ($intLimit == 0) | |
{ | |
return $arrData; | |
} | |
// Only get the data for this turn. | |
else | |
{ | |
return array_slice($arrData, $intOffset, $intLimit); | |
} | |
} | |
/** | |
* Get the data from the data array and try to resolve some special cases. | |
* | |
* @param array $arrRow The data row. | |
* | |
* @param string $strField Name of the intern field. | |
* | |
* @return string The value. | |
*/ | |
protected function getDataFromArray($arrRow, $strField) | |
{ | |
// Get the name of the field from the csv. | |
$strCsvField = $this->arrCsvMapping[$strField]; | |
// Get the value from the CSV. | |
$strValue = $arrRow[$strCsvField]; | |
// Make something with it. | |
switch ($strField) | |
{ | |
case self::LIST_GENDER: | |
return $this->arrGender[$strValue]; | |
case self::LIST_LANGUAGE: | |
if ($this->useCustomLanguage) | |
{ | |
return $this->customLanguage; | |
} | |
else | |
{ | |
return ($this->arrLanConvert[$strValue]) ? $this->arrLanConvert[$strValue] : $this->defaultLanguage; | |
} | |
default: | |
return $strValue; | |
} | |
} | |
/** | |
* Add a new recipient to the database. | |
* | |
* @param array $arrRecipient A list with all information. | |
* | |
* @return \Avisota\Contao\Entity\Recipient The new recipient. | |
*/ | |
protected function addNewRecipient($arrRecipient) | |
{ | |
// Create a new recipient object. | |
$objNewRecipient = new Recipient(); | |
$objNewRecipient->setEmail($this->getDataFromArray($arrRecipient, self::LIST_EMAIL)); | |
$objNewRecipient->setSurname($this->getDataFromArray($arrRecipient, self::LIST_SURNAME)); | |
$objNewRecipient->setForename($this->getDataFromArray($arrRecipient, self::LIST_FORENAME)); | |
$objNewRecipient->setGender($this->getDataFromArray($arrRecipient, self::LIST_GENDER)); | |
$objNewRecipient->setAddedByName($this->strAddedBy); | |
// Save to the database. | |
EntityHelper::getEntityManager()->persist($objNewRecipient); | |
EntityHelper::getEntityManager()->flush(); | |
// Echo the data. | |
$this->echoMsg($this->objEntityAccessor->getRawProperties($objNewRecipient, array('email', 'surname', 'forename', 'gender', 'addedByName'))); | |
return $objNewRecipient; | |
} | |
/** | |
* Add a user to a mailing list. | |
* | |
* @param \Avisota\Contao\Entity\Recipient $objRecipient Recipient object. | |
* | |
* @param string $strLanguage Language. | |
* | |
* @param mixed $options Options for avisota. | |
* | |
* @return \Avisota\Contao\Entity\Subscription[] | |
*/ | |
protected function addSubscriptionFor($objRecipient, $strLanguage, $options) | |
{ | |
// Get the mailing lists. | |
$arrMailingLists = array($this->arrLang2Mailing[$strLanguage]); | |
$arrAvisotaMailingLists = $this->getMailingLists($arrMailingLists); | |
// Add to the global one. | |
$this->objSubscriptionManager->subscribe($objRecipient, null, $options); | |
// Add to the given mailing lists. | |
$subscriptions = $this->objSubscriptionManager->subscribe($objRecipient, $arrAvisotaMailingLists, $options); | |
return $subscriptions; | |
} | |
/** | |
* | |
* @return type | |
*/ | |
public function importRecipients() | |
{ | |
global $container; | |
// Set up everything. | |
$turn = \Input::get('turn'); | |
$offset = $turn * $this->limit; | |
$limit = $this->limit; | |
$options = ($this->sendOptOut) ? SubscriptionManager::OPT_IGNORE_BLACKLIST : SubscriptionManager::OPT_ACTIVATE; | |
$arrRecipients = $this->readCSV($offset, $limit); | |
// Get the entity and subscription managers | |
$entityManager = EntityHelper::getEntityManager(); | |
$repository = $entityManager->getRepository('Avisota\Contao\Entity\Recipient'); | |
// If we have no data end here. | |
if (count($arrRecipients) == 0) | |
{ | |
$this->showEnd(); | |
} | |
foreach ($arrRecipients as $arrRecipient) | |
{ | |
// Check email. | |
if (!$this->isValidEMail($this->getDataFromArray($arrRecipient, self::LIST_EMAIL))) | |
{ | |
continue; | |
} | |
// Get the language. | |
$strLang = $this->getDataFromArray($arrRecipient, self::LIST_LANGUAGE); | |
// Check if we have the email. | |
if (!$this->isMailInDb($this->getDataFromArray($arrRecipient, self::LIST_EMAIL))) | |
{ | |
// Add a new recipient and subscription. | |
$objRecipient = $this->addNewRecipient($arrRecipient); | |
$objSubscriptions = $this->addSubscriptionFor($objRecipient, $strLang, $options); | |
// Send opt-in if flag is set. | |
if ($this->sendOptOut && $objSubscriptions) | |
{ | |
$this->sendOptIn($objRecipient, $objSubscriptions, $strLang); | |
} | |
} | |
else | |
{ | |
// Add a log. | |
$this->echoMsg('Already in DB: ' . $this->getDataFromArray($arrRecipient, self::LIST_EMAIL)); | |
\System::log('Already in DB: ' . $this->getDataFromArray($arrRecipient, self::LIST_EMAIL), __CLASS__ . ' | ' . __FUNCTION__, TL_ERROR); | |
// Check if we should add it to the list. | |
if (!$this->blnAddExistingMailToList) | |
{ | |
continue; | |
} | |
// Get the recipient from the database. | |
$objRecipient = $this->getRecipientByMail($this->getDataFromArray($arrRecipient, self::LIST_EMAIL)); | |
// Echo the data. | |
$this->echoMsg($this->objEntityAccessor->getRawProperties($objRecipient, array('email', 'surname', 'forename', 'gender', 'addedByName'))); | |
// Set the mailing lists. | |
$objSubscriptions = $this->addSubscriptionFor($objRecipient, $strLang, $options); | |
} | |
} | |
$this->showNextStep($turn); | |
} | |
/** | |
* Send opt in mail. | |
* | |
* @param \Avisota\Contao\Entity\Recipient $objRecipient | |
* | |
* @param \Avisota\Contao\Entity\Subscription[] $objSubscriptions | |
* | |
* @param string $strLang The language to use. | |
*/ | |
protected function sendOptIn($objRecipient, $objSubscriptions, $strLang) | |
{ | |
$tokens = array(); | |
foreach ($objSubscriptions as $objSubscription) | |
{ | |
$tokens[] = $objSubscription->getToken(); | |
} | |
$parameters = array( | |
'email' => $objRecipient->getEmail(), | |
'token' => implode(',', $tokens), | |
); | |
$url = \Environment::get('base') . $this->mailUrl[$strLang]; | |
$url .= (strpos($url, '?') === false ? '?' : '&'); | |
$url .= http_build_query($parameters); | |
// ToDo: Check if we need this. We have already the recipient object? | |
// $objSubscription = $objSubscription[0]; | |
// $recipient = $objSubscription->getRecipient(); | |
// TODO | |
$newsletterData = array(); | |
$newsletterData['link'] = (object)array( | |
'url' => $url, | |
'text' => $GLOBALS['TL_LANG']['avisota_subscription']['confirmSubscription'], | |
); | |
$this->sendMessage($objRecipient, $this->mailId, $this->transportId, $newsletterData); | |
} | |
/** | |
* Get the templates and information and send the option. | |
* | |
* @param \Avisota\Contao\Entity\Recipient $objRecipient | |
* | |
* @param string $mailBoilerplateId | |
* | |
* @param string $transportId | |
* | |
* @param string $newsletterData | |
* | |
* @throws \RuntimeException | |
*/ | |
protected function sendMessage($objRecipient, $mailBoilerplateId, $transportId, $newsletterData) | |
{ | |
// Last check if we send a msg. | |
if ($this->sendOptOut == false) | |
{ | |
return; | |
} | |
$this->echoMsg('SEND MSG'); | |
$messageRepository = EntityHelper::getRepository('Avisota\Contao:Message'); | |
$messageEntity = $messageRepository->find($mailBoilerplateId); | |
if (!$messageEntity) | |
{ | |
throw new \RuntimeException('Could not find message id ' . $mailBoilerplateId); | |
} | |
/** @var MessagePreRendererInterface $renderer */ | |
$renderer = $GLOBALS['container']['avisota.renderer']; | |
$preRenderedMessage = $renderer->renderMessage($messageEntity); | |
$message = $preRenderedMessage->render($objRecipient, $newsletterData); | |
/** @var TransportInterface $transport */ | |
$transport = $GLOBALS['container']['avisota.transport.' . $transportId]; | |
$transport->send($message); | |
} | |
} | |
$objImporter = new AvisotaCsvRecipientImporter(); | |
$objImporter->importRecipients(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment