| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 |
- <?php
- require_once dirname(dirname(dirname(__FILE__))) . '/libs/mailchimp-rest-api/src/VPS/MailChimp.php';
- class MailChimpSubscribe
- {
- const MC_ERROR_PH = 'mailchimp';
- /**
- * The modX object.
- *
- * @since 1.0.0
- * @access public
- * @var modX The modX object.
- */
- public $modx;
- /**
- * @var \VPS\MailChimp
- */
- public $mailchimp;
- /**
- * The namespace for this package.
- *
- * @since 1.0.0
- * @access public
- * @var string The package namespace.
- */
- public $namespace = 'mailchimpsubscribe';
- /**
- * Holds all configs values.
- *
- * @since 1.0.0
- * @access public
- * @var array Config value holder.
- */
- public $config = [];
- /**
- * @var Sterc\FormIt\Hook
- */
- public $hook;
- /**
- * Holds mailchimp message for subscribing a user.
- *
- * @since 1.0.0
- * @access public
- * @var string Mailchimp result message.
- */
- public $mcSubscribeMessage = '';
- /**
- * Holds the name or id of the MailChimp list TV.
- *
- * @var string
- */
- public $mcListTV = '';
- /**
- * Should a user be created or should an existing user be updated.
- *
- * @since 1.0.0
- * @access private
- * @var string Mailchimp subscribe mode.
- */
- private $mcSubscribeMode = 'create';
- /**
- * Array containing mergefields and form fields mapping.
- * @var array
- */
- private $mapping = [];
- /**
- * Array containing all mergefields and form values.
- *
- * @var array
- */
- private $values = [];
- /**
- * Name of field used for subscribing to mailchimp newsletter.
- * @var string
- */
- private $subscribeField = 'newsgroup';
- /**
- * Value that the subscribe field should have for subscribing a user to mailchimp.
- * @var string
- */
- private $subscribeFieldValue = 'yes';
- /**
- * Initialize the class.
- *
- * @since 1.0.0
- * @param modX $modx The modX object.
- * @param array $config Array with config values.
- */
- public function __construct(modX $modx, array $config = [])
- {
- $this->modx =& $modx;
- $this->namespace = $this->modx->getOption('namespace', $config, 'mailchimpsubscribe');
- $corePath = $this->modx->getOption(
- 'site.core_path',
- $config,
- $this->modx->getOption('core_path') . 'components/mailchimpsubscribe/'
- );
- $assetsUrl = $this->modx->getOption(
- 'site.assets_url',
- $config,
- $this->modx->getOption('assets_url') . 'components/mailchimpsubscribe/'
- );
- $assetsPath = $this->modx->getOption(
- 'site.assets_path',
- $config,
- $this->modx->getOption('assets_path') . 'components/mailchimpsubscribe/'
- );
- $this->config = array_merge([
- 'namespace' => $this->namespace,
- 'corePath' => $corePath,
- 'modelPath' => $corePath . 'model/',
- 'chunksPath' => $corePath . 'elements/chunks/',
- 'snippetsPath' => $corePath . 'elements/snippets/',
- 'templatesPath' => $corePath . 'templates/',
- 'assetsPath' => $assetsPath,
- 'assetsUrl' => $assetsUrl,
- 'jsUrl' => $assetsUrl . 'js/',
- 'cssUrl' => $assetsUrl . 'css/',
- 'connectorUrl' => $assetsUrl . 'connector.php'
- ], $config);
- $this->mcListTV = $this->modx->getOption('mailchimpsubscribe.list_tv');
- $this->mcListTV = is_numeric($this->mcListTV) ? (int) $this->mcListTV : (string) $this->mcListTV;
- $this->modx->addPackage('mailchimpsubscribe', $this->config['modelPath']);
- $this->modx->lexicon->load('mailchimpsubscribe:default');
- }
- /**
- * @param $hook
- */
- private function setHook($hook)
- {
- $this->hook = $hook;
- }
- private function setSubscribeFields()
- {
- if ($this->hook->config['mailchimpSubscribeField']) {
- $this->subscribeField = $this->hook->config['mailchimpSubscribeField'];
- }
- if ($this->hook->config['mailchimpSubscribeFieldValue']) {
- $this->subscribeFieldValue = $this->hook->config['mailchimpSubscribeFieldValue'];
- }
- }
- /**
- * Set the mailchimp merge tags configuration or add an error.
- *
- * @return bool
- */
- private function setMapping()
- {
- $config = $this->hook->config['mailchimpFields'];
- $fields = array_filter(explode(',', $config));
- if (!$fields) {
- $this->hook->addError(self::MC_ERROR_PH, $this->modx->lexicon('mailchimpsubscribe.error.missing_field_config_scriptproperty'));
- return false;
- }
- foreach ($fields as $field) {
- list($fieldName, $mergeTag) = explode('=', $field);
- $this->mapping[$mergeTag] = $fieldName;
- }
- if (!array_key_exists('EMAIL', $this->mapping)) {
- $this->hook->addError(self::MC_ERROR_PH, $this->modx->lexicon('mailchimpsubscribe.error.missing_required_config_field', ['tag' => 'EMAIL']));
- return false;
- }
- return true;
- }
- /**
- * Set the values array which contains all merge tags and form values which will be pushed to mailchimp.
- */
- private function setValues()
- {
- foreach ($this->mapping as $mergeTag => $fieldname) {
- if ($mergeTag !== 'EMAIL') {
- $this->values[$mergeTag] = $this->formatValue($this->hook->getValue($fieldname));
- }
- }
- }
- /**
- * Init MailChimp REST Enabled API 3.0 Wrapper Class.
- *
- * https://github.com/vatps/mailchimp-rest-api
- */
- private function initMailChimpApi()
- {
- $this->mailchimp = new \VPS\MailChimp($this->modx->getOption('mailchimpsubscribe.mailchimp_api_key'));
- }
- /**
- * Set mailchimp list id based on scriptproperty if it is set, else use tv value.
- *
- * @param $scriptProperties
- *
- * @return null
- */
- private function setListId($scriptProperties)
- {
- if (isset($scriptProperties['mailchimpListId']) && !empty($scriptProperties['mailchimpListId'])) {
- $listId = $scriptProperties['mailchimpListId'];
- } else {
- $listId = $this->modx->resource->getTVValue($this->mcListTV);
- }
- return $listId;
- }
- /**
- * Set mailchimp subscriber status on subscription.
- *
- * @param $scriptProperties
- *
- * @return null
- */
- private function setSubscriberStatus($scriptProperties)
- {
- if (isset($scriptProperties['mailchimpSubscribeStatus']) &&
- !empty($scriptProperties['mailchimpSubscribeStatus'])) {
- $status = $scriptProperties['mailchimpSubscribeStatus'];
- } else {
- $status = 'pending';
- }
- return $status;
- }
- /**
- * Retrieve all MailChimp lists as TV select options.
- *
- * @return string
- */
- public function getMailChimpLists()
- {
- $this->initMailChimpApi();
- $params = array('count' => 100);
- $result = $this->mailchimp->get('/lists/?' . http_build_query($params));
- $options = [];
- if (isset($result['lists']) && !empty($result['lists'])) {
- foreach ($result['lists'] as $list) {
- $options[$list['name']] = $list['name'] . '==' . $list['id'];
- }
- }
- asort($options, SORT_NATURAL);
- array_unshift($options, '- Select a mailchimp list - ==0');
- return implode('||', $options);
- }
- /**
- *
- * @param $hook
- * @param $scriptProperties
- * @return string
- */
- public function subscribeMailChimp($hook, $scriptProperties)
- {
- $this->modx->lexicon->load('mailchimpsubscribe:default');
- /* Set hook. */
- $this->setHook($hook);
- /* Initialize mailchimp api. */
- $this->initMailChimpApi();
- /* Set subscribe fields based on scriptproperties. */
- $this->setSubscribeFields();
- /* Fetch data from hook */
- $values = $this->hook->getValues();
- if ($values[$this->subscribeField] !== $this->subscribeFieldValue) {
- return true;
- }
- /* Validate the properties */
- $valid = $this->setMapping();
- if (!$valid) {
- return false;
- }
- $listId = $this->setListId($scriptProperties);
- $email = $this->formatValue($this->hook->getValue($this->mapping['EMAIL']));
- $this->setValues();
- /* No list id found. */
- if (empty($listId)) {
- $this->hook->addError(
- self::MC_ERROR_PH,
- $this->modx->lexicon('mailchimpsubscribe.error.no_list_found', [], $this->modx->cultureKey)
- );
- return false;
- }
- /* Check if user is allowed to be processed */
- $subscribeUser = $this->checkMCSubscriberStatus($listId, $email);
- if ($subscribeUser === false) {
- $this->hook->addError(self::MC_ERROR_PH, $this->mcSubscribeMessage);
- return false;
- }
- /**
- * If an existing user is not subscribed, update existing user and set status to pending.
- * Which will send the user an emailconfirmation for the subscribtion.
- *
- * Subscribe statusses:
- * - subscribed: To add an address right away.
- * - pending: To send a confirmation email.
- * - unsubscribed/cleaned to archive unused addresses.
- *
- * http://developer.mailchimp.com/documentation/mailchimp/guides/manage-subscribers-with-the-mailchimp-api/
- */
- $subscribeStatus = $this->setSubscriberStatus($scriptProperties);
- /* Check if tags are set and status is not subscribed */
- if ($subscribeStatus !== 'subscribed' &&
- !empty($scriptProperties['mailchimpTags']) &&
- isset($scriptProperties['mailchimpTags'])
- ) {
- $this->hook->addError(
- self::MC_ERROR_PH,
- $this->modx->lexicon(
- 'mailchimpsubscribe.error.incorrect_status',
- [],
- $this->modx->cultureKey
- )
- );
- return false;
- }
- if ($this->mcSubscribeMode === 'update') {
- $result = $this->mailchimp->PATCH(
- '/lists/' . $listId . '/members/' . md5($email),
- [
- 'email_address' => $email,
- 'merge_fields' => $this->values,
- 'status' => $subscribeStatus
- ]
- );
- } else {
- $result = $this->mailchimp->post(
- '/lists/' . $listId . '/members',
- [
- 'email_address' => $email,
- 'merge_fields' => $this->values,
- 'status' => $subscribeStatus
- ]
- );
- }
- if ($result['status'] !== $subscribeStatus) {
- $response = $result['title'] . ': ' . $result['detail'];
- $this->hook->addError(self::MC_ERROR_PH, $response);
- return false;
- }
- /* Add tags to subscription (Has no error handeling to prevent the process being killed) */
- if ($subscribeStatus === 'subscribed' &&
- !empty($scriptProperties['mailchimpTags']) &&
- isset($scriptProperties['mailchimpTags'])
- ) {
- $this->addTags($listId, $email, $scriptProperties['mailchimpTags']);
- }
- return true;
- }
- /**
- * Check mailchimp subscriber status by emailaddress.
- *
- * @param string $listId List id as specified in resource TV.
- * @param string $email Form value emailaddress.
- *
- * @return bool
- */
- public function checkMCSubscriberStatus($listId, $email)
- {
- $this->modx->lexicon->load('mailchimpsubscribe:default');
- $result = $this->mailchimp->get('/lists/' . $listId . '/members/' . md5($email));
- /* If status 404, the e-mailaddress is unknown and e-mailaddress can be subscribed. */
- if ($result['status'] === 404) {
- return true;
- }
- switch ($result['status']) {
- case 'subscribed':
- $this->mcSubscribeMessage = $this->modx->lexicon(
- 'mailchimpsubscribe.error.subscribed',
- [],
- $this->modx->cultureKey
- );
- break;
- case 'unsubscribed':
- /**
- * Update user and set status to pending.
- */
- $this->mcSubscribeMode = 'update';
- return true;
- break;
- case 'pending':
- $this->mcSubscribeMessage = $this->modx->lexicon(
- 'mailchimpsubscribe.error.pending',
- [],
- $this->modx->cultureKey
- );
- break;
- case 'cleaned':
- $this->mcSubscribeMessage = $this->modx->lexicon(
- 'mailchimpsubscribe.error.cleaned',
- [],
- $this->modx->cultureKey
- );
- break;
- }
- return false;
- }
- /**
- * Processes comma separated value to tags for subscribes
- *
- * @param $listId
- * @param $email
- * @param $tags
- * @return string
- */
- public function addTags($listId, $email, $tags)
- {
- $hashed = md5($email);
- $data = [];
- $tags = explode(',', $tags);
- /* Needs array and status active to create tag if not existing */
- foreach ($tags as $value) {
- $data[] = [
- 'name' => $value,
- 'status' => 'active'
- ];
- }
- /* Post data to mailchimp */
- $result = $this->mailchimp->post(
- '/lists/' . $listId . '/members/' . $hashed . '/tags',
- [
- 'tags' => $data
- ]
- );
- return $result;
- }
- /**
- * Format form values.
- *
- * @param $value
- * @return string
- */
- private function formatValue($value) {
- return trim($value);
- }
- }
|