Campaignmonitor_Createsend - Version 1.0.0

Version Notes

Initial release.

Download this release

Release Info

Developer Fontis
Extension Campaignmonitor_Createsend
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

Files changed (76) hide show
  1. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Customer/Edit/Grid.php +64 -0
  2. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email.php +36 -0
  3. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/Grid.php +192 -0
  4. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View.php +98 -0
  5. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Abstract.php +31 -0
  6. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Form.php +38 -0
  7. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Tab/Clicks.php +56 -0
  8. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Tab/Details.php +43 -0
  9. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Tab/Html.php +68 -0
  10. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Tab/Opens.php +56 -0
  11. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Tab/Text.php +49 -0
  12. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Tabs.php +27 -0
  13. app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Switcher.php +28 -0
  14. app/code/community/Campaignmonitor/Createsend/Block/AjaxButton/Abstract.php +109 -0
  15. app/code/community/Campaignmonitor/Createsend/Block/CreateExampleSegments.php +24 -0
  16. app/code/community/Campaignmonitor/Createsend/Block/Linkedattributes.php +66 -0
  17. app/code/community/Campaignmonitor/Createsend/Block/OauthPermissionRequest.php +69 -0
  18. app/code/community/Campaignmonitor/Createsend/Block/OauthRedirectUrl.php +49 -0
  19. app/code/community/Campaignmonitor/Createsend/Block/TestApi.php +24 -0
  20. app/code/community/Campaignmonitor/Createsend/Block/Wishlistattributes.php +66 -0
  21. app/code/community/Campaignmonitor/Createsend/Helper/Api.php +251 -0
  22. app/code/community/Campaignmonitor/Createsend/Helper/Config.php +204 -0
  23. app/code/community/Campaignmonitor/Createsend/Helper/Data.php +452 -0
  24. app/code/community/Campaignmonitor/Createsend/Model/Api.php +897 -0
  25. app/code/community/Campaignmonitor/Createsend/Model/Api/Observer.php +351 -0
  26. app/code/community/Campaignmonitor/Createsend/Model/Config/Api.php +36 -0
  27. app/code/community/Campaignmonitor/Createsend/Model/Config/Attributes/Abstract.php +110 -0
  28. app/code/community/Campaignmonitor/Createsend/Model/Config/AuthenticationMethod.php +45 -0
  29. app/code/community/Campaignmonitor/Createsend/Model/Config/Backend/Apikey.php +52 -0
  30. app/code/community/Campaignmonitor/Createsend/Model/Config/Backend/Listid.php +43 -0
  31. app/code/community/Campaignmonitor/Createsend/Model/Config/ClientSelection.php +27 -0
  32. app/code/community/Campaignmonitor/Createsend/Model/Config/ConflictResolutionMethod.php +45 -0
  33. app/code/community/Campaignmonitor/Createsend/Model/Config/CustomerAttributes.php +311 -0
  34. app/code/community/Campaignmonitor/Createsend/Model/Config/DefaultCustomFields.php +58 -0
  35. app/code/community/Campaignmonitor/Createsend/Model/Config/ExampleSegments.php +218 -0
  36. app/code/community/Campaignmonitor/Createsend/Model/Config/ListFlag.php +21 -0
  37. app/code/community/Campaignmonitor/Createsend/Model/Config/ListSelection.php +27 -0
  38. app/code/community/Campaignmonitor/Createsend/Model/Config/ProductAttributes.php +82 -0
  39. app/code/community/Campaignmonitor/Createsend/Model/Config/Scope.php +93 -0
  40. app/code/community/Campaignmonitor/Createsend/Model/Config/SubscriptionSources.php +45 -0
  41. app/code/community/Campaignmonitor/Createsend/Model/Cron.php +115 -0
  42. app/code/community/Campaignmonitor/Createsend/Model/Customer/Observer.php +545 -0
  43. app/code/community/Campaignmonitor/Createsend/Model/Email.php +38 -0
  44. app/code/community/Campaignmonitor/Createsend/Model/Email/Cron.php +182 -0
  45. app/code/community/Campaignmonitor/Createsend/Model/Email/Template.php +204 -0
  46. app/code/community/Campaignmonitor/Createsend/Model/List/Cron.php +274 -0
  47. app/code/community/Campaignmonitor/Createsend/Model/List/Initial/Cron.php +116 -0
  48. app/code/community/Campaignmonitor/Createsend/Model/Newsletter.php +113 -0
  49. app/code/community/Campaignmonitor/Createsend/Model/Newsletter/Observer.php +35 -0
  50. app/code/community/Campaignmonitor/Createsend/Model/Product/Observer.php +67 -0
  51. app/code/community/Campaignmonitor/Createsend/Model/Resource/Email.php +26 -0
  52. app/code/community/Campaignmonitor/Createsend/Model/Resource/Email/Collection.php +24 -0
  53. app/code/community/Campaignmonitor/Createsend/controllers/Adminhtml/Createsend/ApiController.php +146 -0
  54. app/code/community/Campaignmonitor/Createsend/controllers/Adminhtml/Createsend/EmailController.php +146 -0
  55. app/code/community/Campaignmonitor/Createsend/controllers/Adminhtml/Createsend/SegmentController.php +44 -0
  56. app/code/community/Campaignmonitor/Createsend/controllers/OauthController.php +148 -0
  57. app/code/community/Campaignmonitor/Createsend/controllers/UnsubscribeController.php +67 -0
  58. app/code/community/Campaignmonitor/Createsend/controllers/WebhooksController.php +125 -0
  59. app/code/community/Campaignmonitor/Createsend/etc/adminhtml.xml +61 -0
  60. app/code/community/Campaignmonitor/Createsend/etc/config.xml +292 -0
  61. app/code/community/Campaignmonitor/Createsend/etc/system.xml +300 -0
  62. app/code/community/Campaignmonitor/Createsend/sql/campaignmonitor_createsend_setup/install-1.0.0.php +139 -0
  63. app/design/adminhtml/default/default/layout/campaignmonitor/createsend.xml +134 -0
  64. app/design/adminhtml/default/default/template/campaignmonitor/createsend/ajax.phtml +42 -0
  65. app/design/adminhtml/default/default/template/campaignmonitor/createsend/apiclient.phtml +282 -0
  66. app/design/adminhtml/default/default/template/campaignmonitor/createsend/email/details.phtml +124 -0
  67. app/design/adminhtml/default/default/template/campaignmonitor/createsend/email/html.phtml +40 -0
  68. app/design/adminhtml/default/default/template/campaignmonitor/createsend/email/text.phtml +37 -0
  69. app/design/adminhtml/default/default/template/campaignmonitor/createsend/email/tracking.phtml +121 -0
  70. app/design/adminhtml/default/default/template/campaignmonitor/createsend/switcher.phtml +38 -0
  71. app/design/adminhtml/default/default/template/campaignmonitor/createsend/system/config/form/field/array_dropdown.phtml +198 -0
  72. app/etc/modules/Campaignmonitor_Createsend.xml +26 -0
  73. package.xml +18 -0
  74. shell/campaignmonitor_email.php +53 -0
  75. shell/campaignmonitor_list.php +52 -0
  76. shell/campaignmonitor_list_initial.php +52 -0
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Customer/Edit/Grid.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Adminhtml_Customer_Edit_Grid
19
+ extends Campaignmonitor_Createsend_Block_Adminhtml_Email_Grid
20
+ implements Mage_Adminhtml_Block_Widget_Tab_Interface
21
+ {
22
+ public function getTabLabel()
23
+ {
24
+ /** @noinspection PhpUndefinedMethodInspection */
25
+ return parent::getTabLabel();
26
+ }
27
+
28
+ public function getTabTitle()
29
+ {
30
+ /** @noinspection PhpUndefinedMethodInspection */
31
+ return parent::getTabTitle();
32
+ }
33
+
34
+ /**
35
+ * Can show tab in tabs
36
+ *
37
+ * @return boolean
38
+ */
39
+ public function canShowTab()
40
+ {
41
+ $customer = Mage::registry('current_customer');
42
+ return (bool)$customer->getId();
43
+ }
44
+
45
+ /**
46
+ * Tab is hidden
47
+ *
48
+ * @return boolean
49
+ */
50
+ public function isHidden()
51
+ {
52
+ return false;
53
+ }
54
+
55
+ /**
56
+ * Defines after which existing tab, this tab should be rendered.
57
+ *
58
+ * @return string
59
+ */
60
+ public function getAfter()
61
+ {
62
+ return 'tags';
63
+ }
64
+ }
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Adminhtml_Email extends Mage_Adminhtml_Block_Widget_Grid_Container
19
+ {
20
+ protected $_blockGroup = 'createsend';
21
+ protected $_controller = 'adminhtml_email';
22
+
23
+ public function __construct()
24
+ {
25
+ parent::__construct();
26
+ $this->_removeButton('add');
27
+ }
28
+
29
+ /**
30
+ * @return string
31
+ */
32
+ public function getHeaderText()
33
+ {
34
+ return $this->__('Campaign Monitor - Email Tracking');
35
+ }
36
+ }
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/Grid.php ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Adminhtml_Email_Grid extends Mage_Adminhtml_Block_Widget_Grid
19
+ {
20
+ public function __construct()
21
+ {
22
+ parent::__construct();
23
+ $this->setId('createsend_email_grid');
24
+ $this->setDefaultSort('sent_at');
25
+ $this->setDefaultDir('DESC');
26
+ $this->setSaveParametersInSession(true);
27
+ $this->setUseAjax(true);
28
+ }
29
+
30
+ protected function _prepareColumns()
31
+ {
32
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
33
+ $helper = Mage::helper('createsend');
34
+
35
+ $this->addColumn('sent_at',
36
+ array(
37
+ 'header' => $helper->__('Sent At'),
38
+ 'type' => 'datetime',
39
+ 'index' => 'sent_at'
40
+ )
41
+ );
42
+
43
+ /** @var Campaignmonitor_Createsend_Model_Email $email */
44
+ $email = Mage::getSingleton('createsend/email');
45
+
46
+ $this->addColumn("status",
47
+ array(
48
+ 'header' => $helper->__('Status'),
49
+ 'index' => 'status',
50
+ 'type' => 'options',
51
+ 'options' => array(
52
+ $email::STATUS_SENT => $helper->__($email::STATUS_SENT),
53
+ $email::STATUS_ACCEPTED => $helper->__($email::STATUS_ACCEPTED),
54
+ $email::STATUS_DELIVERED => $helper->__($email::STATUS_DELIVERED),
55
+ $email::STATUS_BOUNCED => $helper->__($email::STATUS_BOUNCED),
56
+ $email::STATUS_SPAM => $helper->__($email::STATUS_SPAM),
57
+ ),
58
+ )
59
+ );
60
+
61
+ $this->addColumn('subject',
62
+ array(
63
+ 'header' => $helper->__('Subject'),
64
+ 'index' => 'subject'
65
+ )
66
+ );
67
+
68
+ $this->addColumn('recipient',
69
+ array(
70
+ 'header' => $helper->__('Recipient'),
71
+ 'index' => 'recipient'
72
+ )
73
+ );
74
+
75
+ if ((Mage::getSingleton('customer/config_share')->isWebsiteScope())
76
+ && Mage::app()->getRequest()->getUserParam('id')) {
77
+
78
+ $this->addColumn('website',
79
+ array(
80
+ 'header' => $helper->__('Website'),
81
+ 'width' => '100px',
82
+ 'sortable' => false,
83
+ 'index' => 'website',
84
+ 'type' => 'options',
85
+ 'options' => Mage::getModel('core/website')->getCollection()->toOptionHash(),
86
+ )
87
+ );
88
+ }
89
+
90
+ if (Mage::getSingleton('admin/session')->isAllowed('adminhtml/createsend_email/view')) {
91
+ $request = Mage::app()->getRequest();
92
+ $customerId = $request->getUserParam('id');
93
+ if (!$customerId) {
94
+ $customerId = 0;
95
+ }
96
+
97
+ $this->addColumn('action',
98
+ array(
99
+ 'header' => $helper->__('Action'),
100
+ 'width' => '50px',
101
+ 'type' => 'action',
102
+ 'getter' => 'getEmailId',
103
+ 'actions' => array(
104
+ array(
105
+ 'caption' => $helper->__('View'),
106
+ 'url' => array(
107
+ 'base' => 'adminhtml/createsend_email/view',
108
+ 'params' => array(
109
+ 'customer_id' => $customerId
110
+ )
111
+ ),
112
+ 'field' => 'email_id',
113
+ 'data-column' => 'action',
114
+ )
115
+ ),
116
+ 'filter' => false,
117
+ 'sortable' => false,
118
+ 'is_system' => true,
119
+ )
120
+ );
121
+ }
122
+
123
+ return parent::_prepareColumns();
124
+ }
125
+
126
+ protected function _addColumnFilterToCollection($column)
127
+ {
128
+ if ($this->getCollection()) {
129
+ $cond = $column->getFilter()->getCondition();
130
+
131
+ if ($column->getId() == 'website') {
132
+ if (!empty($cond)) {
133
+ foreach ($cond as $websiteId) {
134
+ $website = Mage::app()->getWebsite($websiteId);
135
+
136
+ $collection = $this->getCollection();
137
+ $conn = $collection->getConnection();
138
+
139
+ $collection->getSelect()->where(
140
+ new Zend_Db_Expr(
141
+ $conn->quoteInto('(scope=?', 'websites')
142
+ . ' AND ' .
143
+ $conn->quoteInto('scope_id=?)', $websiteId)
144
+ . ' OR ' .
145
+ $conn->quoteInto('(scope=?', 'stores')
146
+ . ' AND ' .
147
+ $conn->quoteInto('scope_id in (?))', $website->getStoreIds())
148
+ )
149
+ );
150
+ }
151
+ }
152
+
153
+ return $this;
154
+ }
155
+ }
156
+
157
+ return parent::_addColumnFilterToCollection($column);
158
+ }
159
+
160
+ protected function _prepareCollection()
161
+ {
162
+ /** @var Campaignmonitor_Createsend_Model_Resource_Email_Collection $collection */
163
+ $collection = Mage::getModel('createsend/email')->getCollection();
164
+
165
+ $request = Mage::app()->getRequest();
166
+ $website = $request->getUserParam('website');
167
+ $store = $request->getUserParam('store');
168
+
169
+ if ($customerId = $request->getUserParam('id')) {
170
+ if ($customer = Mage::getSingleton('customer/customer')->load($customerId)) {
171
+ $collection = $collection->addFieldToFilter(
172
+ 'recipient',
173
+ array(
174
+ 'like' => '%' . $customer->getEmail() . '%'
175
+ )
176
+ );
177
+ }
178
+ } else {
179
+ list($scope, $scopeId) = Mage::getSingleton('createsend/config_scope')->_getScope($website, $store);
180
+ $collection->addFieldToFilter('scope', $scope)->addFieldToFilter('scope_id', $scopeId);
181
+ }
182
+
183
+ $this->setCollection($collection);
184
+
185
+ return parent::_prepareCollection();
186
+ }
187
+
188
+ public function getGridUrl()
189
+ {
190
+ return $this->getUrl('adminhtml/createsend_email/grid', array('_current'=>true));
191
+ }
192
+ }
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Adminhtml_Email_View extends Mage_Adminhtml_Block_Widget_Form_Container
19
+ {
20
+ protected $_objectId = 'id';
21
+ protected $_blockGroup = 'createsend';
22
+ protected $_controller = 'adminhtml_email';
23
+ protected $_mode = 'view';
24
+
25
+ const HEADER_MESSAGE_ID = 'Message ID: %s';
26
+
27
+ public function __construct()
28
+ {
29
+ parent::__construct();
30
+
31
+ if ($this->isResendable()) {
32
+ $this->_updateButton('save', 'label', Mage::helper('createsend')->__('Resend'));
33
+ } else {
34
+ $this->_removeButton('save');
35
+ }
36
+
37
+ $this->_removeButton('reset');
38
+ }
39
+
40
+ public function getHeaderText()
41
+ {
42
+ $message = $this->getMessage();
43
+
44
+ return sprintf(Mage::helper('createsend')->__(self::HEADER_MESSAGE_ID), htmlentities($message['MessageID']));
45
+ }
46
+
47
+ public function getBackUrl()
48
+ {
49
+ $request = Mage::app()->getRequest();
50
+ $customerId = $request->getUserParam('customer_id');
51
+ if ($customerId) {
52
+ return $this->getUrl(
53
+ 'adminhtml/customer/edit',
54
+ array(
55
+ 'id' => $customerId,
56
+ '_query' => array('active_tab' => 'createsend_email_grid')
57
+ )
58
+ );
59
+ } else {
60
+ return $this->getUrl('adminhtml/createsend_email/index');
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Returns the email message object from registry. Message is of the form of an
66
+ * array as returned by Campaign Monitor API.
67
+ *
68
+ * @link https://www.campaignmonitor.com/api/transactional/#message_details
69
+ *
70
+ * @return array
71
+ */
72
+ public function getMessage()
73
+ {
74
+ return Mage::registry('createsend_email');
75
+ }
76
+
77
+ /**
78
+ * Returns true if the message can be resent.
79
+ *
80
+ * @return bool
81
+ */
82
+ public function isResendable()
83
+ {
84
+ $message = $this->getMessage();
85
+
86
+ $key = 'CanBeResent';
87
+ if (array_key_exists($key, $message)) {
88
+ if (is_bool($message[$key])) {
89
+ return $message[$key];
90
+ } else {
91
+ return (mb_strtoupper(trim($message[$key])) === mb_strtoupper("true")) ? TRUE : FALSE;
92
+ }
93
+ } else {
94
+ // Cannot be resent by default
95
+ return false;
96
+ }
97
+ }
98
+ }
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Abstract.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ abstract class Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Abstract
19
+ extends Mage_Adminhtml_Block_Widget
20
+ {
21
+ /**
22
+ * Retrieve email details, an array returned by Campaign Monitor API
23
+ * @link https://www.campaignmonitor.com/api/transactional/#message_details
24
+ *
25
+ * @return array
26
+ */
27
+ public function getEmail()
28
+ {
29
+ return Mage::registry('createsend_email');
30
+ }
31
+ }
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Form.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Form extends Mage_Adminhtml_Block_Widget_Form
19
+ {
20
+ /**
21
+ * @return Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Form
22
+ */
23
+ protected function _prepareForm()
24
+ {
25
+ $form = new Varien_Data_Form(
26
+ array(
27
+ 'id' => 'createsend_email_view_form',
28
+ 'name' => 'editForm',
29
+ 'action' => $this->getUrl('*/*/resend', array('email_id' => $this->getRequest()->getParam('email_id'))),
30
+ 'method' => 'get',
31
+ )
32
+ );
33
+
34
+ $form->setUseContainer(true);
35
+ $this->setForm($form);
36
+ return parent::_prepareForm();
37
+ }
38
+ }
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Tab/Clicks.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Tab_Clicks
19
+ extends Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Abstract
20
+ implements Mage_Adminhtml_Block_Widget_Tab_Interface
21
+ {
22
+ const TRACK_INDEX = 'Clicks';
23
+
24
+ public function getTrackIndex()
25
+ {
26
+ return self::TRACK_INDEX;
27
+ }
28
+
29
+ public function getTabLabel()
30
+ {
31
+ /** @noinspection PhpUndefinedMethodInspection */
32
+ return parent::getTabLabel();
33
+ }
34
+
35
+ public function getTabTitle()
36
+ {
37
+ /** @noinspection PhpUndefinedMethodInspection */
38
+ return parent::getTabTitle();
39
+ }
40
+
41
+ public function canShowTab()
42
+ {
43
+ return true;
44
+ }
45
+
46
+ public function isHidden()
47
+ {
48
+ /** @var array $email */
49
+ $email = $this->getEmail();
50
+ if (empty($email['TotalClicks'])) {
51
+ return true;
52
+ } else {
53
+ return false;
54
+ }
55
+ }
56
+ }
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Tab/Details.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Tab_Details
19
+ extends Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Abstract
20
+ implements Mage_Adminhtml_Block_Widget_Tab_Interface
21
+ {
22
+ public function getTabLabel()
23
+ {
24
+ /** @noinspection PhpUndefinedMethodInspection */
25
+ return parent::getTabLabel();
26
+ }
27
+
28
+ public function getTabTitle()
29
+ {
30
+ /** @noinspection PhpUndefinedMethodInspection */
31
+ return parent::getTabTitle();
32
+ }
33
+
34
+ public function canShowTab()
35
+ {
36
+ return true;
37
+ }
38
+
39
+ public function isHidden()
40
+ {
41
+ return false;
42
+ }
43
+ }
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Tab/Html.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Tab_Html
19
+ extends Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Abstract
20
+ implements Mage_Adminhtml_Block_Widget_Tab_Interface
21
+ {
22
+ public function getTabLabel()
23
+ {
24
+ /** @noinspection PhpUndefinedMethodInspection */
25
+ return parent::getTabLabel();
26
+ }
27
+
28
+ public function getTabTitle()
29
+ {
30
+ /** @noinspection PhpUndefinedMethodInspection */
31
+ return parent::getTabTitle();
32
+ }
33
+
34
+ public function canShowTab()
35
+ {
36
+ return true;
37
+ }
38
+
39
+ public function isHidden()
40
+ {
41
+ /** @var array $email */
42
+ $email = $this->getEmail();
43
+ if (empty($email['Message']['Body']['Html'])) {
44
+ return true;
45
+ } else {
46
+ return false;
47
+ }
48
+ }
49
+
50
+ /**
51
+ * Returns the url for viewing the Email Body given the Email ID (table primary key)
52
+ *
53
+ * @param int $emailId
54
+ * @return string
55
+ */
56
+ public function getEmailViewUrl($emailId)
57
+ {
58
+ return $this->getUrl(
59
+ 'adminhtml/createsend_email/view',
60
+ array(
61
+ '_query' => array(
62
+ 'email_id' => $emailId,
63
+ 'display' => 'body'
64
+ )
65
+ )
66
+ );
67
+ }
68
+ }
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Tab/Opens.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Tab_Opens
19
+ extends Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Abstract
20
+ implements Mage_Adminhtml_Block_Widget_Tab_Interface
21
+ {
22
+ const TRACK_INDEX = 'Opens';
23
+
24
+ public function getTrackIndex()
25
+ {
26
+ return self::TRACK_INDEX;
27
+ }
28
+
29
+ public function getTabLabel()
30
+ {
31
+ /** @noinspection PhpUndefinedMethodInspection */
32
+ return parent::getTabLabel();
33
+ }
34
+
35
+ public function getTabTitle()
36
+ {
37
+ /** @noinspection PhpUndefinedMethodInspection */
38
+ return parent::getTabTitle();
39
+ }
40
+
41
+ public function canShowTab()
42
+ {
43
+ return true;
44
+ }
45
+
46
+ public function isHidden()
47
+ {
48
+ /** @var array $email */
49
+ $email = $this->getEmail();
50
+ if (empty($email['TotalOpens'])) {
51
+ return true;
52
+ } else {
53
+ return false;
54
+ }
55
+ }
56
+ }
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Tab/Text.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Tab_Text
19
+ extends Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Abstract
20
+ implements Mage_Adminhtml_Block_Widget_Tab_Interface
21
+ {
22
+ public function getTabLabel()
23
+ {
24
+ /** @noinspection PhpUndefinedMethodInspection */
25
+ return parent::getTabLabel();
26
+ }
27
+
28
+ public function getTabTitle()
29
+ {
30
+ /** @noinspection PhpUndefinedMethodInspection */
31
+ return parent::getTabTitle();
32
+ }
33
+
34
+ public function canShowTab()
35
+ {
36
+ return true;
37
+ }
38
+
39
+ public function isHidden()
40
+ {
41
+ /** @var array $email */
42
+ $email = $this->getEmail();
43
+ if (empty($email['Message']['Body']['Text'])) {
44
+ return true;
45
+ } else {
46
+ return false;
47
+ }
48
+ }
49
+ }
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Email/View/Tabs.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Tabs extends Mage_Adminhtml_Block_Widget_Tabs
19
+ {
20
+ public function __construct()
21
+ {
22
+ parent::__construct();
23
+ $this->setId('createsend_email_tabs');
24
+ $this->setDestElementId('createsend_email_view_form');
25
+ $this->setTitle(Mage::helper('createsend')->__('View Email'));
26
+ }
27
+ }
app/code/community/Campaignmonitor/Createsend/Block/Adminhtml/Switcher.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Extends the System Config Switcher to remove unwanted text.
20
+ */
21
+ class Campaignmonitor_Createsend_Block_Adminhtml_Switcher extends Mage_Adminhtml_Block_System_Config_Switcher
22
+ {
23
+ protected function _prepareLayout()
24
+ {
25
+ $this->setTemplate('campaignmonitor/createsend/switcher.phtml');
26
+ return Mage_Adminhtml_Block_Template::_prepareLayout();
27
+ }
28
+ }
app/code/community/Campaignmonitor/Createsend/Block/AjaxButton/Abstract.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ abstract class Campaignmonitor_Createsend_Block_AjaxButton_Abstract extends Mage_Adminhtml_Block_System_Config_Form_Field
19
+ {
20
+ /** @var string */
21
+ protected $_urlPath;
22
+
23
+ /** @var string */
24
+ protected $_ajaxUrl;
25
+
26
+ /** @var string */
27
+ protected $_buttonHtml;
28
+
29
+ protected function _construct()
30
+ {
31
+ parent::_construct();
32
+ $this->setTemplate('campaignmonitor/createsend/ajax.phtml');
33
+ }
34
+
35
+ /**
36
+ * Return element html
37
+ *
38
+ * @param Varien_Data_Form_Element_Abstract $element
39
+ * @return string
40
+ */
41
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
42
+ {
43
+ /** @var Mage_Core_Model_Config_Data $configData */
44
+ $configData = Mage::getSingleton('adminhtml/config_data');
45
+
46
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
47
+ $scopeModel = Mage::getSingleton('createsend/config_scope');
48
+ list($scope, $scopeId) = $scopeModel->_getScope($configData->getWebsite(), $configData->getStore());
49
+
50
+ $this->_ajaxUrl = $this->getUrl(
51
+ $this->_urlPath,
52
+ array(
53
+ '_query' => array(
54
+ 'scope' => $scope,
55
+ 'scopeId' => $scopeId,
56
+ )
57
+ )
58
+ );
59
+
60
+ $this->setElement($element);
61
+
62
+ $button = $this->getLayout()->createBlock('adminhtml/widget_button')
63
+ ->setType('button')
64
+ ->setLabel($element->getLabel())
65
+ ->setOnClick('javascript:' . $this->getAjaxFunction(). '(); return false;')
66
+ ->setId($element->getId());
67
+
68
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
69
+ $helper = Mage::helper("createsend");
70
+
71
+ if (!$helper->isCompleteConfig($scope, $scopeId)) {
72
+ $button->setDisabled('disabled');
73
+ }
74
+
75
+ $this->_buttonHtml = $button->toHtml();
76
+
77
+ return $this->_toHtml();
78
+ }
79
+
80
+ /**
81
+ * Returns the Javascript function name for performing the Ajax call.
82
+ *
83
+ * @return string
84
+ */
85
+ public function getAjaxFunction()
86
+ {
87
+ return $this->getElement()->getId() . 'Ajax';
88
+ }
89
+
90
+ /**
91
+ * Returns the AJAX URL to test the API
92
+ *
93
+ * @return string
94
+ */
95
+ public function getAjaxUrl()
96
+ {
97
+ return $this->_ajaxUrl;
98
+ }
99
+
100
+ /**
101
+ * Returns the HTML for the custom API Test button
102
+ *
103
+ * @return string
104
+ */
105
+ public function getButtonHtml()
106
+ {
107
+ return $this->_buttonHtml;
108
+ }
109
+ }
app/code/community/Campaignmonitor/Createsend/Block/CreateExampleSegments.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Campaign Monitor Create Example Segments Button
20
+ */
21
+ class Campaignmonitor_Createsend_Block_CreateExampleSegments extends Campaignmonitor_Createsend_Block_AjaxButton_Abstract
22
+ {
23
+ protected $_urlPath = 'adminhtml/createsend_segment/createExamples';
24
+ }
app/code/community/Campaignmonitor/Createsend/Block/Linkedattributes.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Linkedattributes extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
19
+ {
20
+ protected $magentoOptions;
21
+
22
+ public function __construct()
23
+ {
24
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
25
+ $helper = Mage::helper("createsend");
26
+
27
+ $this->addColumn('magento', array(
28
+ 'label' => $helper->__('Magento customer attribute'),
29
+ 'size' => 28,
30
+ ));
31
+ $this->_addAfter = false;
32
+ $this->_addButtonLabel = $helper->__('Add linked attribute');
33
+
34
+ parent::__construct();
35
+ $this->setTemplate('campaignmonitor/createsend/system/config/form/field/array_dropdown.phtml');
36
+
37
+ $options = Mage::getSingleton('createsend/config_customerAttributes')->toOptionArray();
38
+ $this->magentoOptions = array();
39
+ foreach ($options as $option) {
40
+ $this->magentoOptions[$option['value']] = $option['label'];
41
+ }
42
+
43
+ asort($this->magentoOptions);
44
+ }
45
+
46
+ protected function _renderCellTemplate($columnName)
47
+ {
48
+ if (empty($this->_columns[$columnName])) {
49
+ throw new Exception('Wrong column name specified.');
50
+ }
51
+ $column = $this->_columns[$columnName];
52
+ $inputName = $this->getElement()->getName() . '[#{_id}][' . $columnName . ']';
53
+
54
+ if ($columnName == 'magento') {
55
+ $rendered = '<select name="'.$inputName.'">';
56
+ foreach ($this->magentoOptions as $att => $name) {
57
+ $rendered .= '<option value="'.$att.'">'.$name.'</option>';
58
+ }
59
+ $rendered .= '</select>';
60
+ } else {
61
+ return '<input type="text" name="' . $inputName . '" value="#{' . $columnName . '}" ' . ($column['size'] ? 'size="' . $column['size'] . '"' : '') . '/>';
62
+ }
63
+
64
+ return $rendered;
65
+ }
66
+ }
app/code/community/Campaignmonitor/Createsend/Block/OauthPermissionRequest.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Campaign Monitor OAuth Permission Request Button
20
+ *
21
+ */
22
+
23
+ class Campaignmonitor_Createsend_Block_OauthPermissionRequest extends Mage_Adminhtml_Block_System_Config_Form_Field
24
+ {
25
+ /**
26
+ * Return element html
27
+ *
28
+ * @param Varien_Data_Form_Element_Abstract $element
29
+ * @return string
30
+ */
31
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
32
+ {
33
+ /** @var Mage_Core_Model_Config_Data $configData */
34
+ $configData = Mage::getSingleton('adminhtml/config_data');
35
+ list($scope, $scopeId) = Mage::getSingleton('createsend/config_scope')
36
+ ->_getScope($configData->getWebsite(), $configData->getStore());
37
+
38
+ // Redirect admin to Campaign Monitor Application Approval Page
39
+
40
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
41
+ $api = Mage::getModel('createsend/api');
42
+ $url = $api->getOauthPermissionRequestUrl($scope, $scopeId);
43
+
44
+ $this->setElement($element);
45
+
46
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
47
+ $helper = Mage::helper("createsend");
48
+
49
+ $button = $this->getLayout()->createBlock('adminhtml/widget_button')
50
+ ->setType('button')
51
+ ->setLabel($element->getLabel())
52
+ //->setOnClick("setLocation('$url')")
53
+ ->setOnClick("popWin('$url', '_blank')")
54
+ ->setId($element->getId());
55
+
56
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
57
+ $scopeModel = Mage::getModel('createsend/config_scope');
58
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
59
+
60
+ $clientId = $helper->getOAuthClientId($storeId);
61
+ $clientSecret = $helper->getOAuthClientSecret($storeId);
62
+ if (empty($clientId) || empty($clientSecret)) {
63
+ // Hide if OAuth Client ID or Client Secret is blank
64
+ $button->setDisabled('disabled');
65
+ }
66
+
67
+ return $button->toHtml();
68
+ }
69
+ }
app/code/community/Campaignmonitor/Createsend/Block/OauthRedirectUrl.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Campaign Monitor OAuth Redirect URL information.
20
+ *
21
+ */
22
+ class Campaignmonitor_Createsend_Block_OauthRedirectUrl extends Mage_Adminhtml_Block_System_Config_Form_Field
23
+ {
24
+ /**
25
+ * Return element html
26
+ *
27
+ * @param Varien_Data_Form_Element_Abstract $element
28
+ * @return string
29
+ */
30
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
31
+ {
32
+ /** @var Mage_Core_Model_Config_Data $configData */
33
+ $configData = Mage::getSingleton('adminhtml/config_data');
34
+ list($scope, $scopeId) = Mage::getSingleton('createsend/config_scope')
35
+ ->_getScope($configData->getWebsite(), $configData->getStore());
36
+
37
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
38
+ $api = Mage::getModel('createsend/api');
39
+ $url = $api->getOauthRedirectUri($scope, $scopeId);
40
+
41
+ $element->setValue($url);
42
+
43
+ // Add a hidden input field to get <depends> working
44
+ $html = $element->getAfterElementHtml();
45
+ $element->setAfterElementHtml($html . sprintf('<input id="%s" type="hidden" value=""/>', $element->getId()));
46
+
47
+ return parent::_getElementHtml($element);
48
+ }
49
+ }
app/code/community/Campaignmonitor/Createsend/Block/TestApi.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Campaign Monitor Test API Button
20
+ */
21
+ class Campaignmonitor_Createsend_Block_TestApi extends Campaignmonitor_Createsend_Block_AjaxButton_Abstract
22
+ {
23
+ protected $_urlPath = 'adminhtml/createsend_api/test';
24
+ }
app/code/community/Campaignmonitor/Createsend/Block/Wishlistattributes.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Block_Wishlistattributes extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
19
+ {
20
+ protected $magentoOptions;
21
+
22
+ public function __construct()
23
+ {
24
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
25
+ $helper = Mage::helper("createsend");
26
+
27
+ $this->addColumn('magento', array(
28
+ 'label' => $helper->__('Product attribute'),
29
+ 'size' => 28,
30
+ ));
31
+ $this->_addAfter = false;
32
+ $this->_addButtonLabel = $helper->__('Add product attribute');
33
+
34
+ parent::__construct();
35
+ $this->setTemplate('campaignmonitor/createsend/system/config/form/field/array_dropdown.phtml');
36
+
37
+ $options = Mage::getSingleton('createsend/config_productAttributes')->toOptionArray();
38
+ $this->magentoOptions = array();
39
+ foreach ($options as $option) {
40
+ $this->magentoOptions[$option['value']] = $option['label'];
41
+ }
42
+
43
+ asort($this->magentoOptions);
44
+ }
45
+
46
+ protected function _renderCellTemplate($columnName)
47
+ {
48
+ if (empty($this->_columns[$columnName])) {
49
+ throw new Exception('Wrong column name specified.');
50
+ }
51
+ $column = $this->_columns[$columnName];
52
+ $inputName = $this->getElement()->getName() . '[#{_id}][' . $columnName . ']';
53
+
54
+ if ($columnName == 'magento') {
55
+ $rendered = '<select name="'.$inputName.'">';
56
+ foreach ($this->magentoOptions as $att => $name) {
57
+ $rendered .= '<option value="'.$att.'">'.$name.'</option>';
58
+ }
59
+ $rendered .= '</select>';
60
+ } else {
61
+ return '<input type="text" name="' . $inputName . '" value="#{' . $columnName . '}" ' . ($column['size'] ? 'size="' . $column['size'] . '"' : '') . '/>';
62
+ }
63
+
64
+ return $rendered;
65
+ }
66
+ }
app/code/community/Campaignmonitor/Createsend/Helper/Api.php ADDED
@@ -0,0 +1,251 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Helper_Api extends Mage_Core_Helper_Abstract
19
+ {
20
+ const MAX_CM_SUBSCRIBER_IMPORT = 1000;
21
+ const LABEL_SELECT_CLIENT = 'Select Client...';
22
+ const LABEL_CREATE_NEW_LIST = 'Create a new list in Campaign Monitor';
23
+ const LABEL_ENTER_YOUR_API_KEY = 'Enter your API Key';
24
+ const ID_CREATE_NEW_LIST = 'NEW_LIST';
25
+
26
+ /**
27
+ * Gets all the Campaign Monitor clients for the given scope/scopeId for use in an HTML select.
28
+ * The first option will be a 'Select Client...' prompt.
29
+ *
30
+ * On API Error, returns a single element array with key 'value' => 'error'
31
+ *
32
+ * @param string $scope
33
+ * @param int $scopeId
34
+ * @return array|null
35
+ */
36
+ public function getClients($scope, $scopeId)
37
+ {
38
+ /** @var $api Campaignmonitor_Createsend_Model_Api */
39
+ $api = Mage::getModel('createsend/api');
40
+
41
+ $reply = $api->call(
42
+ Zend_Http_Client::GET,
43
+ "clients",
44
+ array(),
45
+ array(),
46
+ $scope,
47
+ $scopeId
48
+ );
49
+
50
+ $clients = array();
51
+ if ($reply['success'] === false) {
52
+ Mage::helper('createsend')->log($reply);
53
+
54
+ $clients[] = array(
55
+ 'value' => 'error',
56
+ 'label' => self::LABEL_ENTER_YOUR_API_KEY,
57
+ 'message' => sprintf($api::ERR_API_REQUEST, $reply['data']['Message'])
58
+ );
59
+ } else {
60
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
61
+ $helper = Mage::helper('createsend');
62
+
63
+ $clients[] = array(
64
+ 'value' => '',
65
+ 'label' => $helper->__(self::LABEL_SELECT_CLIENT)
66
+ );
67
+
68
+ foreach ($reply['data'] as $client) {
69
+ $clients[] = array(
70
+ 'value' => $client['ClientID'],
71
+ 'label' => $client['Name']
72
+ );
73
+ }
74
+ }
75
+
76
+ return $clients;
77
+ }
78
+
79
+ /**
80
+ * Gets all the Campaign Monitor subscriber lists for the given clientId
81
+ * using credentials from given scope/scopeId for use in an HTML select.
82
+ * The last option will be a 'Create a new list' option
83
+ *
84
+ * On API Error, returns a single element array with key 'value' => 'error'
85
+ *
86
+ * @param string $clientId
87
+ * @param string $scope
88
+ * @param int $scopeId
89
+ * @return array|null
90
+ */
91
+ public function getLists($clientId, $scope, $scopeId)
92
+ {
93
+ /** @var $api Campaignmonitor_Createsend_Model_Api */
94
+ $api = Mage::getModel('createsend/api');
95
+
96
+ $reply = $api->call(
97
+ Zend_Http_Client::GET,
98
+ "clients/${clientId}/lists",
99
+ array(),
100
+ array(),
101
+ $scope,
102
+ $scopeId
103
+ );
104
+
105
+ $lists = array();
106
+ if ($reply['success'] === false) {
107
+ Mage::helper('createsend')->log($reply);
108
+
109
+ $lists[] = array(
110
+ 'value' => 'error',
111
+ 'label' => self::LABEL_ENTER_YOUR_API_KEY,
112
+ 'message' => sprintf($api::ERR_API_REQUEST, $reply['data']['Message'])
113
+ );
114
+ } else {
115
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
116
+ $helper = Mage::helper('createsend');
117
+
118
+ foreach ($reply['data'] as $client) {
119
+ $lists[] = array(
120
+ 'value' => $client['ListID'],
121
+ 'label' => $client['Name']
122
+ );
123
+ }
124
+
125
+ $lists[] = array(
126
+ 'value' => self::ID_CREATE_NEW_LIST,
127
+ 'label' => $helper->__(self::LABEL_CREATE_NEW_LIST)
128
+ );
129
+ }
130
+
131
+ return $lists;
132
+ }
133
+
134
+ /**
135
+ * Tests the API Key by getting the list of clients.
136
+ *
137
+ * @param string $scope
138
+ * @param int $scopeId
139
+ * @return array|null
140
+ */
141
+ public function testApiKey($scope, $scopeId)
142
+ {
143
+ /** @var $api Campaignmonitor_Createsend_Model_Api */
144
+ $api = Mage::getModel('createsend/api');
145
+
146
+ $reply = $api->call(
147
+ Zend_Http_Client::GET,
148
+ "clients",
149
+ array(),
150
+ array(),
151
+ $scope,
152
+ $scopeId
153
+ );
154
+
155
+ return $reply;
156
+ }
157
+
158
+ /**
159
+ * Lists all Magento subscribers and returns the list in an array compatible with
160
+ * the Campaign Monitor API.
161
+ *
162
+ * @param int $storeId
163
+ * @return array
164
+ */
165
+ public function getSubscribers($storeId)
166
+ {
167
+ $listData = array();
168
+
169
+ /** @var Mage_Newsletter_Model_Subscriber $subscribers */
170
+ $subscribers = Mage::getModel('newsletter/subscriber');
171
+
172
+ $collection = $subscribers->getCollection()
173
+ ->addFieldToFilter('store_id', $storeId)
174
+ ->addFieldToFilter('subscriber_status', Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED);
175
+
176
+ /** @var Mage_Newsletter_Model_Subscriber $subscriber */
177
+ foreach ($collection as $subscriber) {
178
+ $email = $subscriber->getSubscriberEmail();
179
+
180
+ $subscriberData['EmailAddress'] = $email;
181
+
182
+ $websiteId = Mage::app()->getStore($subscriber->getStoreId())->getWebsiteId();
183
+
184
+ /* @var Mage_Customer_Model_Customer $customer */
185
+ $customer = Mage::getModel("customer/customer")
186
+ ->setWebsiteId($websiteId)
187
+ ->loadByEmail($email);
188
+
189
+ if ($customer->getId()) {
190
+ $subscriberData['Name'] = $customer->getName();
191
+ }
192
+
193
+ $subscriberData['CustomFields'] =
194
+ Campaignmonitor_Createsend_Model_Customer_Observer::generateCustomFields($customer);
195
+
196
+ $listData[] = $subscriberData;
197
+ }
198
+
199
+ return $listData;
200
+ }
201
+
202
+ /**
203
+ * Performs an initial full subscriber sync from Magento to Campaign Monitor
204
+ * for a particular store. The check for already synchronized list should be
205
+ * done by the caller.
206
+ *
207
+ * @param $storeId
208
+ * @return array|bool|null
209
+ */
210
+ function performFullSync($storeId)
211
+ {
212
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
213
+ $helper = Mage::helper('createsend');
214
+
215
+ $listId = $helper->getListId($storeId);
216
+ $scope = 'stores';
217
+ $scopeId = $storeId;
218
+
219
+ /** @var Campaignmonitor_Createsend_Helper_Api $apiHelper */
220
+ $apiHelper = Mage::helper('createsend/api');
221
+
222
+ $listData = $apiHelper->getSubscribers($storeId);
223
+
224
+ /** @var $api Campaignmonitor_Createsend_Model_Api */
225
+ $api = Mage::getModel('createsend/api');
226
+
227
+ $index = 0;
228
+ do {
229
+ $partialData = array_slice($listData, $index * self::MAX_CM_SUBSCRIBER_IMPORT, self::MAX_CM_SUBSCRIBER_IMPORT);
230
+ $reply = $api->call(
231
+ Zend_Http_Client::POST,
232
+ "subscribers/{$listId}/import",
233
+ array(
234
+ 'Subscribers' => $partialData,
235
+ 'Resubscribe' => true,
236
+ 'QueueSubscriptionBasedAutoResponders' => false,
237
+ 'RestartSubscriptionBasedAutoresponders' => true
238
+ ),
239
+ array(),
240
+ $scope,
241
+ $scopeId
242
+ );
243
+ } while (
244
+ $reply['success'] !== false
245
+ &&
246
+ count($listData) > (($index++ * self::MAX_CM_SUBSCRIBER_IMPORT) + self::MAX_CM_SUBSCRIBER_IMPORT)
247
+ );
248
+
249
+ return $reply;
250
+ }
251
+ }
app/code/community/Campaignmonitor/Createsend/Helper/Config.php ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Helper_Config extends Mage_Core_Helper_Abstract
19
+ {
20
+ const FLAG_STATUS_NEW = 'new';
21
+ const FLAG_STATUS_PROCESSING = 'processing';
22
+ const FLAG_STATUS_DONE = 'done';
23
+
24
+ const FLAG_PROCESS_RUNNING = 'running';
25
+ const FLAG_PROCESS_STOPPED = 'stopped';
26
+
27
+ const INDEX_INITIAL_SYNC = 'initialSync';
28
+ const INDEX_CUSTOM_FIELDS = 'customFields';
29
+ const INDEX_EXAMPLE_SEGMENTS = 'exampleSegments';
30
+
31
+ /**
32
+ * Adds the default customer and product attributes to the magento configuration setting for this scope.
33
+ * Returns the number of attributes added.
34
+ *
35
+ * @param string $scope
36
+ * @param int $scopeId
37
+ * @return int
38
+ */
39
+ function createDefaultCustomFields($scope, $scopeId)
40
+ {
41
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
42
+ $helper = Mage::helper('createsend');
43
+
44
+ /** @var Campaignmonitor_Createsend_Model_Config_DefaultCustomFields $defaultSource */
45
+ $defaultSource = Mage::getSingleton('createsend/config_defaultCustomFields');
46
+
47
+ $linkedAttributes = @unserialize(
48
+ $helper->getScopedConfig(
49
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_M_TO_CM_ATTRIBUTES,
50
+ $scope,
51
+ $scopeId
52
+ )
53
+ );
54
+ $defaultCustomerAttributes = $defaultSource->getDefaultCustomerAttributes();
55
+ $newLinkedAttributes = $this->addDefaultAttributes($linkedAttributes, $defaultCustomerAttributes);
56
+ Mage::getConfig()->saveConfig(
57
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_M_TO_CM_ATTRIBUTES,
58
+ @serialize($newLinkedAttributes),
59
+ $scope,
60
+ $scopeId
61
+ );
62
+
63
+ $productAttributes = @unserialize(
64
+ $helper->getScopedConfig(
65
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_WISHLIST_PRODUCT_ATTRIBUTES,
66
+ $scope,
67
+ $scopeId
68
+ )
69
+ );
70
+ $defaultProductAttributes = $defaultSource->getDefaultProductAttributes();
71
+ $newProductAttributes = $this->addDefaultAttributes($productAttributes, $defaultProductAttributes);
72
+ Mage::getConfig()->saveConfig(
73
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_WISHLIST_PRODUCT_ATTRIBUTES,
74
+ @serialize($newProductAttributes),
75
+ $scope,
76
+ $scopeId
77
+ );
78
+
79
+ $oldCount = count($linkedAttributes) + count($productAttributes);
80
+ $newCount = count($newLinkedAttributes) + count($newProductAttributes);
81
+
82
+ return ($newCount - $oldCount);
83
+ }
84
+
85
+ /**
86
+ * Returns the duplicate custom attributes (if any).
87
+ * Returns an empty array if no duplicate custom attributes found.
88
+ *
89
+ * @param string $configPath The system configuration path for the attributes
90
+ * @param string $scope
91
+ * @param int $scopeId
92
+ * @return array
93
+ */
94
+ function getDuplicateAttributes($configPath, $scope, $scopeId)
95
+ {
96
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
97
+ $helper = Mage::helper('createsend');
98
+
99
+ $duplicateAttributes = array();
100
+
101
+ $customerAttributes = @unserialize(
102
+ $helper->getScopedConfig(
103
+ $configPath,
104
+ $scope,
105
+ $scopeId
106
+ )
107
+ );
108
+
109
+ $usedAttributes = array();
110
+ foreach ($customerAttributes as $attr) {
111
+ $value = $attr['magento'];
112
+
113
+ if (in_array($value, $usedAttributes)) {
114
+ // Already used, add it to the duplicate list
115
+ $duplicateAttributes[] = $value;
116
+ } else {
117
+ $usedAttributes[] = $value;
118
+ }
119
+ }
120
+
121
+ return $duplicateAttributes;
122
+ }
123
+
124
+ /**
125
+ * Adds values from $defaultAttributes into $attributes if not yet in array
126
+ *
127
+ * @param array $attributes
128
+ * @param array $defaultAttributes
129
+ * @return array
130
+ */
131
+ protected function addDefaultAttributes($attributes, $defaultAttributes)
132
+ {
133
+ if (!is_array($attributes)) {
134
+ $attributes = array();
135
+ }
136
+
137
+ foreach ($defaultAttributes as $attr) {
138
+ $addAttribute = array('magento' => $attr);
139
+ if (in_array($addAttribute, $attributes) === FALSE) {
140
+ $attributes[] = $addAttribute;
141
+ }
142
+ }
143
+
144
+ return $attributes;
145
+ }
146
+
147
+ /**
148
+ * Loads the flag given the flag class.
149
+ *
150
+ * @param string $flagClass
151
+ * @return Mage_Core_Model_Flag
152
+ */
153
+ protected function loadFlag($flagClass)
154
+ {
155
+ /** @var Mage_Core_Model_Flag $flagModel */
156
+ $flagModel = Mage::getModel($flagClass);
157
+ $flagModel->loadSelf();
158
+
159
+ return $flagModel;
160
+ }
161
+
162
+ /**
163
+ * Adds data to the flag with an index key. Existing data for the key will be overwritten.
164
+ * Data for other keys will remain untouched.
165
+ *
166
+ * @param string $flagClass
167
+ * @param string $key
168
+ * @param string $listData
169
+ * @throws Exception
170
+ */
171
+ public function addFlagData($flagClass, $key, $listData)
172
+ {
173
+ $flagModel = $this->loadFlag($flagClass);
174
+
175
+ /** @var array $flagData */
176
+ $flagData = $flagModel->getFlagData();
177
+ if ($flagData === null) {
178
+ $flagData = array();
179
+ }
180
+ $flagData[$key] = $listData;
181
+
182
+ $flagModel->setFlagData($flagData)->save();
183
+ }
184
+
185
+ /**
186
+ * Retrieves flag data given the flag class and the index key.
187
+ *
188
+ * @param string $flagClass
189
+ * @param string $key
190
+ * @return mixed
191
+ */
192
+ public function getFlagData($flagClass, $key)
193
+ {
194
+ $flagModel = $this->loadFlag($flagClass);
195
+
196
+ $flagData = $flagModel->getFlagData();
197
+
198
+ if (is_array($flagData) && array_key_exists($key, $flagData)) {
199
+ return $flagData[$key];
200
+ } else {
201
+ return FALSE;
202
+ }
203
+ }
204
+ }
app/code/community/Campaignmonitor/Createsend/Helper/Data.php ADDED
@@ -0,0 +1,452 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Helper_Data extends Mage_Core_Helper_Data
19
+ {
20
+ const LOGFILE = "campaignmonitor_createsend.log";
21
+
22
+ const XML_PATH_WEBHOOK_ID = 'createsend_general/api/webhook_id';
23
+ const XML_PATH_LIST_ID = 'createsend_general/api/list_id';
24
+ const XML_PATH_NEW_LIST_NAME = 'createsend_general/api/new_list_name';
25
+ const XML_PATH_AUTHENTICATION_METHOD = 'createsend_general/api/authentication_method';
26
+ const XML_PATH_API_ID = 'createsend_general/api/api_key';
27
+ const XML_PATH_API_CLIENT_ID = 'createsend_general/api/api_client_id';
28
+ const XML_PATH_OAUTH_CLIENT_ID = 'createsend_general/api/oauth_client_id';
29
+ const XML_PATH_OAUTH_CLIENT_SECRET = 'createsend_general/api/oauth_client_secret';
30
+ const XML_PATH_MAX_WISHLIST_ITEMS = 'createsend_customers/wishlists/max_wishlist_items';
31
+ const XML_PATH_WEBHOOK_ENABLED = 'createsend_general/advanced/webhook_enabled';
32
+ const XML_PATH_OAUTH_ACCESS_TOKEN = 'createsend_general/api/oauth_access_token';
33
+ const XML_PATH_OAUTH_ACCESS_TOKEN_EXPIRY_DATE = 'createsend_general/api/oauth_access_token_expiry_date';
34
+ const XML_PATH_OAUTH_REFRESH_TOKEN = 'createsend_general/api/oauth_refresh_token';
35
+ const XML_PATH_TRANSACTIONAL_EMAIL_ENABLED = 'createsend_transactional/emails/transactional_email_enabled';
36
+ const XML_PATH_EMAIL_RETENTION_DAYS = 'createsend_transactional/emails/transactional_email_retention_days';
37
+ const XML_PATH_SUBSCRIBER_SYNC_ENABLED = 'createsend_general/advanced/subscriber_synchronisation_enabled';
38
+ const XML_PATH_SUBSCRIBER_SYNC_RESOLUTION_METHOD = 'createsend_general/advanced/subscriber_synchronisation_resolution_method';
39
+ const XML_PATH_SUBSCRIBER_SYNC_PREFERRED_SOURCE = 'createsend_general/advanced/subscriber_synchronisation_preferred_source';
40
+ const XML_PATH_MAGENTO_CRON_ENABLED = 'createsend_general/advanced/magento_cron_enabled';
41
+ const XML_PATH_LOGGING = 'createsend_general/advanced/logging';
42
+ const XML_PATH_M_TO_CM_ATTRIBUTES = 'createsend_customers/attributes/m_to_cm_attributes';
43
+ const XML_PATH_WISHLIST_PRODUCT_ATTRIBUTES = 'createsend_customers/wishlists/wishlist_product_attributes';
44
+
45
+ protected $canLog = null;
46
+
47
+ /**
48
+ * Logs all extension specific notices to a separate file
49
+ *
50
+ * @param string $message The message to log
51
+ * @param int $level The log level (defined in the Zend_Log class)
52
+ */
53
+ public function log($message, $level = Zend_Log::DEBUG)
54
+ {
55
+ if ($this->canLog()) {
56
+ Mage::log($message, $level, self::LOGFILE);
57
+ }
58
+ }
59
+
60
+ /**
61
+ * @return bool
62
+ */
63
+ public function canLog()
64
+ {
65
+ if ($this->canLog === null) {
66
+ $this->canLog = Mage::getStoreConfig(self::XML_PATH_LOGGING);
67
+ }
68
+ return $this->canLog;
69
+ }
70
+
71
+ /**
72
+ * Returns the authentication method configuration value.
73
+ * No need to trim as value comes from source model and not from user input.
74
+ *
75
+ * @param mixed $store Get the configuration value for this store code or ID
76
+ * @return string
77
+ */
78
+ public function getAuthenticationMethod($store = null)
79
+ {
80
+ return Mage::getStoreConfig(self::XML_PATH_AUTHENTICATION_METHOD, $store);
81
+ }
82
+
83
+ /**
84
+ * Returns a sanitized version of the API key configuration value
85
+ *
86
+ * @param string $scope
87
+ * @param int $scopeId
88
+ * @return string
89
+ */
90
+ public function getApiKey($scope, $scopeId)
91
+ {
92
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
93
+ $scopeModel = Mage::getSingleton('createsend/config_scope');
94
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
95
+
96
+ return urlencode(trim($this->getStoreConfig(self::XML_PATH_API_ID, $storeId)));
97
+ }
98
+
99
+ /**
100
+ * Returns a sanitized version of the API key Client ID configuration value
101
+ *
102
+ * @param mixed $store Get the configuration value for this store code or ID
103
+ * @return string
104
+ */
105
+ public function getApiClientId($store = null)
106
+ {
107
+ return urlencode(trim(Mage::getStoreConfig(self::XML_PATH_API_CLIENT_ID, $store)));
108
+ }
109
+
110
+ /**
111
+ * Returns a sanitized version of the list id configuration value
112
+ *
113
+ * @param mixed $store Get the configuration value for this store code or ID
114
+ * @return string
115
+ */
116
+ public function getListId($store = null)
117
+ {
118
+ // Get value from database directly, bypassing the config cache
119
+ // because we are saving the config value using Mage:getConfig()->saveConfig()
120
+ return urlencode(trim($this->getStoreConfig(self::XML_PATH_LIST_ID, $store)));
121
+ }
122
+
123
+ /**
124
+ * Returns the new list name configuration value.
125
+ *
126
+ * @param mixed $store
127
+ * @return string
128
+ */
129
+ public function getNewListName($store = null)
130
+ {
131
+ return trim(Mage::getStoreConfig(self::XML_PATH_NEW_LIST_NAME, $store));
132
+ }
133
+
134
+ /**
135
+ * Returns the OAuth Client ID configuration value
136
+ *
137
+ * @param mixed $store Get the configuration value for this store code or ID
138
+ * @return string
139
+ */
140
+ public function getOAuthClientId($store = null)
141
+ {
142
+ return trim(Mage::getStoreConfig(self::XML_PATH_OAUTH_CLIENT_ID, $store));
143
+ }
144
+
145
+ /**
146
+ * Returns the OAuth Client Secret configuration value
147
+ *
148
+ * @param mixed $store Get the configuration value for this store code or ID
149
+ * @return string
150
+ */
151
+ public function getOAuthClientSecret($store = null)
152
+ {
153
+ return trim(Mage::getStoreConfig(self::XML_PATH_OAUTH_CLIENT_SECRET, $store));
154
+ }
155
+
156
+ /**
157
+ * Returns the OAuth Access Token configuration value
158
+ *
159
+ * @param mixed $store Get the configuration value for this store code or ID
160
+ * @return string
161
+ */
162
+ public function getOAuthAccessToken($store = null)
163
+ {
164
+ return $this->getStoreConfig(self::XML_PATH_OAUTH_ACCESS_TOKEN, $store);
165
+ }
166
+
167
+ /**
168
+ * Returns the OAuth Access Token configuration value in the specified store
169
+ *
170
+ * @param mixed $store Get the configuration value for this store code or ID
171
+ * @return string
172
+ */
173
+ public function getOAuthAccessTokenExpiryDate($store = null)
174
+ {
175
+ return $this->getStoreConfig(self::XML_PATH_OAUTH_ACCESS_TOKEN_EXPIRY_DATE, $store);
176
+ }
177
+
178
+ /**
179
+ * Returns the OAuth Refresh Token in the specified store
180
+ *
181
+ * @param mixed $store Get the configuration value for this store code or ID
182
+ * @return string
183
+ */
184
+ public function getOAuthRefreshToken($store = null)
185
+ {
186
+ return $this->getStoreConfig(self::XML_PATH_OAUTH_REFRESH_TOKEN, $store);
187
+ }
188
+
189
+ /**
190
+ * Returns the Max Wish list items
191
+ *
192
+ * @param mixed $store Get the configuration value for this store code or ID
193
+ * @return int
194
+ */
195
+ public function getMaxWistlistItems($store = null)
196
+ {
197
+ return Mage::getStoreConfig(self::XML_PATH_MAX_WISHLIST_ITEMS, $store);
198
+ }
199
+
200
+ /**
201
+ * Returns the Wishlist product attributes for the custom fields
202
+ *
203
+ * @param mixed $store Get the configuration value for this store code or ID
204
+ * @return int
205
+ */
206
+ public function getProductAttributes($store = null)
207
+ {
208
+ return Mage::getStoreConfig(self::XML_PATH_WISHLIST_PRODUCT_ATTRIBUTES, $store);
209
+ }
210
+
211
+ /**
212
+ * Returns the Webhook enabled configuration value
213
+ *
214
+ * @param mixed $store Get the configuration value for this store code or ID
215
+ * @return bool
216
+ */
217
+ public function isWebhookEnabled($store = null)
218
+ {
219
+ return Mage::getStoreConfigFlag(self::XML_PATH_WEBHOOK_ENABLED, $store);
220
+ }
221
+
222
+ /**
223
+ * Returns the Transactional Email configuration value
224
+ *
225
+ * @param mixed $store Get the configuration value for this store code or ID
226
+ * @return bool
227
+ */
228
+ public function isTransactionalEmailsEnabled($store = null)
229
+ {
230
+ return Mage::getStoreConfigFlag(self::XML_PATH_TRANSACTIONAL_EMAIL_ENABLED, $store);
231
+ }
232
+
233
+ /**
234
+ * Returns the Subscriber Synchronisation Enabled configuration value
235
+ *
236
+ * @param mixed $store Get the configuration value for this store code or ID
237
+ * @return bool
238
+ */
239
+ public function isSubscriberSynchronisationEnabled($store = null)
240
+ {
241
+ return Mage::getStoreConfigFlag(self::XML_PATH_SUBSCRIBER_SYNC_ENABLED, $store);
242
+ }
243
+
244
+ /**
245
+ * Returns the Subscriber Synchronisation Resolution Method configuration value
246
+ *
247
+ * @param mixed $store Get the configuration value for this store code or ID
248
+ * @return string
249
+ */
250
+ public function getSubscriberSynchronisationResolutionMethod($store = null)
251
+ {
252
+ return Mage::getStoreConfig(self::XML_PATH_SUBSCRIBER_SYNC_RESOLUTION_METHOD, $store);
253
+ }
254
+
255
+ /**
256
+ * Returns the Subscriber Synchronisation Preferred Source configuration value
257
+ *
258
+ * @param mixed $store Get the configuration value for this store code or ID
259
+ * @return mixed
260
+ */
261
+ public function getSubscriberSynchronisationPreferredSource($store = null)
262
+ {
263
+ return Mage::getStoreConfig(self::XML_PATH_SUBSCRIBER_SYNC_PREFERRED_SOURCE, $store);
264
+ }
265
+
266
+ /**
267
+ * Returns the Magento Cron Enabled configuration value
268
+ *
269
+ * @param mixed $store Get the configuration value for this store code or ID
270
+ * @return bool
271
+ */
272
+ public function isMagentoCronEnabled($store = null)
273
+ {
274
+ return Mage::getStoreConfigFlag(self::XML_PATH_MAGENTO_CRON_ENABLED, $store);
275
+ }
276
+
277
+ /**
278
+ * Returns the Transactional Email Header Retention Days configuration value
279
+ *
280
+ * @param mixed $store Get the configuration value for this store code or ID
281
+ * @return int
282
+ */
283
+ public function getEmailRetentionDays($store = null)
284
+ {
285
+ return Mage::getStoreConfig(self::XML_PATH_EMAIL_RETENTION_DAYS, $store);
286
+ }
287
+
288
+ /**
289
+ * Returns the Campaign Monitor Client ID
290
+ *
291
+ * @param mixed $store Get the configuration value for this store code or ID
292
+ * @return null|string
293
+ */
294
+ public function getClientId($store)
295
+ {
296
+ return $this->getApiClientId($store);
297
+ }
298
+
299
+ /**
300
+ * Saves the token data for OAuth API
301
+ *
302
+ * @param array $data Array containing the access token ($data['access_token']),
303
+ * expiry period in seconds ($data['expires_in'])
304
+ * and refresh token ($data['refresh_token'])
305
+ * @param string $scope
306
+ * @param int $scopeId
307
+ * @return bool
308
+ */
309
+ public function saveOauthTokenData(array $data, $scope, $scopeId)
310
+ {
311
+ if (empty($data['access_token'])) {
312
+ return false;
313
+ }
314
+
315
+ $now = new DateTime();
316
+ $expiry = $now->add(DateInterval::createFromDateString($data['expires_in'] . ' seconds'));
317
+
318
+ /** @var Mage_Core_Model_Config $configSingleton */
319
+ $configSingleton = Mage::getConfig();
320
+
321
+ $configSingleton->saveConfig(
322
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_OAUTH_ACCESS_TOKEN,
323
+ $data['access_token'], $scope, $scopeId
324
+ );
325
+
326
+ $configSingleton->saveConfig(
327
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_OAUTH_ACCESS_TOKEN_EXPIRY_DATE,
328
+ $expiry->format('Y-m-d H:i:s O'), $scope, $scopeId
329
+ );
330
+
331
+ $configSingleton->saveConfig(
332
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_OAUTH_REFRESH_TOKEN,
333
+ $data['refresh_token'], $scope, $scopeId
334
+ );
335
+
336
+ return true;
337
+ }
338
+
339
+ /**
340
+ * Returns true if the configuration for the specified scope/scopeId is complete.
341
+ *
342
+ * @param string $scope
343
+ * @param int $scopeId
344
+ * @return bool
345
+ */
346
+ function isCompleteConfig($scope, $scopeId)
347
+ {
348
+ $reply = true;
349
+
350
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
351
+ $scopeModel = Mage::getSingleton('createsend/config_scope');
352
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
353
+
354
+ $authenticationMethod = $this->getAuthenticationMethod($storeId);
355
+ switch ($authenticationMethod) {
356
+ case Campaignmonitor_Createsend_Model_Config_AuthenticationMethod::AUTHENTICATION_METHOD_API_KEY:
357
+ $apiKey = $this->getApiKey($scope, $scopeId);
358
+
359
+ if (!$apiKey) {
360
+ $reply = false;
361
+ }
362
+ break;
363
+
364
+ case Campaignmonitor_Createsend_Model_Config_AuthenticationMethod::AUTHENTICATION_METHOD_OAUTH:
365
+ $clientId = $this->getOAuthClientId($storeId);
366
+ $clientSecret = $this->getOAuthClientSecret($storeId);
367
+ $oauthAccessToken = $this->getOAuthAccessToken($storeId);
368
+
369
+ if (!$clientId || !$clientSecret || !$oauthAccessToken) {
370
+ $reply = false;
371
+ }
372
+ break;
373
+
374
+ default:
375
+ $reply = false;
376
+ break;
377
+
378
+ }
379
+
380
+ $listId = $this->getScopedConfig(Campaignmonitor_Createsend_Helper_Data::XML_PATH_LIST_ID, $scope, $scopeId);
381
+
382
+ if ($listId === false) {
383
+ $reply = false;
384
+ }
385
+
386
+ return $reply;
387
+ }
388
+
389
+ /**
390
+ * Gets the appropriate configuration value from the database, given the path and store code or ID.
391
+ * If the configuration is not found in the store scope, the value for website scope and default scope
392
+ * will be retrieved.
393
+ *
394
+ * This function is written to work the same way as Mage::getStoreConfig() except that it does not
395
+ * use the config cache. This function should be used if there are config settings that
396
+ * were saved directly using Mage::getConfig()->saveConfig()
397
+ *
398
+ * @param string $path
399
+ * @param mixed $store
400
+ * @return mixed|null
401
+ */
402
+ public function getStoreConfig($path, $store)
403
+ {
404
+ $configValue = $this->getScopedConfig($path, 'stores', Mage::app()->getStore($store)->getId());
405
+ if ($configValue === false) {
406
+ $configValue = $this->getScopedConfig($path, 'websites', Mage::app()->getStore($store)->getWebsiteId());
407
+ if ($configValue === false) {
408
+ $configValue = $this->getScopedConfig($path, 'default', Mage_Core_Model_App::ADMIN_STORE_ID);
409
+ if ($configValue === false) {
410
+ $configValue = null;
411
+ }
412
+ }
413
+ }
414
+
415
+ return $configValue;
416
+ }
417
+
418
+ /**
419
+ * Gets the appropriate configuration value from the database, given the path, scope and ID. Uses similar logic
420
+ * to the method Mage_Core_Model_Resource_Config::deleteConfig(), and should only be used when querying a config
421
+ * value known to be in the DB and where scope must be known.
422
+ *
423
+ * @param string $path the tree path
424
+ * @param string $scope default, website or store scope
425
+ * @param int $scopeId The ID of the scoped reference
426
+ * @return mixed
427
+ */
428
+ public function getScopedConfig($path, $scope, $scopeId)
429
+ {
430
+ /** @var Mage_Core_Model_Resource $resource */
431
+ $resource = Mage::getSingleton('core/resource');
432
+ /** @var Magento_Db_Adapter_Pdo_Mysql $db */
433
+ // Uses the core_write table instead of core_read to get up to date information as config is iteratively saved.
434
+ $db = $resource->getConnection(
435
+ Mage_Core_Model_Resource::DEFAULT_WRITE_RESOURCE
436
+ );
437
+
438
+ $coreConfigTable = $resource->getTableName('core/config_data');
439
+ $select = $db->select()
440
+ ->from($coreConfigTable, 'value')
441
+ ->where('path = ?', $path)
442
+ ->where('scope = ?', $scope)
443
+ ->where('scope_id = ?', $scopeId);
444
+
445
+ $value = $db->fetchOne($select);
446
+ if ($value !== null) {
447
+ return $value;
448
+ }
449
+
450
+ return false;
451
+ }
452
+ }
app/code/community/Campaignmonitor/Createsend/Model/Api.php ADDED
@@ -0,0 +1,897 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Responsible for making calls and getting responses from the Campaign Monitor API.
20
+ * Uses the key authorization mechanism (see the link for further information)
21
+ *
22
+ * @link https://www.campaignmonitor.com/api/getting-started/
23
+ */
24
+ class Campaignmonitor_Createsend_Model_Api
25
+ {
26
+ const API_BASE_URL = 'https://api.createsend.com/';
27
+ const API_PATH = 'api/v3.1/';
28
+ const API_OAUTH_PATH = 'oauth/';
29
+
30
+ const CODE_SUBSCRIBER_NOT_IN_LIST = 203;
31
+ const CODE_DUPLICATE_SEGMENT_TITLE = 275;
32
+ const CODE_INVALID_SEGMENT_RULES = 277;
33
+ const CODE_FIELD_KEY_EXISTS = 255;
34
+
35
+ const ERR_API_REQUEST = 'API Error: %s';
36
+ const ERR_INVALID_HTTP_METHOD = 'The method "%s" is not an acceptable HTTP method';
37
+ const ERR_INVALID_AUTH_METHOD = 'The method "%s" is not an acceptable Authentication method';
38
+ const ERR_INVALID_JSON = 'The following response is not valid JSON: "%s"';
39
+ const ERR_ID_REQUIRED = 'The "%s" data is required to make this call';
40
+ const ERR_NO_LIST_ID_AT_SCOPE = 'There is no list ID defined at this %s/%s scope. Cannot create webhook';
41
+ const ERR_CANNOT_UPDATE_WEBHOOK = 'API Error: Cannot update webhook (%s)';
42
+ const ERR_CANNOT_LIST_WEBHOOKS = 'API Error: Cannot list webhook (%s)';
43
+
44
+ const ERR_CANNOT_CREATE_CUSTOM_FIELD = 'API Error: Cannot create custom field: (%1$s): %2$s';
45
+ const ERR_CREATE_CUSTOM_FIELDS = 'Please create these custom fields on the Campaign Monitor list: %s';
46
+ const ERR_SEGMENT_EXISTS = 'A segment with the same title already exists on this list.';
47
+ const ERR_UNABLE_TO_CREATE_SEGMENT = 'Unable to create segment (%1$s): %2$s';
48
+ const LOG_SEGMENT_CREATED = 'Segment successfully created (%s).';
49
+
50
+ const LOG_API_REQUEST = 'API Request %s @ %s: %s';
51
+ const LOG_API_RESPONSE = 'API Response (%s) @ %s: %s';
52
+ const LOG_CREATED_WEBHOOK = 'Created webhook with ID "%s"';
53
+ const LOG_DELETED_WEBHOOK = 'Deleted webhook with ID "%s"';
54
+ const LOG_WEBHOOKS_NOT_ENABLED = 'Webhooks not enabled.';
55
+
56
+ const WEBHOOK_EVENT_SUBSCRIBE = 'Subscribe';
57
+ const WEBHOOK_EVENT_UPDATE = 'Update';
58
+ const WEBHOOK_EVENT_DEACTIVATE = 'Deactivate';
59
+
60
+ const SUBSCRIBER_STATUS_ACTIVE = 'Active';
61
+ const SUBSCRIBER_STATUS_DELETED = 'Deleted';
62
+
63
+ const WEBHOOK_STATUS_ACTIVE = 'Active';
64
+ const WEBHOOK_STATUS_UNSUBSCRIBED = 'Unsubscribed';
65
+ const WEBHOOK_STATUS_DELETED = 'Deleted';
66
+
67
+ const WEBHOOK_PAYLOAD_FORMAT_JSON = 'Json';
68
+
69
+ const OAUTH_API_TOKEN_REQUEST = 'oauth_token';
70
+
71
+ const FIELD_TYPE_TEXT = 'Text';
72
+ const FIELD_TYPE_NUMBER = 'Number';
73
+ const FIELD_TYPE_DATE = 'Date';
74
+ const FIELD_TYPE_SELECT_ONE = 'MultiSelectOne';
75
+ const FIELD_TYPE_SELECT_MANY = 'MultiSelectMany';
76
+ const FIELD_TYPE_COUNTRY = 'Country';
77
+
78
+ const CM_MAX_CUSTOM_FIELD_LENGTH = 100;
79
+ const CM_CUSTOM_FIELD_PREFIX = 'Magento ';
80
+
81
+ const WISHLIST_CUSTOM_FIELD_PREFIX = 'Wishlist Item';
82
+ const WISHLIST_CUSTOM_FIELD_PATTERN = '%1$s %2$s %3$s';
83
+
84
+ const USER_AGENT_STRING = 'CM_Magento_Extension; Magento %s; Extension %s; List ID %s';
85
+
86
+ // Methods used by the API
87
+ /** @var array */
88
+ protected $_supportedMethods = array(
89
+ Zend_Http_Client::DELETE,
90
+ Zend_Http_Client::GET,
91
+ Zend_Http_Client::POST,
92
+ Zend_Http_Client::PUT
93
+ );
94
+
95
+ // Permissions to be requested when authenticating via OAuth
96
+ /** @var array */
97
+ protected $_oauthPermissions = array(
98
+ 'ManageLists',
99
+ 'ImportSubscribers',
100
+ 'ViewTransactional',
101
+ 'SendTransactional'
102
+ );
103
+
104
+ /**
105
+ * Returns the URL for the OAuth Controller
106
+ *
107
+ * @param string $scope
108
+ * @param int $scopeId
109
+ * @return string
110
+ */
111
+ public function getOauthRedirectUri($scope, $scopeId)
112
+ {
113
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
114
+ $scopeModel = Mage::getModel('createsend/config_scope');
115
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
116
+
117
+ $url = Mage::getUrl(
118
+ 'createsend/oauth/getToken',
119
+ array(
120
+ '_nosid' => true,
121
+ '_store' => $storeId,
122
+ '_type' => 'direct_link'
123
+ )
124
+ );
125
+
126
+ return $url;
127
+ }
128
+
129
+ /**
130
+ * Returns the URL Address for the Campaign Monitor OAuth Permission Request Page,
131
+ * including all the GET parameters required by the Campaign Monitor API for OAuth
132
+ *
133
+ * @link https://www.campaignmonitor.com/api/getting-started/#authenticating_with_oauth
134
+ *
135
+ * @param string $scope
136
+ * @param int $scopeId
137
+ * @return string
138
+ */
139
+ public function getOauthPermissionRequestUrl($scope, $scopeId)
140
+ {
141
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
142
+ $helper = Mage::helper('createsend');
143
+
144
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
145
+ $scopeModel = Mage::getModel('createsend/config_scope');
146
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
147
+
148
+ return self::API_BASE_URL . self::API_OAUTH_PATH . '?' . http_build_query (
149
+ array(
150
+ 'type' => 'web_server',
151
+ 'client_id' => $helper->getOAuthClientId($storeId),
152
+ 'redirect_uri' => $this->getOauthRedirectUri($scope, $scopeId),
153
+ 'scope' => implode(',', $this->_oauthPermissions),
154
+ 'state' => implode(',', array($scope, $scopeId))
155
+ )
156
+ );
157
+ }
158
+
159
+ /**
160
+ * Calculate the version of Magento through a checking of arbitrary magento characteristics.
161
+ *
162
+ * @return string
163
+ */
164
+ public function getMagentoVersion()
165
+ {
166
+ $version = Mage::getVersion();
167
+ $edition = 'ce';
168
+
169
+ // If the version is above 1.6.0.0 it might be professional or enterprise.
170
+ if (version_compare($version, '1.6.0.0', '>=')) {
171
+ // Calculate whether the install has gift cards. if it doesn't, it's community.
172
+ $hasGiftcards = Mage::getModel('enterprise_giftcard/giftcard');
173
+
174
+ if ($hasGiftcards) {
175
+ // Check whether the installation has the enterprise search observer. Only enterprise has this.
176
+ $hasSolr = Mage::getModel('enterprise_search/observer');
177
+
178
+ if ($hasSolr) {
179
+ $edition = 'ee';
180
+ } else {
181
+ $edition = 'pe';
182
+ }
183
+ } else {
184
+ $edition = 'ce';
185
+ }
186
+ }
187
+
188
+ return sprintf('%s %s', $edition, $version);
189
+ }
190
+
191
+ /**
192
+ * Responsible for providing an interface to the API and parsing the data returned from the API into a manageable
193
+ * format.
194
+ *
195
+ * If the API returns a JSON object that is just a string that string will be in the [data][Message] key. This key
196
+ * is also responsible for error messages if the API request fails as well as error messages the API returns.
197
+ *
198
+ * Returns an array of the form
199
+ * [success] => bool
200
+ * [status_code] => int
201
+ * [data] => array
202
+ * [Message] => string
203
+ * [DataA] => Returned field
204
+ * [DataB] => Returned field
205
+ *
206
+ * @param string $method The HTTP method to use. Accepted methods are defined at the top of this class and constants
207
+ * are available in the Zend_Http_Client class.
208
+ * @param string $endpoint The API endpoint to query; for example: lists/1eax88123c7cedasdas70fd05saxqwbf
209
+ * @param array $postFields An array of fields to send the end point
210
+ * @param array $queryParams An array of URI query parameters to append to the URI
211
+ * @param string $scope 'default' | 'websites' | 'stores'
212
+ * @param int $scopeId The id of the scope
213
+ *
214
+ * @return array|null
215
+ */
216
+ public function call($method, $endpoint, $postFields = array(), $queryParams = array(), $scope, $scopeId)
217
+ {
218
+ /** @var array $data */
219
+ $data = array(
220
+ 'success' => false,
221
+ 'status_code' => null,
222
+ 'data' => null
223
+ );
224
+
225
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
226
+ $helper = Mage::helper('createsend');
227
+
228
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
229
+ $scopeModel = Mage::getModel('createsend/config_scope');
230
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
231
+
232
+ $authenticationMethod = $helper->getAuthenticationMethod($storeId);
233
+ if ($endpoint === 'token') {
234
+ $authenticationMethod = self::OAUTH_API_TOKEN_REQUEST;
235
+ }
236
+
237
+ $apiKeyOrToken = '';
238
+
239
+ switch ($authenticationMethod) {
240
+ case Campaignmonitor_Createsend_Model_Config_AuthenticationMethod::AUTHENTICATION_METHOD_API_KEY:
241
+ $apiKeyOrToken = $helper->getApiKey($scope, $scopeId);
242
+
243
+ if (!$apiKeyOrToken) {
244
+ $data['data']['Message'] = 'No API key set in configuration';
245
+ return $data;
246
+ }
247
+
248
+ break;
249
+
250
+ case Campaignmonitor_Createsend_Model_Config_AuthenticationMethod::AUTHENTICATION_METHOD_OAUTH:
251
+ $expiry = new DateTime($helper->getOAuthAccessTokenExpiryDate($storeId));
252
+ $now = new DateTime();
253
+ if ($now > $expiry) {
254
+ $this->_refreshToken($scope, $scopeId, $storeId);
255
+ }
256
+
257
+ $apiKeyOrToken = $helper->getOAuthAccessToken($storeId);
258
+
259
+ if (!$apiKeyOrToken) {
260
+ $data['data']['Message'] = 'No OAuth Token yet. Please request and allow OAuth permission first.';
261
+ return $data;
262
+ }
263
+
264
+ break;
265
+ }
266
+
267
+ $mageVersion = strtoupper($this->getMagentoVersion());
268
+ $extVersion = Mage::getConfig()->getModuleConfig("Campaignmonitor_Createsend")->version;
269
+ $listId = $helper->getListId($storeId);
270
+
271
+ $userAgent = sprintf(self::USER_AGENT_STRING, $mageVersion, $extVersion, $listId);
272
+
273
+ $response = $this->_callApi($authenticationMethod, $apiKeyOrToken, $method, $endpoint, $postFields,
274
+ $queryParams, $userAgent);
275
+ if (!$response) {
276
+ $data['data']['Message'] = 'An error occurred during the request.';
277
+ return $data;
278
+ }
279
+
280
+ $data['success'] = $response->isSuccessful();
281
+
282
+ // Get the response content. The response will either be a JSON encoded object or nothing, depending on the
283
+ // call. The only situation in which content is not JSON is a request URI without a .json file suffix.
284
+ if (stripos($response->getHeader('content-type'), 'application/json') !== null) {
285
+ try {
286
+ $returnContent = Zend_Json::decode($response->getBody());
287
+
288
+ // The API sometimes returns a string, not an array.
289
+ if (is_array($returnContent)) {
290
+ $data['data'] = $returnContent;
291
+ } else {
292
+ $data['data'] = array('Message' => $returnContent);
293
+ }
294
+ } catch (Zend_Json_Exception $e) {
295
+ $helper->log(sprintf(self::ERR_INVALID_JSON, $response->getBody()));
296
+ }
297
+ }
298
+
299
+ $data['status_code'] = $response->getStatus();
300
+ return $data;
301
+ }
302
+
303
+ /**
304
+ * Responsible for making the actual calls to the API. The authorization method is either "API Key" or "OAuth"
305
+ * authorisation method, and documentation can be found at the link below.
306
+ *
307
+ * @link https://www.campaignmonitor.com/api/
308
+ *
309
+ * @param string $authenticationMethod The Authentication Method to be used for the request ('api_key' or 'oauth')
310
+ * @param string $apiKeyOrToken The API key or OAuth Access Token required to make the API request
311
+ * @param string $method The HTTP Method for the request. Valid methods are documented at the top of the class
312
+ * @param string $endpoint The endpoint to make the request of
313
+ * @param array $postFields The fields that should be posted to the end point
314
+ * @param array $queryParams Any query params that should be appended to the request
315
+ * @param string $userAgent HTTP User-Agent to use
316
+ *
317
+ * @return Zend_Http_Response
318
+ * @throws Mage_Core_Exception if the method given is not an accepted method
319
+ * @throws Zend_Http_Client_Exception if something goes wrong during the connection
320
+ */
321
+ protected function _callApi($authenticationMethod, $apiKeyOrToken, $method, $endpoint,
322
+ $postFields = array(), $queryParams = array(), $userAgent)
323
+ {
324
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
325
+ $helper = Mage::helper('createsend');
326
+
327
+ if (in_array($method, $this->_supportedMethods) === false) {
328
+ Mage::throwException(sprintf(self::ERR_INVALID_HTTP_METHOD, $method));
329
+ }
330
+
331
+ // Construct the client
332
+ $client = new Zend_Http_Client();
333
+ $client->setMethod($method);
334
+ $client->setConfig(array('useragent' => $userAgent));
335
+
336
+ $uri = self::API_BASE_URL . self::API_PATH . $endpoint . '.json';
337
+
338
+ switch ($authenticationMethod) {
339
+ case Campaignmonitor_Createsend_Model_Config_AuthenticationMethod::AUTHENTICATION_METHOD_API_KEY:
340
+ $client->setAuth($apiKeyOrToken, null, Zend_Http_Client::AUTH_BASIC);
341
+ break;
342
+
343
+ case Campaignmonitor_Createsend_Model_Config_AuthenticationMethod::AUTHENTICATION_METHOD_OAUTH:
344
+ $client->setHeaders('Authorization', 'Bearer ' . $apiKeyOrToken);
345
+ break;
346
+
347
+ case self::OAUTH_API_TOKEN_REQUEST:
348
+ $uri = self::API_BASE_URL . self::API_OAUTH_PATH . $endpoint;
349
+ break;
350
+
351
+ default:
352
+ Mage::throwException(sprintf(self::ERR_INVALID_AUTH_METHOD, $authenticationMethod));
353
+ break;
354
+ }
355
+
356
+ if (count($queryParams) > 0) {
357
+ $uri .= '?' . http_build_query($queryParams);
358
+ }
359
+ $client->setUri($uri);
360
+
361
+ $payload = Zend_Json::encode($postFields);
362
+
363
+ // Optionally set the POST payload
364
+ if ($method === Zend_Http_Client::POST) {
365
+ $client->setRawData($payload, 'application/json');
366
+ }
367
+
368
+ // Log the request for debugging
369
+ $helper->log(
370
+ sprintf(self::LOG_API_REQUEST, $method, $client->getUri()->__toString(), $payload),
371
+ Zend_Log::DEBUG
372
+ );
373
+
374
+ try {
375
+ $response = $client->request();
376
+ } catch (Zend_Http_Client_Exception $e) {
377
+ $helper->log($e->getMessage(), Zend_Log::WARN);
378
+ return false;
379
+ }
380
+
381
+ // Log response
382
+ $helper->log(
383
+ sprintf(self::LOG_API_RESPONSE, $response->getStatus(), $client->getUri()->__toString(), $response->getBody()),
384
+ Zend_Log::DEBUG
385
+ );
386
+
387
+ return $response;
388
+ }
389
+
390
+ /**
391
+ * Refreshes and saves the OAuth Access Token
392
+ *
393
+ * @param string $scope
394
+ * @param int $scopeId
395
+ * @param int $storeId
396
+ * @return bool
397
+ */
398
+ protected function _refreshToken($scope, $scopeId, $storeId)
399
+ {
400
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
401
+ $helper = Mage::helper('createsend');
402
+
403
+ // refresh access token
404
+ $response = $this->call(
405
+ Zend_Http_Client::POST,
406
+ 'token',
407
+ array(),
408
+ array(
409
+ 'grant_type' => 'refresh_token',
410
+ 'refresh_token' => $helper->getOAuthRefreshToken($storeId),
411
+ ),
412
+ $scope,
413
+ $scopeId
414
+ );
415
+
416
+ return $helper->saveOauthTokenData($response['data'], $scope, $scopeId);
417
+ }
418
+
419
+ /**
420
+ * Updates the webhooks based for scope/scopeId.
421
+ *
422
+ * @param string $scope
423
+ * @param int $scopeId
424
+ * @return array|null
425
+ */
426
+ public function updateWebhooks($scope, $scopeId)
427
+ {
428
+ $data = array(
429
+ 'success' => false,
430
+ 'data' => null
431
+ );
432
+
433
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
434
+ $scopeModel = Mage::getModel('createsend/config_scope');
435
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
436
+ $store = Mage::app()->getStore($storeId);
437
+
438
+ $webhookUrl = Mage::getUrl('createsend/webhooks/index', array('_store' => $store));
439
+
440
+ /** @var Mage_Core_Model_Config $configSingleton */
441
+ $configSingleton = Mage::getConfig();
442
+
443
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
444
+ $helper = Mage::helper('createsend');
445
+
446
+ $webhookEnabled = $helper->isWebhookEnabled($storeId);
447
+
448
+ // Magento's normal config system will inherit all values from whatever parent object sets them. While this
449
+ // is OK for usage we cannot delete or manipulate a webhook based on an inherited value. Therefore we call
450
+ // a method that directly queries the core_config_data table, based on the scope values in the request.
451
+ $listId = $helper->getScopedConfig(Campaignmonitor_Createsend_Helper_Data::XML_PATH_LIST_ID, $scope, $scopeId);
452
+
453
+ if ($listId === false) {
454
+ $data['data']['Message'] = sprintf(self::ERR_NO_LIST_ID_AT_SCOPE, $scope, $scopeId);
455
+ return $data;
456
+ }
457
+
458
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
459
+ $api = Mage::getModel('createsend/api');
460
+
461
+ $this->deleteAllWebhooks($listId, $scope, $scopeId);
462
+
463
+ if ($webhookEnabled) {
464
+ $result = $api->call(
465
+ Zend_Http_Client::POST,
466
+ "lists/{$listId}/webhooks",
467
+ array(
468
+ 'Events' => array(
469
+ Campaignmonitor_Createsend_Model_Api::WEBHOOK_EVENT_SUBSCRIBE,
470
+ Campaignmonitor_Createsend_Model_Api::WEBHOOK_EVENT_UPDATE,
471
+ Campaignmonitor_Createsend_Model_Api::WEBHOOK_EVENT_DEACTIVATE
472
+ ),
473
+ 'Url' => $webhookUrl,
474
+ 'PayloadFormat' => Campaignmonitor_Createsend_Model_Api::WEBHOOK_PAYLOAD_FORMAT_JSON
475
+ ),
476
+ array(),
477
+ $scope,
478
+ $scopeId
479
+ );
480
+
481
+ if ($result['success'] === false) {
482
+ return $result;
483
+ }
484
+
485
+ $configSingleton->saveConfig(
486
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_WEBHOOK_ID,
487
+ $result['data']['Message'], $scope, $scopeId
488
+ );
489
+
490
+ $helper->log(sprintf(self::LOG_CREATED_WEBHOOK, $result['data']['Message']));
491
+
492
+ $data['success'] = true;
493
+ $data['data']['Message'] = sprintf(self::LOG_CREATED_WEBHOOK, $result['data']['Message']);
494
+ } else {
495
+ $data['success'] = true;
496
+ $data['data']['Message'] = self::LOG_WEBHOOKS_NOT_ENABLED;
497
+ }
498
+
499
+ return $data;
500
+ }
501
+
502
+ /**
503
+ * Deletes all webhooks registered for the list.
504
+ *
505
+ * @param string $listId Campaign Monitor List ID
506
+ * @param string $scope
507
+ * @param int $scopeId
508
+ */
509
+ public function deleteAllWebhooks($listId, $scope, $scopeId)
510
+ {
511
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
512
+ $api = Mage::getModel('createsend/api');
513
+
514
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
515
+ $helper = Mage::helper("createsend");
516
+
517
+ // Get webhook id from config data and try to remove it
518
+ $webhookId = $helper->getScopedConfig(Campaignmonitor_Createsend_Helper_Data::XML_PATH_WEBHOOK_ID, $scope, $scopeId);
519
+ if ($webhookId !== false) {
520
+ Mage::getConfig()->deleteConfig($helper::XML_PATH_WEBHOOK_ID, $scope, $scopeId);
521
+ $this->_deleteWebhook($listId, $webhookId, $scope, $scopeId);
522
+ }
523
+
524
+ // Then try to remove all other remaining webhooks, if any
525
+ $result = $api->call(
526
+ Zend_Http_Client::GET,
527
+ "lists/{$listId}/webhooks",
528
+ array(),
529
+ array(),
530
+ $scope,
531
+ $scopeId
532
+ );
533
+
534
+ if ($result['success'] !== false) {
535
+ foreach ($result['data'] as $webhookData) {
536
+ $webhookId = $webhookData['WebhookID'];
537
+ $this->_deleteWebhook($listId, $webhookId, $scope, $scopeId);
538
+ }
539
+ }
540
+ }
541
+
542
+ /**
543
+ * Deletes a webhook previously registered in Campaign Monitor.
544
+ *
545
+ * @param string $listId Campaign Monitor List ID
546
+ * @param string $webhookId The webhook to de-register
547
+ * @param string $scope
548
+ * @param int $scopeId
549
+ * @return array|null
550
+ */
551
+ protected function _deleteWebhook($listId, $webhookId, $scope, $scopeId)
552
+ {
553
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
554
+ $api = Mage::getModel('createsend/api');
555
+
556
+ /** @var Mage_Core_Model_Config $configSingleton */
557
+ $configSingleton = Mage::getConfig();
558
+
559
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
560
+ $helper = Mage::helper('createsend');
561
+
562
+ $result = $api->call(
563
+ Zend_Http_Client::DELETE,
564
+ "lists/{$listId}/webhooks/{$webhookId}",
565
+ array(),
566
+ array(),
567
+ $scope,
568
+ $scopeId
569
+ );
570
+
571
+ if ($result['success'] === false) {
572
+ return $result;
573
+ } else {
574
+ $helper->log(sprintf(self::LOG_DELETED_WEBHOOK, $webhookId), Zend_Log::NOTICE);
575
+ }
576
+
577
+ $savedWebhookId = $helper->getScopedConfig(
578
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_WEBHOOK_ID, $scope, $scopeId
579
+ );
580
+
581
+ if ($savedWebhookId === $webhookId) {
582
+ $configSingleton->deleteConfig($helper::XML_PATH_WEBHOOK_ID, $scope, $scopeId);
583
+ }
584
+
585
+ return $result;
586
+ }
587
+
588
+ /**
589
+ * Subscribes an email address to CM. The list ID will be retrieved from the configuration using the scope/scopeId.
590
+ *
591
+ * @param string $email The email address to subscribe
592
+ * @param string $scope
593
+ * @param int $scopeId
594
+ * @return array|null
595
+ */
596
+ public function subscribe($email, $scope, $scopeId)
597
+ {
598
+ $subscriberData = array(
599
+ 'EmailAddress' => $email,
600
+ 'Resubscribe' => true,
601
+ 'RestartSubscriptionBasedAutoresponders' => true
602
+ );
603
+
604
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
605
+ $helper = Mage::helper("createsend");
606
+
607
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
608
+ $scopeModel = Mage::getModel('createsend/config_scope');
609
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
610
+ $websiteId = $scopeModel->getWebsiteIdFromScope($scope, $scopeId);
611
+
612
+ /* @var Mage_Customer_Model_Customer $customer */
613
+ $customer = Mage::getModel("customer/customer")
614
+ ->setWebsiteId($websiteId)
615
+ ->loadByEmail($email);
616
+
617
+ if ($customer->getId()) {
618
+ $subscriberData['Name'] = $customer->getName();
619
+ }
620
+
621
+ $subscriberData['CustomFields'] =
622
+ Campaignmonitor_Createsend_Model_Customer_Observer::generateCustomFields($customer);
623
+
624
+ return $this->call(
625
+ Zend_Http_Client::POST,
626
+ 'subscribers/' . $helper->getListId($storeId),
627
+ $subscriberData,
628
+ array(),
629
+ $scope,
630
+ $scopeId
631
+ );
632
+ }
633
+
634
+ /**
635
+ * Un-subscribes an email address from CM list of scope/scopeId
636
+ *
637
+ * @param string $email The email to un-subscribe from CM
638
+ * @param string $scope
639
+ * @param int $scopeId
640
+ * @return array|null
641
+ */
642
+ public function unsubscribe($email, $scope, $scopeId)
643
+ {
644
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
645
+ $helper = Mage::helper("createsend");
646
+
647
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
648
+ $scopeModel = Mage::getModel('createsend/config_scope');
649
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
650
+
651
+ return $this->call(
652
+ Zend_Http_Client::POST,
653
+ "subscribers/{$helper->getListId($storeId)}/unsubscribe",
654
+ array(
655
+ 'EmailAddress' => $email
656
+ ),
657
+ array(),
658
+ $scope,
659
+ $scopeId
660
+ );
661
+ }
662
+
663
+ /**
664
+ * Returns the Campaign Monitor Custom Field name with the prefix and truncated to max length
665
+ *
666
+ * @param $fieldName
667
+ * @return string
668
+ */
669
+ public function formatCustomFieldName($fieldName)
670
+ {
671
+ $customName = self::CM_CUSTOM_FIELD_PREFIX . $fieldName;
672
+
673
+ // Return only up to CM_MAX_CUSTOM_FIELD_LENGTH characters to avoid error
674
+ return substr($customName, 0, self::CM_MAX_CUSTOM_FIELD_LENGTH);
675
+ }
676
+
677
+ /**
678
+ * Creates a Campaign Monitor custom field on the list defined in the scope/scopeid using the API.
679
+ *
680
+ * @param string $fieldName The name of the custom field to be created.
681
+ * @param string $dataType Data Type, can be either: Text, Number, Date, MultiSelectOne, MultiSelectMany, Country or USState.
682
+ * @param array $options Array of options if type is MultiSelectOne or MultiSelectMany
683
+ * @param bool $isVisibleInPreferenceCenter Whether the field should be visible in the subscriber preference center.
684
+ * @param string $scope Scope
685
+ * @param int $scopeId Scope ID
686
+ * @return array|null
687
+ */
688
+ public function createCustomField($fieldName, $dataType, $options, $isVisibleInPreferenceCenter, $scope, $scopeId)
689
+ {
690
+ $params = array(
691
+ 'FieldName' => $this->formatCustomFieldName($fieldName),
692
+ 'DataType' => $dataType,
693
+ 'VisibleInPreferenceCenter' => $isVisibleInPreferenceCenter,
694
+ );
695
+ if (is_array($options) && count($options)
696
+ && ($dataType == self::FIELD_TYPE_SELECT_ONE || $dataType == self::FIELD_TYPE_SELECT_MANY)
697
+ ){
698
+ $params['Options'] = $options;
699
+ }
700
+
701
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
702
+ $helper = Mage::helper("createsend");
703
+
704
+ $listId = $helper->getScopedConfig($helper::XML_PATH_LIST_ID, $scope, $scopeId);
705
+
706
+ return $this->call(
707
+ Zend_Http_Client::POST,
708
+ "lists/{$listId}/customfields",
709
+ $params,
710
+ array(),
711
+ $scope,
712
+ $scopeId
713
+ );
714
+ }
715
+
716
+ /**
717
+ * Creates Campaign Monitor customer custom fields on the list id defined in the scope.
718
+ *
719
+ * @param string $scope
720
+ * @param int $scopeId
721
+ * @return array List of errors, grouped by error message
722
+ */
723
+ public function createCustomerCustomFields($scope, $scopeId)
724
+ {
725
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
726
+ $helper = Mage::helper('createsend');
727
+
728
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
729
+ $scopeModel = Mage::getSingleton('createsend/config_scope');
730
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
731
+
732
+ /** @var Campaignmonitor_Createsend_Model_Config_CustomerAttributes $attrSource */
733
+ $attrSource = Mage::getSingleton('createsend/config_customerAttributes');
734
+
735
+ $linkedAttributes = @unserialize(Mage::getStoreConfig($helper::XML_PATH_M_TO_CM_ATTRIBUTES, $storeId));
736
+
737
+ $errors = array();
738
+
739
+ foreach ($linkedAttributes as $la) {
740
+ $magentoAtt = $la['magento'];
741
+ $cmAtt = $attrSource->getCustomFieldName($la['magento'], true);
742
+ $dataType = $attrSource->getFieldType($magentoAtt);
743
+ $options = $attrSource->getFieldOptions($magentoAtt);
744
+
745
+ $reply = $this->createCustomField(
746
+ $cmAtt,
747
+ $dataType,
748
+ $options,
749
+ false,
750
+ $scope,
751
+ $scopeId
752
+ );
753
+
754
+ if ($reply['success'] === false) {
755
+ // Ignore 'field name already exists' errors
756
+ if ($reply['data']['Code'] != self::CODE_FIELD_KEY_EXISTS) {
757
+ $message = $reply['data']['Message'];
758
+
759
+ if (!isset($errors[$message])) {
760
+ $errors[$message] = array();
761
+ }
762
+
763
+ $errors[$message][] = $this->formatCustomFieldName($cmAtt);
764
+ }
765
+ }
766
+ }
767
+
768
+ return $errors;
769
+ }
770
+
771
+ /**
772
+ * Creates Campaign Monitor wishlist custom fields on the list id defined in the scope.
773
+ *
774
+ * @param string $scope
775
+ * @param int $scopeId
776
+ * @return array List of errors, grouped by error message
777
+ */
778
+ public function createWishlistCustomFields($scope, $scopeId)
779
+ {
780
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
781
+ $helper = Mage::helper('createsend');
782
+
783
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
784
+ $scopeModel = Mage::getSingleton('createsend/config_scope');
785
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
786
+
787
+ /** @var Campaignmonitor_Createsend_Model_Config_ProductAttributes $attrSource */
788
+ $attrSource = Mage::getSingleton('createsend/config_productAttributes');
789
+
790
+ // Create wishlist custom fields
791
+ $maxWishlistItems = $helper->getMaxWistlistItems($storeId);
792
+ $productAttributes = @unserialize(Mage::getStoreConfig($helper::XML_PATH_WISHLIST_PRODUCT_ATTRIBUTES, $storeId));
793
+
794
+ if (empty($productAttributes) && empty($maxWishlistItems)) {
795
+ return array();
796
+ }
797
+
798
+ $options = array();
799
+ $errors = array();
800
+
801
+ foreach ($productAttributes as $pa) {
802
+ $magentoAtt = $pa['magento'];
803
+ $cmAtt = $attrSource->getCustomFieldName($pa['magento'], true);
804
+ $dataType = $attrSource->getFieldType($magentoAtt);
805
+
806
+ for ($i = 1; $i <= $maxWishlistItems; $i++) {
807
+ $fieldName = sprintf(self::WISHLIST_CUSTOM_FIELD_PATTERN, self::WISHLIST_CUSTOM_FIELD_PREFIX, $i, $cmAtt);
808
+ $reply = $this->createCustomField(
809
+ $fieldName,
810
+ $dataType,
811
+ $options,
812
+ false,
813
+ $scope,
814
+ $scopeId
815
+ );
816
+
817
+ if ($reply['success'] === false) {
818
+ // Ignore 'field name already exists' errors
819
+ if ($reply['data']['Code'] != self::CODE_FIELD_KEY_EXISTS) {
820
+ $message = $reply['data']['Message'];
821
+
822
+ if (!isset($errors[$message])) {
823
+ $errors[$message] = array();
824
+ }
825
+
826
+ $errors[$message][] = $this->formatCustomFieldName($cmAtt);
827
+ }
828
+ }
829
+ }
830
+ }
831
+
832
+ return $errors;
833
+ }
834
+
835
+ /**
836
+ * Creates all the example segments as defined in Campaignmonitor_Createsend_Model_Config_ExampleSegments.
837
+ * Returns an array of status and message per segment creation call.
838
+ *
839
+ * @param string $scope
840
+ * @param int $scopeId
841
+ * @return array
842
+ */
843
+ public function createExampleSegments($scope, $scopeId)
844
+ {
845
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
846
+ $helper = Mage::helper("createsend");
847
+
848
+ $listId = $helper->getScopedConfig($helper::XML_PATH_LIST_ID, $scope, $scopeId);
849
+
850
+ $segments = Mage::getSingleton('createsend/config_exampleSegments')->getExampleSegments();
851
+
852
+ /** @var array $response */
853
+ $responses = array();
854
+
855
+ foreach ($segments as $segmentKey => $segment) {
856
+ $reply = $this->call(
857
+ Zend_Http_Client::POST,
858
+ 'segments/' . $listId,
859
+ $segment,
860
+ array(),
861
+ $scope,
862
+ $scopeId
863
+ );
864
+
865
+ $status = 'success';
866
+ if ($reply['success'] === false) {
867
+ $status = 'error';
868
+ $message = sprintf(self::ERR_UNABLE_TO_CREATE_SEGMENT, $segment['Title'], $reply['data']['Message']);
869
+ switch ($reply['data']['Code']) {
870
+ case self::CODE_DUPLICATE_SEGMENT_TITLE:
871
+ $status = 'warning';
872
+ $message .= ' -- ' . self::ERR_SEGMENT_EXISTS;
873
+ break;
874
+ case self::CODE_INVALID_SEGMENT_RULES:
875
+ $pos = strpos($segmentKey, ':');
876
+ if ($pos === FALSE) {
877
+ $requiredFields = $segmentKey;
878
+ } else {
879
+ $requiredFields = substr($segmentKey, $pos + 1);
880
+ }
881
+
882
+ $message .= ' -- ' . sprintf(self::ERR_CREATE_CUSTOM_FIELDS, $requiredFields);
883
+ break;
884
+ }
885
+ } else {
886
+ $message = sprintf(self::LOG_SEGMENT_CREATED, $segment['Title']);
887
+ }
888
+
889
+ $responses[] = array(
890
+ 'status' => $status,
891
+ 'message' => $message
892
+ );
893
+ }
894
+
895
+ return $responses;
896
+ }
897
+ }
app/code/community/Campaignmonitor/Createsend/Model/Api/Observer.php ADDED
@@ -0,0 +1,351 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Responsible for taking action using the api model as a result of some dispatched Magento event
20
+ */
21
+ class Campaignmonitor_Createsend_Model_Api_Observer
22
+ {
23
+ const ERR_CANNOT_CREATE_SUBSCRIBER = 'Api Error: Could not create subscription for "%s" ("%s")';
24
+ const ERR_NO_EMAIL_PARAMETER = 'There was no email parameter supplied in this request';
25
+
26
+ const MSG_CANNOT_CREATE_SUBSCRIBER = 'Could not create subscriber "%s": An api error occurred: %s';
27
+
28
+ const LOG_ADD_SUBSCRIBER = 'Adding newsletter subscription via frontend Sign up block for "%s"';
29
+ const LOG_CUSTOMER_NOT_LOGGED_IN = 'Not subscribed, customer is not logged in: "%s"';
30
+
31
+ const MSG_NEW_LIST_CREATED = 'New Campaign Monitor list created.';
32
+ const MSG_CONNECT_SUCCESS = 'Your Magento account has been successfully connected, please allow some time for your data to be synced.';
33
+ const MSG_PRE_CREATED_CONFIG = 'To help get you started we\'ve already mapped some of your subscriber data and created pre-packaged segments in Campaign Monitor, <a href="https://login.createsend.com/l" target="_blank">log in to your account</a> to check them out.';
34
+
35
+ const SUBSCRIBER_DEFAULT_NAME = '(Guest)';
36
+
37
+ /**
38
+ * Updates the Deactivate webhook on a config change based on the value of that config
39
+ *
40
+ * @param Varien_Event_Observer $observer
41
+ * @listen admin_system_config_changed_section_createsend_general
42
+ * @throws Mage_Core_Exception if the API returns a bad result
43
+ */
44
+ public function checkConfig(Varien_Event_Observer $observer)
45
+ {
46
+ list($scope, $scopeId) = Mage::getSingleton('createsend/config_scope')
47
+ ->_getScope($observer->getWebsite(), $observer->getStore());
48
+
49
+ $request = Mage::app()->getRequest();
50
+ $section = $request->getUserParam('section');
51
+ $website = $request->getUserParam('website');
52
+ $store = $request->getUserParam('store');
53
+
54
+ /** @var Mage_Core_Model_Config_Data $configData */
55
+ $configData = Mage::getModel('adminhtml/config_data')
56
+ ->setSection($section)
57
+ ->setWebsite($website)
58
+ ->setStore($store)
59
+ ->load();
60
+
61
+ // Do nothing unless there is a LIST ID configured for this scope.
62
+ if (!isset($configData[Campaignmonitor_Createsend_Helper_Data::XML_PATH_LIST_ID])) {
63
+ return;
64
+ }
65
+
66
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
67
+ $helper = Mage::helper('createsend');
68
+
69
+ $listId = $helper->getScopedConfig(Campaignmonitor_Createsend_Helper_Data::XML_PATH_LIST_ID, $scope, $scopeId);
70
+
71
+ // Create new list if requested
72
+ /** @var Campaignmonitor_Createsend_Helper_Api $apiHelper */
73
+ $apiHelper = Mage::helper('createsend/api');
74
+
75
+ if ($listId === $apiHelper::ID_CREATE_NEW_LIST
76
+ && isset($configData[Campaignmonitor_Createsend_Helper_Data::XML_PATH_NEW_LIST_NAME])) {
77
+
78
+ $newList = $configData[Campaignmonitor_Createsend_Helper_Data::XML_PATH_NEW_LIST_NAME];
79
+
80
+ /** @var $api Campaignmonitor_Createsend_Model_Api */
81
+ $api = Mage::getModel('createsend/api');
82
+
83
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $configScope */
84
+ $configScope = Mage::getSingleton('createsend/config_scope');
85
+ $storeId = $configScope->getStoreIdFromScope($scope, $scopeId);
86
+
87
+ $clientId = $helper->getApiClientId($storeId);
88
+ $params = array(
89
+ 'Title' => $newList
90
+ );
91
+ $reply = $api->call(
92
+ Zend_Http_Client::POST,
93
+ "lists/${clientId}",
94
+ $params,
95
+ array(),
96
+ $scope,
97
+ $scopeId
98
+ );
99
+
100
+ if ($reply['success'] === false) {
101
+ Mage::getSingleton('adminhtml/session')->addError(
102
+ sprintf($api::ERR_API_REQUEST, $reply['data']['Message'])
103
+ );
104
+ } else {
105
+ // Successfully created new list, save the List ID
106
+ $listId = $reply['data']['Message'];
107
+ Mage::getConfig()->saveConfig(Campaignmonitor_Createsend_Helper_Data::XML_PATH_LIST_ID, $listId, $scope, $scopeId);
108
+ }
109
+ }
110
+
111
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
112
+ $api = Mage::getModel('createsend/api');
113
+
114
+ // Check if API config is complete and complete list set up
115
+ if ($helper->isCompleteConfig($scope, $scopeId)) {
116
+ /** @var Campaignmonitor_Createsend_Helper_Config $configHelper */
117
+ $configHelper = Mage::helper('createsend/config');
118
+
119
+ $flagClass = 'createsend/config_listFlag';
120
+ $listFlagData = $configHelper->getFlagData($flagClass, $listId);
121
+ if ($listFlagData === FALSE) {
122
+ // Display message the first time list set up is complete
123
+ Mage::getSingleton('adminhtml/session')->addSuccess(self::MSG_CONNECT_SUCCESS);
124
+ Mage::getSingleton('adminhtml/session')->addSuccess(self::MSG_PRE_CREATED_CONFIG);
125
+
126
+ $listFlagData = array(
127
+ 'scope' => $scope,
128
+ 'scopeId' => $scopeId,
129
+ );
130
+
131
+ $configHelper->addFlagData($flagClass, $listId, $listFlagData);
132
+ }
133
+
134
+ if ($helper->isSubscriberSynchronisationEnabled()) {
135
+ // Set the flag to synchronise the list for the first time
136
+ if (!array_key_exists(Campaignmonitor_Createsend_Helper_Config::INDEX_INITIAL_SYNC, $listFlagData)) {
137
+ $listFlagData[Campaignmonitor_Createsend_Helper_Config::INDEX_INITIAL_SYNC] = Campaignmonitor_Createsend_Helper_Config::FLAG_STATUS_NEW;
138
+ $configHelper->addFlagData($flagClass, $listId, $listFlagData);
139
+ }
140
+ }
141
+
142
+ // Auto-create custom fields if not yet done for the List ID
143
+ if (!array_key_exists(Campaignmonitor_Createsend_Helper_Config::INDEX_CUSTOM_FIELDS, $listFlagData)
144
+ || $listFlagData[Campaignmonitor_Createsend_Helper_Config::INDEX_CUSTOM_FIELDS] === Campaignmonitor_Createsend_Helper_Config::FLAG_STATUS_NEW
145
+ ) {
146
+ $listFlagData[Campaignmonitor_Createsend_Helper_Config::INDEX_CUSTOM_FIELDS] = Campaignmonitor_Createsend_Helper_Config::FLAG_STATUS_PROCESSING;
147
+ $configHelper->addFlagData($flagClass, $listId, $listFlagData);
148
+
149
+ // Add default custom fields in configuration
150
+ /** @var Campaignmonitor_Createsend_Model_Customer_Observer $observer */
151
+ $observer = Mage::getModel('createsend/customer_observer');
152
+ $observer->createAllCustomFields($scope, $scopeId);
153
+
154
+ $listFlagData[Campaignmonitor_Createsend_Helper_Config::INDEX_CUSTOM_FIELDS] = Campaignmonitor_Createsend_Helper_Config::FLAG_STATUS_DONE;
155
+ $configHelper->addFlagData($flagClass, $listId, $listFlagData);
156
+ }
157
+
158
+ // Auto-create example segments if not yet done for the List ID
159
+ if (!array_key_exists(Campaignmonitor_Createsend_Helper_Config::INDEX_EXAMPLE_SEGMENTS, $listFlagData)
160
+ || $listFlagData[Campaignmonitor_Createsend_Helper_Config::INDEX_EXAMPLE_SEGMENTS] === Campaignmonitor_Createsend_Helper_Config::FLAG_STATUS_NEW
161
+ ) {
162
+ $listFlagData[Campaignmonitor_Createsend_Helper_Config::INDEX_EXAMPLE_SEGMENTS] = Campaignmonitor_Createsend_Helper_Config::FLAG_STATUS_PROCESSING;
163
+ $configHelper->addFlagData($flagClass, $listId, $listFlagData);
164
+
165
+ $responses = $api->createExampleSegments($scope, $scopeId);
166
+
167
+ foreach ($responses as $response) {
168
+ switch ($response['status']) {
169
+ case 'warning':
170
+ Mage::getSingleton('adminhtml/session')->addWarning($response['message']);
171
+ break;
172
+ case 'error':
173
+ Mage::getSingleton('adminhtml/session')->addError($response['message']);
174
+ break;
175
+ }
176
+ }
177
+
178
+ $listFlagData[Campaignmonitor_Createsend_Helper_Config::INDEX_EXAMPLE_SEGMENTS] = Campaignmonitor_Createsend_Helper_Config::FLAG_STATUS_DONE;
179
+ $configHelper->addFlagData($flagClass, $listId, $listFlagData);
180
+ }
181
+ }
182
+
183
+ $webhookId = $helper->getScopedConfig(Campaignmonitor_Createsend_Helper_Data::XML_PATH_WEBHOOK_ID, $scope, $scopeId);
184
+ $webhookEnabled = $helper->isWebhookEnabled($store);
185
+
186
+ // Create webhook if none found on this scope
187
+ if ($webhookEnabled && $webhookId === false) {
188
+ $result = $api->updateWebhooks($scope, $scopeId);
189
+ if ($result['success'] === false) {
190
+ Mage::throwException(
191
+ sprintf(Campaignmonitor_Createsend_Model_Api::ERR_CANNOT_UPDATE_WEBHOOK, $result['data']['Message'])
192
+ );
193
+ }
194
+ } else {
195
+ if (!$webhookEnabled && $webhookId !== false) {
196
+ // There is a stored webhook ID for this scope, but webhooks are disabled,
197
+ // so delete all registered webhooks for this scope
198
+ $api->deleteAllWebhooks($listId, $scope, $scopeId);
199
+ }
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Responsible for handling the updating of users in Campaign Monitor before they are updated in Magento.
205
+ *
206
+ * @param Varien_Event_Observer $observer
207
+ * @listen controller_action_predispatch_adminhtml_newsletter_subscriber_massUnsubscribe
208
+ */
209
+ public function massUnsubscribeUsers(Varien_Event_Observer $observer)
210
+ {
211
+ /** @var Mage_Core_Controller_Request_Http $request */
212
+ $subscribers = $observer->getControllerAction()->getRequest()->getPost('subscriber');
213
+ if (!is_array($subscribers)) {
214
+ Mage::getModel('adminhtml/session')
215
+ ->addNotice('Could not unsubscribe subscribers from Createsend: No subscribers selected');
216
+ return;
217
+ }
218
+
219
+ foreach ($subscribers as $subscriber) {
220
+ /** @var Mage_Newsletter_Model_Subscriber $newsletter */
221
+ $newsletter = Mage::getModel('newsletter/subscriber');
222
+ $newsletter->load($subscriber);
223
+
224
+ if ($newsletter->getCustomerId() != 0) {
225
+ // Registered customer
226
+ $scope = 'stores';
227
+ $scopeId = $newsletter->getStoreId();
228
+ } else {
229
+ if ($newsletter->getStoreId()) {
230
+ $scope = 'stores';
231
+ $scopeId = $newsletter->getStoreId();
232
+ } else {
233
+ // Guest user, use default scope (cannot get storeId from subscribeNewUser() observer)
234
+ $scope = 'default';
235
+ $scopeId = 0;
236
+ }
237
+ }
238
+
239
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
240
+ $scopeModel = Mage::getModel('createsend/config_scope');
241
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
242
+
243
+ Mage::getModel('createsend/api')->call(
244
+ Zend_Http_Client::POST,
245
+ "subscribers/" . Mage::helper('createsend')->getListId($storeId) . "/unsubscribe",
246
+ array(
247
+ 'EmailAddress' => $newsletter->getEmail()
248
+ ),
249
+ array(),
250
+ $scope,
251
+ $scopeId
252
+ );
253
+ }
254
+ }
255
+
256
+ /**
257
+ * Subscribes a new user when given a request event
258
+ *
259
+ * @param Varien_Event_Observer $observer
260
+ * @listen controller_action_predispatch_newsletter_subscriber_new
261
+ */
262
+ public function subscribeNewUser(Varien_Event_Observer $observer)
263
+ {
264
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
265
+ $helper = Mage::helper('createsend');
266
+ $email = $observer->getControllerAction()->getRequest()->getPost('email');
267
+
268
+ // If the parameter is missing, do nothing
269
+ if (!$email) {
270
+ $helper->log(self::ERR_NO_EMAIL_PARAMETER, Zend_Log::WARN);
271
+ return;
272
+ }
273
+
274
+ $subscriberData = array(
275
+ 'Name' => self::SUBSCRIBER_DEFAULT_NAME,
276
+ 'EmailAddress' => $email,
277
+ 'Resubscribe' => true,
278
+ 'RestartSubscriptionBasedAutoresponders' => true
279
+ );
280
+
281
+ // $observer scope always returns default/0
282
+ $scope = 'default';
283
+ $scopeId = 0;
284
+
285
+ /** @var Mage_Customer_Helper_Data $customerHelper */
286
+ $customerHelper = Mage::helper('customer');
287
+ if ($customerHelper->isLoggedIn()) {
288
+ /** @var Mage_Customer_Model_Customer $customerModel */
289
+ $customerModel = $customerHelper->getCustomer();
290
+ $subscriberData['Name'] = $customerModel->getName();
291
+ $subscriberData['CustomFields'] = Campaignmonitor_Createsend_Model_Customer_Observer::generateCustomFields($customerModel);
292
+
293
+ // Use store scope only if customer is using the same email address.
294
+ // Otherwise, use default/0 as above
295
+ if (strcasecmp($email, $customerModel->getEmail()) === 0) {
296
+ $scope = 'stores';
297
+ // TODO: use current store id?
298
+ $scopeId = $customerModel->getStoreId();
299
+ }
300
+ } else {
301
+ /** @var Mage_Customer_Model_Customer $customer */
302
+ $customer = Mage::getModel("customer/customer");
303
+ $customer->setWebsiteId(Mage::app()->getWebsite('admin')->getId());
304
+ $customer->loadByEmail($email);
305
+ $subscriberData['CustomFields'] = Campaignmonitor_Createsend_Model_Customer_Observer::generateCustomFields($customer);
306
+
307
+ if ($customer->getId()) {
308
+ // Do not subscribe to newsletter if customer is not logged in and a customer email is used.
309
+ // Magento does not subscribe a registered customer to newsletter if customer is not logged in.
310
+ $helper->log(sprintf(self::LOG_CUSTOMER_NOT_LOGGED_IN, $email), Zend_Log::WARN);
311
+
312
+ return;
313
+ } else {
314
+ $scope = 'stores';
315
+ $scopeId = Mage::app()->getStore()->getId();
316
+ }
317
+ }
318
+
319
+ $helper->log(sprintf(self::LOG_ADD_SUBSCRIBER, $email));
320
+
321
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
322
+ $scopeModel = Mage::getModel('createsend/config_scope');
323
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
324
+
325
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
326
+ $api = Mage::getModel('createsend/api');
327
+
328
+ $result = $api->call(
329
+ Zend_Http_Client::POST,
330
+ 'subscribers/' . $helper->getListId($storeId),
331
+ $subscriberData,
332
+ array(),
333
+ $scope,
334
+ $scopeId
335
+ );
336
+
337
+ if (!$result['success']) {
338
+ // We don't know what the API is going to return to the user. For safety we indicate to the user it was
339
+ // an API error, but log the API error as a warning.
340
+ Mage::getSingleton('core/session')->addError(
341
+ sprintf(self::MSG_CANNOT_CREATE_SUBSCRIBER, $email)
342
+ );
343
+
344
+ // Log more detailed information for debugging
345
+ $helper->log(
346
+ sprintf(self::ERR_CANNOT_CREATE_SUBSCRIBER, $email, $result['data']['Message']),
347
+ Zend_Log::WARN
348
+ );
349
+ }
350
+ }
351
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/Api.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Config_Api
19
+ {
20
+ /**
21
+ * @param Varien_Event_Observer $observer
22
+ */
23
+ public function addJavascriptBlock($observer)
24
+ {
25
+ $controller = $observer->getAction();
26
+ $layout = $controller->getLayout();
27
+
28
+ // Load only if in our section
29
+ $params = $controller->getRequest()->getParams();
30
+ if (array_key_exists('section', $params) && $params['section'] === 'createsend_general') {
31
+ $block = $layout->createBlock('adminhtml/template');
32
+ $block->setTemplate('campaignmonitor/createsend/apiclient.phtml');
33
+ $layout->getBlock('js')->append($block);
34
+ }
35
+ }
36
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/Attributes/Abstract.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ abstract class Campaignmonitor_Createsend_Model_Config_Attributes_Abstract
19
+ {
20
+ /** @var array $_fields */
21
+ protected $_fields;
22
+
23
+ /** @var array $_customFieldNameMapping Custom field name for Magento attributes ["magento" => "campaignmonitor"] */
24
+ protected $_customFieldNameMapping;
25
+
26
+ /**
27
+ * @return array
28
+ */
29
+ public function toOptionArray()
30
+ {
31
+ $optionArray = array();
32
+
33
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
34
+ $helper = Mage::helper('createsend');
35
+
36
+ foreach ($this->_fields as $key => $field) {
37
+ $optionArray[] = array('value' => $key, 'label' => $helper->__($field['label']));
38
+ }
39
+
40
+ return $optionArray;
41
+ }
42
+
43
+ /**
44
+ * Returns the field type for the attribute from the $_fields array.
45
+ * Returns null if not found.
46
+ *
47
+ * @param $field
48
+ * @return string|null
49
+ */
50
+ public function getFieldType($field)
51
+ {
52
+ if (isset($this->_fields[$field])) {
53
+ return $this->_fields[$field]['type'];
54
+ } else {
55
+ return null;
56
+ }
57
+ }
58
+
59
+ /**
60
+ * Returns the display/frontend name for the attribute from the $_fields array.
61
+ * Returns null if not found.
62
+ *
63
+ * @param $field
64
+ * @return string|null
65
+ */
66
+ public function getFieldLabel($field)
67
+ {
68
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
69
+ $helper = Mage::helper('createsend');
70
+
71
+ if (isset($this->_fields[$field])) {
72
+ return $helper->__($this->_fields[$field]['label']);
73
+ } else {
74
+ return null;
75
+ }
76
+ }
77
+
78
+ /**
79
+ * Returns an array of string options for the field.
80
+ * If the field is not a MultiSelectOne/MultiSelectMany, an empty array should be returned.
81
+ * This function should be overridden if the subclass has attributes that are select options.
82
+ *
83
+ * @param string $field
84
+ * @return array
85
+ */
86
+ public function getFieldOptions($field)
87
+ {
88
+ return array();
89
+ }
90
+
91
+ /**
92
+ * Returns the Campaign Monitor custom field name given the Magento attribute name.
93
+ *
94
+ * @param string $field The Magento attribute name
95
+ * @param bool $returnDefault If true, returns the default value. Otherwise, returns null.
96
+ * @return null|string
97
+ */
98
+ public function getCustomFieldName($field, $returnDefault = true)
99
+ {
100
+ if (array_key_exists($field, $this->_customFieldNameMapping)) {
101
+ return $this->_customFieldNameMapping[$field];
102
+ } else {
103
+ if ($returnDefault) {
104
+ return $field;
105
+ } else {
106
+ return null;
107
+ }
108
+ }
109
+ }
110
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/AuthenticationMethod.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Campaign Monitor authentication type selector
20
+ *
21
+ */
22
+ class Campaignmonitor_Createsend_Model_Config_AuthenticationMethod
23
+ {
24
+ const AUTHENTICATION_METHOD_API_KEY = 'api_key';
25
+ const AUTHENTICATION_METHOD_OAUTH = 'oauth';
26
+
27
+ /**
28
+ * @return array
29
+ */
30
+ public function toOptionArray()
31
+ {
32
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
33
+ $helper = Mage::helper('createsend');
34
+ return array(
35
+ array(
36
+ 'value' => self::AUTHENTICATION_METHOD_API_KEY,
37
+ 'label' => $helper->__('API Key')
38
+ ),
39
+ array(
40
+ 'value' => self::AUTHENTICATION_METHOD_OAUTH,
41
+ 'label' => $helper->__('OAuth')
42
+ ),
43
+ );
44
+ }
45
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/Backend/Apikey.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Config_Backend_Apikey extends Mage_Core_Model_Config_Data
19
+ {
20
+ const ERR_INVALID_API_KEY = 'Invalid API Key: %s';
21
+ const MSG_VALID_API_KEY = 'Valid API Key.';
22
+ /**
23
+ *
24
+ * @return Mage_Core_Model_Abstract
25
+ */
26
+ protected function _afterSave()
27
+ {
28
+ $request = Mage::app()->getRequest();
29
+ $website = $request->getUserParam('website');
30
+ $store = $request->getUserParam('store');
31
+ list($scope, $scopeId) = Mage::getSingleton('createsend/config_scope')->_getScope($website, $store);
32
+
33
+ /** @var Campaignmonitor_Createsend_Helper_Api $apiHelper */
34
+ $apiHelper = Mage::helper('createsend/api');
35
+
36
+ // Test API Key by getting the list of clients
37
+ $reply = $apiHelper->testApiKey($scope, $scopeId);
38
+
39
+ if ($reply['success'] === false) {
40
+ Mage::getSingleton('adminhtml/session')->addError(
41
+ sprintf(self::ERR_INVALID_API_KEY, $reply['data']['Message'])
42
+ );
43
+ } else {
44
+ // Display success message only when value is changed
45
+ if ($this->isValueChanged()) {
46
+ Mage::getSingleton('adminhtml/session')->addSuccess(sprintf(self::MSG_VALID_API_KEY));
47
+ }
48
+ }
49
+
50
+ return parent::_afterSave();
51
+ }
52
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/Backend/Listid.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Config_Backend_Listid extends Mage_Core_Model_Config_Data
19
+ {
20
+ /**
21
+ * If the List ID value is changed, delete all webhooks associated with the old List ID
22
+ *
23
+ * @return Mage_Core_Model_Abstract
24
+ */
25
+ protected function _afterSave()
26
+ {
27
+ if ($this->isValueChanged()) {
28
+ $oldListId = $this->getOldValue();
29
+
30
+ $request = Mage::app()->getRequest();
31
+ $website = $request->getUserParam('website');
32
+ $store = $request->getUserParam('store');
33
+ list($scope, $scopeId) = Mage::getSingleton('createsend/config_scope')->_getScope($website, $store);
34
+
35
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
36
+ $api = Mage::getModel('createsend/api');
37
+
38
+ $api->deleteAllWebhooks($oldListId, $scope, $scopeId);
39
+ }
40
+
41
+ return parent::_afterSave();
42
+ }
43
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/ClientSelection.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Config_ClientSelection
19
+ {
20
+ /**
21
+ * @return array
22
+ */
23
+ public function toOptionArray()
24
+ {
25
+ return array();
26
+ }
27
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/ConflictResolutionMethod.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Campaign Monitor authentication type selector
20
+ *
21
+ */
22
+ class Campaignmonitor_Createsend_Model_Config_ConflictResolutionMethod
23
+ {
24
+ const RESOLUTION_METHOD_TIMESTAMP = 'timestamp';
25
+ const RESOLUTION_METHOD_SOURCE = 'source';
26
+
27
+ /**
28
+ * @return array
29
+ */
30
+ public function toOptionArray()
31
+ {
32
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
33
+ $helper = Mage::helper('createsend');
34
+ return array(
35
+ array(
36
+ 'value' => self::RESOLUTION_METHOD_TIMESTAMP,
37
+ 'label' => $helper->__('Timestamp')
38
+ ),
39
+ array(
40
+ 'value' => self::RESOLUTION_METHOD_SOURCE,
41
+ 'label' => $helper->__('Preferred Source')
42
+ ),
43
+ );
44
+ }
45
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/CustomerAttributes.php ADDED
@@ -0,0 +1,311 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Product attributes to be included in the custom fields to be sent to Campaign Monitor
20
+ *
21
+ */
22
+ class Campaignmonitor_Createsend_Model_Config_CustomerAttributes
23
+ extends Campaignmonitor_Createsend_Model_Config_Attributes_Abstract
24
+ {
25
+ const ADDRESS_FIELD_PREFIX = 'FONTIS-';
26
+
27
+ /** @var array $_customFieldNameMapping */
28
+ protected $_customFieldNameMapping = array(
29
+ 'confirmation' => 'Customer Email Is Confirmed',
30
+ 'created_at' => 'Customer Date Created',
31
+ 'created_in' => 'Customer Created From Store',
32
+ 'customer_activated' => 'Customer Account Activated',
33
+ 'dob' => 'Customer Date Of Birth',
34
+ 'firstname' => 'Customer First Name',
35
+ 'gender' => 'Customer Gender',
36
+ 'group_id' => 'Customer Group',
37
+ 'lastname' => 'Customer Last Name',
38
+ 'middlename' => 'Customer Middle Name',
39
+ 'prefix' => 'Customer Prefix',
40
+ 'store_id' => 'Store',
41
+ 'suffix' => 'Customer Suffix',
42
+ 'taxvat' => 'Customer Tax/VAT Number',
43
+ 'website_id' => 'Customer Website',
44
+ 'FONTIS-billing-firstname' => 'Billing Customer First Name',
45
+ 'FONTIS-billing-lastname' => 'Billing Customer Last Name',
46
+ 'FONTIS-shipping-firstname' => 'Shipping Customer First Name',
47
+ 'FONTIS-shipping-lastname' => 'Shipping Customer Last Name',
48
+ );
49
+
50
+ // Put all extra custom attributes here (Do not put billing and sales attributes here)
51
+ /** @var array $_extraAttributes */
52
+ protected $_extraAttributes = array(
53
+ 'FONTIS-has-account' => array(
54
+ 'label' => 'Has Customer Account',
55
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_SELECT_ONE,
56
+ 'options' => array('Yes', 'No')
57
+ ),
58
+ 'FONTIS-number-of-wishlist-items' => array(
59
+ 'label' => 'Number of Wishlist Items',
60
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_NUMBER
61
+ )
62
+ );
63
+
64
+ /** @var array $_excludedAttributes */
65
+ protected $_excludedAttributes = array(
66
+ 'entity_type_id',
67
+ 'entity_id',
68
+ 'attribute_set_id',
69
+ 'password_hash',
70
+ 'increment_id',
71
+ 'updated_at',
72
+ 'email',
73
+ 'default_billing',
74
+ 'default_shipping',
75
+ 'disable_auto_group_change',
76
+ 'rp_token',
77
+ 'rp_token_created_at',
78
+ );
79
+
80
+ // Attribute name to be displayed in Magento
81
+ /** @var array $_attributeNames */
82
+ protected $_attributeNames = array(
83
+ 'store_id' => 'Store',
84
+ 'group_id' => 'Customer Group',
85
+ 'website_id' => 'Website',
86
+ 'created_at' => 'Date Created',
87
+ );
88
+
89
+ /** @var array $_addressFields */
90
+ protected $_addressFields = array(
91
+ 'firstname' => 'First Name',
92
+ 'lastname' => 'Last Name',
93
+ 'company' => 'Company',
94
+ 'telephone' => 'Phone',
95
+ 'fax' => 'Fax',
96
+ 'street' => 'Street',
97
+ 'city' => 'City',
98
+ 'region_id' => 'State/Province',
99
+ 'postcode' => 'Zip/Postal Code',
100
+ 'country_id' => 'Country',
101
+ );
102
+
103
+ /** @var array $_addressTypes */
104
+ protected $_addressTypes = array(
105
+ 'billing' => 'Billing',
106
+ 'shipping' => 'Shipping',
107
+ );
108
+
109
+ /** @var array $_salesAttributes */
110
+ protected $_salesAttributes = array(
111
+ 'FONTIS-sales-last-order-value' => array(
112
+ 'label' => 'Last Order Value',
113
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_NUMBER
114
+ ),
115
+ 'FONTIS-sales-last-order-date' => array(
116
+ 'label' => 'Last Order Date',
117
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_DATE
118
+ ),
119
+ 'FONTIS-sales-average-order-value' => array(
120
+ 'label' => 'Average Order Value',
121
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_NUMBER
122
+ ),
123
+ 'FONTIS-sales-total-order-value' => array(
124
+ 'label' => 'Total Order Value',
125
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_NUMBER
126
+ ),
127
+ 'FONTIS-sales-total-number-of-orders' => array(
128
+ 'label' => 'Total Number Of Orders',
129
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_NUMBER
130
+ ),
131
+ 'FONTIS-sales-total-number-of-products-ordered' => array(
132
+ 'label' => 'Total Quantity Ordered',
133
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_NUMBER
134
+ ),
135
+ 'FONTIS-sales-first-order-date' => array(
136
+ 'label' => 'First Order Date',
137
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_DATE
138
+ ),
139
+ );
140
+
141
+ public function __construct()
142
+ {
143
+ $this->_fields = array();
144
+
145
+ // Add extra attributes
146
+ $this->_fields = array_merge($this->_fields, $this->_extraAttributes);
147
+
148
+ /** @var Mage_Customer_Model_Customer $customerModel */
149
+ $customerModel = Mage::getModel('customer/customer');
150
+ $magentoAttributes = $customerModel->getAttributes();
151
+
152
+ foreach (array_keys($magentoAttributes) as $att) {
153
+ $attribute = $customerModel->getAttribute($att);
154
+
155
+ if (!in_array($att, $this->_excludedAttributes)) {
156
+ $label = $attribute->getFrontendLabel();
157
+
158
+ // give nicer names to the attributes
159
+ if (isset($this->_attributeNames[$att])) {
160
+ $name = $this->_attributeNames[$att];
161
+ } elseif (!empty($label)) {
162
+ $name = $attribute->getFrontendLabel();
163
+ } else {
164
+ $name = $att;
165
+ }
166
+
167
+ // Get the attribute type for Campaign Monitor
168
+ if ($attribute->getFrontendInput() === 'date' || $attribute->getFrontendInput() === 'datetime') {
169
+ $type = Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_DATE;
170
+ } elseif ($attribute->getBackendType() == 'int' && $attribute->getFrontendInput() == 'text') {
171
+ $type = Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_NUMBER;
172
+ } elseif ($attribute->getBackendType() == 'decimal') {
173
+ $type = Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_NUMBER;
174
+ } elseif ($att == 'gender' || $att == 'confirmation') {
175
+ $type = Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_SELECT_ONE;
176
+ } elseif ($this->isBooleanAttribute($attribute)) {
177
+ $type = Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_SELECT_ONE;
178
+ } else {
179
+ $type = Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_TEXT;
180
+ }
181
+
182
+ // Populate the field list
183
+ $this->_fields[$att] = array(
184
+ 'label' => $name,
185
+ 'type' => $type
186
+ );
187
+ if ($type === Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_SELECT_ONE) {
188
+ if ($att == 'confirmation') {
189
+ $this->_fields[$att]['options'] = array('Yes', 'No');
190
+ } else {
191
+ $allOptions = $attribute->getSource()->getAllOptions(false);
192
+
193
+ $options = array();
194
+ foreach ($allOptions as $option) {
195
+ $options[] = $option['label'];
196
+ }
197
+
198
+ $this->_fields[$att]['options'] = $options;
199
+ }
200
+ }
201
+ }
202
+ }
203
+ asort($this->_fields);
204
+
205
+ $this->_fields = array_merge($this->_fields, $this->getAddressFields('Billing'));
206
+ $this->_fields = array_merge($this->_fields, $this->getAddressFields('Shipping'));
207
+
208
+ $this->_fields = array_merge($this->_fields, $this->_salesAttributes);
209
+ }
210
+
211
+ /**
212
+ * Returns true if the attribute type is boolean based on source model.
213
+ * Returns false otherwise.
214
+ *
215
+ * @param Mage_Customer_Model_Entity_Attribute $attribute
216
+ * @return bool
217
+ */
218
+ public function isBooleanAttribute($attribute)
219
+ {
220
+ return $attribute->getSourceModel()
221
+ && $attribute->getSourceModel() == 'eav/entity_attribute_source_boolean';
222
+ }
223
+
224
+ /**
225
+ * Returns all attribute option labels in an array
226
+ *
227
+ * @param string $field
228
+ * @return array
229
+ */
230
+ public function getFieldOptions($field)
231
+ {
232
+ if (array_key_exists($field, $this->_fields)
233
+ && $this->_fields[$field]['type'] == Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_SELECT_ONE) {
234
+
235
+ return $this->_fields[$field]['options'];
236
+ } else {
237
+ return array();
238
+ }
239
+ }
240
+
241
+ /**
242
+ * Returns an array of address attributes based on address type
243
+ *
244
+ * @param string $addressType "Billing" or "Shipping"
245
+ * @return array
246
+ */
247
+ protected function getAddressFields($addressType)
248
+ {
249
+ $fields = array();
250
+
251
+ foreach ($this->_addressFields as $att => $label) {
252
+ $fields[self::ADDRESS_FIELD_PREFIX . strtolower($addressType) . '-' . $att] = array(
253
+ 'label' => sprintf('%s Address: %s', $addressType, $label),
254
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_TEXT
255
+ );
256
+ }
257
+
258
+ return $fields;
259
+ }
260
+
261
+ /**
262
+ * Returns the Campaign Monitor custom field name given the Magento attribute name.
263
+ *
264
+ * @param string $field The Magento attribute name
265
+ * @param bool $returnDefault If true, returns the default value. Otherwise, returns null.
266
+ * @return null|string
267
+ */
268
+ public function getCustomFieldName($field, $returnDefault = true)
269
+ {
270
+ $custom = parent::getCustomFieldName($field, false);
271
+ if ($custom !== null) {
272
+ return $custom;
273
+ }
274
+
275
+ if (array_key_exists($field, $this->_attributeNames)) {
276
+ return $this->_attributeNames[$field];
277
+ }
278
+
279
+ if (array_key_exists($field, $this->_extraAttributes)) {
280
+ return $this->_extraAttributes[$field]['label'];
281
+ }
282
+
283
+ if (array_key_exists($field, $this->_salesAttributes)) {
284
+ return $this->_salesAttributes[$field]['label'];
285
+ }
286
+
287
+ foreach ($this->_addressTypes as $addressType => $addressTypeLabel) {
288
+ $typePrefix = self::ADDRESS_FIELD_PREFIX . $addressType . '-';
289
+
290
+ // Check if the field is one of these address types
291
+ if (0 === strpos($field, $typePrefix)) {
292
+ // Remove the prefix from the field name
293
+ $addressField = substr($field, strlen($typePrefix));
294
+
295
+ if (array_key_exists($addressField, $this->_addressFields)) {
296
+ $addressFieldLabel = $this->_addressFields[$addressField];
297
+
298
+ return sprintf('%s %s', $addressTypeLabel, $addressFieldLabel);
299
+ } else {
300
+ return sprintf('%s %s', $addressTypeLabel, ucwords($addressField));
301
+ }
302
+ }
303
+ }
304
+
305
+ if ($returnDefault) {
306
+ return ucwords($field);
307
+ } else {
308
+ return null;
309
+ }
310
+ }
311
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/DefaultCustomFields.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Config_DefaultCustomFields
19
+ {
20
+ protected $_defaultCustomerAttributes = array(
21
+ 'FONTIS-has-account',
22
+ 'created_in',
23
+ 'group_id',
24
+ 'created_at',
25
+ 'firstname',
26
+ 'lastname',
27
+ 'dob',
28
+ 'gender',
29
+ 'confirmation',
30
+ 'website_id',
31
+ 'store_id',
32
+ 'FONTIS-sales-average-order-value',
33
+ 'FONTIS-sales-first-order-date',
34
+ 'FONTIS-sales-last-order-value',
35
+ 'FONTIS-sales-last-order-date',
36
+ 'FONTIS-sales-total-order-value',
37
+ 'FONTIS-sales-total-number-of-orders',
38
+ 'FONTIS-sales-total-number-of-products-ordered',
39
+ 'FONTIS-number-of-wishlist-items',
40
+ );
41
+
42
+ protected $_defaultProductAttributes = array(
43
+ 'name',
44
+ 'price',
45
+ 'short_description',
46
+ 'sku',
47
+ );
48
+
49
+ public function getDefaultCustomerAttributes()
50
+ {
51
+ return $this->_defaultCustomerAttributes;
52
+ }
53
+
54
+ public function getDefaultProductAttributes()
55
+ {
56
+ return $this->_defaultProductAttributes;
57
+ }
58
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/ExampleSegments.php ADDED
@@ -0,0 +1,218 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Config_ExampleSegments
19
+ {
20
+ /**
21
+ * Returns Example Segments to be created in Campaign Monitor
22
+ *
23
+ * The keys of the return array correspond to the custom field(s) that are required for
24
+ * creating the example segment.
25
+ *
26
+ * The array keys should be in the format: [<Rule name> :] <RequireField1> [, <RequiredField2> [...]]
27
+ * The Rule name along with the colon (:) can be omitted if the required fields combination is unique.
28
+ *
29
+ * The required fields will be displayed to the user along with the error message
30
+ * when the segment creation results in a CODE_INVALID_SEGMENT_RULES error
31
+ * (happens when custom fields are non-existent) to let the user know
32
+ * which fields are missing.
33
+ *
34
+ * See Campaign Monitor API for segment definition format:
35
+ *
36
+ * @link https://www.campaignmonitor.com/api/segments/
37
+ *
38
+ * @return array
39
+ */
40
+ public function getExampleSegments()
41
+ {
42
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
43
+ $api = Mage::getModel('createsend/api');
44
+
45
+ /** @var Campaignmonitor_Createsend_Model_Config_CustomerAttributes $customerAttributes */
46
+ $customerAttributes = Mage::getSingleton('createsend/config_customerAttributes');
47
+
48
+ $cmHasCustomerAccount = $api->formatCustomFieldName(
49
+ $customerAttributes->getCustomFieldName('FONTIS-has-account', true)
50
+ );
51
+ $cmAverageOrderValue = $api->formatCustomFieldName(
52
+ $customerAttributes->getCustomFieldName('FONTIS-sales-average-order-value', true)
53
+ );
54
+ $cmTotalNumberOfOrders = $api->formatCustomFieldName(
55
+ $customerAttributes->getCustomFieldName('FONTIS-sales-total-number-of-orders', true)
56
+ );
57
+ $cmTotalOrderValue = $api->formatCustomFieldName(
58
+ $customerAttributes->getCustomFieldName('FONTIS-sales-total-order-value', true)
59
+ );
60
+ $cmCustomerGender = $api->formatCustomFieldName(
61
+ $customerAttributes->getCustomFieldName('gender', true)
62
+ );
63
+ $cmWishlistItemCount = $api->formatCustomFieldName(
64
+ $customerAttributes->getCustomFieldName('FONTIS-number-of-wishlist-items', true)
65
+ );
66
+
67
+ $sampleSegments = array(
68
+ "All subscribers: $cmHasCustomerAccount" => array(
69
+ 'Title' => 'All subscribers',
70
+ 'RuleGroups' => array(
71
+ array(
72
+ 'Rules' => array(
73
+ array(
74
+ 'RuleType' => $cmHasCustomerAccount,
75
+ 'Clause' => 'EQUALS Yes'
76
+ )
77
+ )
78
+ )
79
+ )
80
+ ),
81
+ "Big spenders: $cmAverageOrderValue" => array(
82
+ 'Title' => 'Big spenders',
83
+ 'RuleGroups' => array(
84
+ array(
85
+ 'Rules' => array(
86
+ array(
87
+ 'RuleType' => $cmAverageOrderValue,
88
+ 'Clause' => 'GREATER_THAN_OR_EQUAL 500'
89
+ )
90
+ )
91
+ )
92
+ )
93
+ ),
94
+ "Frequent Buyers: $cmTotalNumberOfOrders" => array(
95
+ 'Title' => 'Frequent Buyers',
96
+ 'RuleGroups' => array(
97
+ array(
98
+ 'Rules' => array(
99
+ array(
100
+ 'RuleType' => $cmTotalNumberOfOrders,
101
+ 'Clause' => 'GREATER_THAN_OR_EQUAL 5'
102
+ )
103
+ )
104
+ )
105
+ )
106
+ ),
107
+ "VIPs: $cmTotalNumberOfOrders, $cmTotalOrderValue" => array(
108
+ 'Title' => 'VIPs',
109
+ 'RuleGroups' => array(
110
+ array(
111
+ 'Rules' => array(
112
+ array(
113
+ 'RuleType' => $cmTotalNumberOfOrders,
114
+ 'Clause' => 'GREATER_THAN_OR_EQUAL 5'
115
+ )
116
+ )
117
+ ),
118
+ array(
119
+ 'Rules' => array(
120
+ array(
121
+ 'RuleType' => $cmTotalOrderValue,
122
+ 'Clause' => 'GREATER_THAN_OR_EQUAL 500'
123
+ )
124
+ )
125
+ )
126
+ )
127
+ ),
128
+ "Subscribers that haven’t purchased: $cmHasCustomerAccount, $cmTotalNumberOfOrders" => array(
129
+ 'Title' => 'Subscribers that haven’t purchased',
130
+ 'RuleGroups' => array(
131
+ array(
132
+ 'Rules' => array(
133
+ array(
134
+ 'RuleType' => $cmHasCustomerAccount,
135
+ 'Clause' => 'EQUALS Yes'
136
+ )
137
+ )
138
+ ),
139
+ array(
140
+ 'Rules' => array(
141
+ array(
142
+ 'RuleType' => $cmTotalNumberOfOrders,
143
+ 'Clause' => 'EQUALS 0'
144
+ )
145
+ )
146
+ )
147
+ )
148
+ ),
149
+ "First time customers: $cmTotalNumberOfOrders" => array(
150
+ 'Title' => 'First time customers',
151
+ 'RuleGroups' => array(
152
+ array(
153
+ 'Rules' => array(
154
+ array(
155
+ 'RuleType' => $cmTotalNumberOfOrders,
156
+ 'Clause' => 'EQUALS 1'
157
+ )
158
+ )
159
+ )
160
+ )
161
+ ),
162
+ "All customers: $cmTotalNumberOfOrders" => array(
163
+ 'Title' => 'All customers',
164
+ 'RuleGroups' => array(
165
+ array(
166
+ 'Rules' => array(
167
+ array(
168
+ 'RuleType' => $cmTotalNumberOfOrders,
169
+ 'Clause' => 'GREATER_THAN_OR_EQUAL 1'
170
+ )
171
+ )
172
+ )
173
+ )
174
+ ),
175
+ "Customers with a wishlist: $cmWishlistItemCount" => array(
176
+ 'Title' => 'Customers with a wishlist',
177
+ 'RuleGroups' => array(
178
+ array(
179
+ 'Rules' => array(
180
+ array(
181
+ 'RuleType' => $cmWishlistItemCount,
182
+ 'Clause' => 'GREATER_THAN_OR_EQUAL 1'
183
+ )
184
+ )
185
+ )
186
+ )
187
+ ),
188
+ "Males: $cmCustomerGender" => array(
189
+ 'Title' => 'Males',
190
+ 'RuleGroups' => array(
191
+ array(
192
+ 'Rules' => array(
193
+ array(
194
+ 'RuleType' => $cmCustomerGender,
195
+ 'Clause' => 'EQUALS Male'
196
+ )
197
+ )
198
+ )
199
+ )
200
+ ),
201
+ "Females: $cmCustomerGender" => array(
202
+ 'Title' => 'Females',
203
+ 'RuleGroups' => array(
204
+ array(
205
+ 'Rules' => array(
206
+ array(
207
+ 'RuleType' => $cmCustomerGender,
208
+ 'Clause' => 'EQUALS Female'
209
+ )
210
+ )
211
+ )
212
+ )
213
+ ),
214
+ );
215
+
216
+ return $sampleSegments;
217
+ }
218
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/ListFlag.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Config_ListFlag extends Mage_Core_Model_Flag
19
+ {
20
+ protected $_flagCode = 'createsend_lists';
21
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/ListSelection.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Config_ListSelection
19
+ {
20
+ /**
21
+ * @return array
22
+ */
23
+ public function toOptionArray()
24
+ {
25
+ return array();
26
+ }
27
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/ProductAttributes.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Product attributes to be included in the custom fields to be sent to Campaign Monitor
20
+ *
21
+ */
22
+ class Campaignmonitor_Createsend_Model_Config_ProductAttributes
23
+ extends Campaignmonitor_Createsend_Model_Config_Attributes_Abstract
24
+ {
25
+ /** @var array $_customFieldNameMapping */
26
+ protected $_customFieldNameMapping = array(
27
+ // Define custom field names for product attributes here
28
+ // 'short_description'
29
+ );
30
+
31
+ protected $_fields = array(
32
+ 'name' => array(
33
+ 'label' => 'Name',
34
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_TEXT
35
+ ),
36
+ 'price' => array(
37
+ 'label' => 'Price',
38
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_NUMBER
39
+ ),
40
+ 'short_description' => array(
41
+ 'label' => 'Description',
42
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_TEXT
43
+ ),
44
+ 'sku' => array(
45
+ 'label' => 'SKU',
46
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_TEXT
47
+ ),
48
+ 'url_key' => array(
49
+ 'label' => 'URL Key',
50
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_TEXT
51
+ ),
52
+ 'url_path' => array(
53
+ 'label' => 'URL Path',
54
+ 'type' => Campaignmonitor_Createsend_Model_Api::FIELD_TYPE_TEXT
55
+ ),
56
+ );
57
+
58
+ /**
59
+ * Returns the Campaign Monitor custom field name given the Magento attribute name.
60
+ *
61
+ * @param string $field The Magento attribute name
62
+ * @param bool $returnDefault If true, returns the default value. Otherwise, returns null.
63
+ * @return null|string
64
+ */
65
+ public function getCustomFieldName($field, $returnDefault = true)
66
+ {
67
+ $custom = parent::getCustomFieldName($field, false);
68
+ if ($custom !== null) {
69
+ return $custom;
70
+ }
71
+
72
+ if (array_key_exists($field, $this->_fields)) {
73
+ return $this->_fields[$field]['label'];
74
+ }
75
+
76
+ if ($returnDefault) {
77
+ return ucwords($field);
78
+ } else {
79
+ return null;
80
+ }
81
+ }
82
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/Scope.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Provides _getScope function for getting scope and scope id given a website and/or store.
20
+ *
21
+ */
22
+ class Campaignmonitor_Createsend_Model_Config_Scope
23
+ {
24
+ /**
25
+ * Get the scope from $website or $store
26
+ *
27
+ * @param string $website
28
+ * @param string $store
29
+ * @return array
30
+ */
31
+ public function _getScope($website, $store)
32
+ {
33
+ // This code is duplicated from the _getScope method in adminhtml/core_config. It is duplicated because
34
+ // that method is protected and we have need to determine the scope using the same logic.
35
+ if ($store) {
36
+ $scope = 'stores';
37
+ $scopeId = (int)Mage::getConfig()->getNode('stores/' . $store . '/system/store/id');
38
+ } elseif ($website) {
39
+ $scope = 'websites';
40
+ $scopeId = (int)Mage::getConfig()->getNode('websites/' . $website . '/system/website/id');
41
+ } else {
42
+ $scope = 'default';
43
+ $scopeId = Mage_Core_Model_App::ADMIN_STORE_ID;
44
+ }
45
+
46
+ return array($scope, $scopeId);
47
+ }
48
+
49
+ /**
50
+ * Returns the Website Id given the scope/scopeId
51
+ *
52
+ * @param string $scope
53
+ * @param int $scopeId
54
+ * @return int
55
+ */
56
+ public function getWebsiteIdFromScope($scope, $scopeId)
57
+ {
58
+ $websiteId = Mage::app()->getStore(Mage_Core_Model_App::ADMIN_STORE_ID)->getWebsiteId();
59
+
60
+ if ($scope === 'websites') {
61
+ $websiteId = $scopeId;
62
+ } elseif ($scope === 'stores') {
63
+ $websiteId = Mage::app()->getStore($scopeId)->getWebsiteId();
64
+ }
65
+
66
+ return $websiteId;
67
+ }
68
+
69
+ /**
70
+ * Returns the Store Id given the scope/scopeId
71
+ *
72
+ * @param string $scope
73
+ * @param int $scopeId
74
+ * @return int
75
+ * @throws Mage_Core_Exception
76
+ */
77
+ public function getStoreIdFromScope($scope, $scopeId)
78
+ {
79
+ $storeId = Mage_Core_Model_App::ADMIN_STORE_ID;
80
+
81
+ if ($scope === 'websites') {
82
+ try {
83
+ $storeId = Mage::app()->getWebsite($scopeId)->getDefaultGroup()->getDefaultStoreId();
84
+ } catch (Exception $e) {
85
+ // Use admin store id as above
86
+ }
87
+ } elseif ($scope === 'stores') {
88
+ $storeId = $scopeId;
89
+ }
90
+
91
+ return $storeId;
92
+ }
93
+ }
app/code/community/Campaignmonitor/Createsend/Model/Config/SubscriptionSources.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Campaign Monitor authentication type selector
20
+ *
21
+ */
22
+ class Campaignmonitor_Createsend_Model_Config_SubscriptionSources
23
+ {
24
+ const SOURCE_CAMPAIGN_MONITOR = 'cm';
25
+ const SOURCE_MAGENTO = 'magento';
26
+
27
+ /**
28
+ * @return array
29
+ */
30
+ public function toOptionArray()
31
+ {
32
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
33
+ $helper = Mage::helper('createsend');
34
+ return array(
35
+ array(
36
+ 'value' => self::SOURCE_CAMPAIGN_MONITOR,
37
+ 'label' => $helper->__('Campaign Monitor')
38
+ ),
39
+ array(
40
+ 'value' => self::SOURCE_MAGENTO,
41
+ 'label' => $helper->__('Magento')
42
+ ),
43
+ );
44
+ }
45
+ }
app/code/community/Campaignmonitor/Createsend/Model/Cron.php ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ abstract class Campaignmonitor_Createsend_Model_Cron
19
+ {
20
+ const LOG_ITERATOR_START = 'Scope Iterator Start.';
21
+ const LOG_ITERATOR_END = 'Scope Iterator End.';
22
+ const LOG_ITERATOR_ITEM = 'Calling %1$s for %2$s...';
23
+
24
+ /**
25
+ * The method to register in config.xml for Magento cron.
26
+ * Only executes the runJob method if cron is enabled in configuration.
27
+ */
28
+ public function runFromMagentoCron()
29
+ {
30
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
31
+ $helper = Mage::helper('createsend');
32
+
33
+ $useMagentoCron = $helper->isMagentoCronEnabled(Mage_Core_Model_App::ADMIN_STORE_ID);
34
+
35
+ if ($useMagentoCron) {
36
+ $this->runJob();
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Subclasses must implement this method which will be executed if cron is enabled
42
+ *
43
+ * @return mixed
44
+ */
45
+ abstract function runJob();
46
+
47
+ /**
48
+ * Executes function(s) in $functions array for all scopes where $configPath configuration value is defined
49
+ * (not inherited) and $helper->$helperConfig($storeId) is true.
50
+ *
51
+ * Passes the values for the configuration value for $configPath ($configValue), $scope and $scopeId
52
+ * to the function(s), in this order.
53
+ *
54
+ * $functions array should be in the form of:
55
+ *
56
+ * <pre>
57
+ * array(
58
+ * array(
59
+ * 'class' => $object,
60
+ * 'method' => 'method1',
61
+ * ),
62
+ * array(
63
+ * 'class' => $object,
64
+ * 'method' => 'method2',
65
+ * ),
66
+ * )
67
+ * </pre>
68
+ *
69
+ * @param string $configPath The path to the configuration value, eg. 'createsend_general/api/list_id'
70
+ * @param string $helperConfigChecker The name of the helper method which determines if the function(s) should
71
+ * should be executed for the particular scope/scopeId
72
+ * @param array $functions An array of object and method pair(s) to execute by calling call_user_func_array()
73
+ */
74
+ public function iterateScopes($configPath, $helperConfigChecker, array $functions = array())
75
+ {
76
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
77
+ $helper = Mage::helper('createsend');
78
+
79
+ $helper->log(self::LOG_ITERATOR_START);
80
+
81
+ // Get all scopes where List ID is defined (not inherited)
82
+ $configModel = Mage::getModel('core/config_data')->getCollection()
83
+ ->addFieldToFilter('path', $configPath)
84
+ ->addFieldToSelect('value')
85
+ ->addFieldToSelect('scope')
86
+ ->addFieldToSelect('scope_id');
87
+
88
+ foreach ($configModel as $config) {
89
+ $configValue = $config->getValue();
90
+ $scope = $config->getScope();
91
+ $scopeId = $config->getScopeId();
92
+
93
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
94
+ $scopeModel = Mage::getModel('createsend/config_scope');
95
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
96
+
97
+ $configEnabled = call_user_func_array(array($helper, $helperConfigChecker), array($storeId));
98
+ if ($configEnabled) {
99
+ foreach ($functions as $function) {
100
+ $object = $function['class'];
101
+ $method = $function['method'];
102
+
103
+ $helper->log(sprintf(self::LOG_ITERATOR_ITEM, $method, $configValue));
104
+
105
+ call_user_func_array(
106
+ array($object, $method),
107
+ array($configValue, $scope, $scopeId)
108
+ );
109
+ }
110
+ }
111
+ }
112
+
113
+ $helper->log(self::LOG_ITERATOR_END);
114
+ }
115
+ }
app/code/community/Campaignmonitor/Createsend/Model/Customer/Observer.php ADDED
@@ -0,0 +1,545 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Responsible for taking action on Createsend as a result of some customer action.
20
+ */
21
+ class Campaignmonitor_Createsend_Model_Customer_Observer
22
+ {
23
+ const MSG_CUSTOM_FIELDS_CREATED = 'Campaign Monitor custom fields created.';
24
+ const MSG_CANNOT_DELETE_CORE_CUSTOM_FIELDS = 'You cannot remove a core custom field. Core custom fields restored.';
25
+ const MSG_DUPLICATE_CUSTOMER_FIELDS = 'You have defined duplicate customer attributes: %s';
26
+ const MSG_DUPLICATE_PRODUCT_FIELDS = 'You have defined duplicate wishlist product attributes: %s';
27
+
28
+
29
+ /**
30
+ * Updates the subscription status of a user on campaign monitor based on user data in Magento
31
+ *
32
+ * @param Varien_Event_Observer $observer
33
+ * @listen customer_save_before
34
+ * @listen sales_order_save_after
35
+ * @listen wishlist_product_add_after
36
+ */
37
+ public function checkSubscriptionStatus($observer)
38
+ {
39
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
40
+ $helper = Mage::helper("createsend");
41
+ $event = $observer->getEvent();
42
+ /** @var Mage_Customer_Model_Customer $customer */
43
+ $customer = $event->getCustomer();
44
+
45
+ if (!$customer) {
46
+ $order = $event->getOrder();
47
+ if ($order) {
48
+ $customerId = $order->getCustomerId();
49
+
50
+ if (!$customerId) {
51
+ return;
52
+ }
53
+
54
+ $customer = Mage::getModel('customer/customer')->load($customerId);
55
+ } else {
56
+ $eventData = $event->getData();
57
+ $items = $eventData['items'];
58
+
59
+ if (count($items) > 0) {
60
+ /** @var Mage_Wishlist_Model_Item $item */
61
+ $item = $items[0];
62
+ $itemData = $item->getData();
63
+ /** @var Mage_Wishlist_Model_Wishlist $wishlist */
64
+ $wishlist = $itemData['wishlist'];
65
+ $wishlistData = $wishlist->getData();
66
+ $customerId = $wishlistData['customer_id'];
67
+
68
+ if (!$customerId) {
69
+ return;
70
+ }
71
+
72
+ $customer = Mage::getModel('customer/customer')->load($customerId);
73
+ }
74
+ }
75
+ }
76
+
77
+ $name = $customer->getName();
78
+ $newEmail = $customer->getEmail();
79
+ $subscribed = $customer->getIsSubscribed();
80
+ $oldEmail = Mage::getModel('customer/customer')->load($customer->getId())->getEmail();
81
+
82
+ // if subscribed is NULL (i.e. because the form didn't set it one way
83
+ // or the other), get the existing value from the database
84
+ if ($subscribed === null) {
85
+ $subscribed = Mage::getModel('newsletter/subscriber')->loadByCustomer($customer)->isSubscribed();
86
+ }
87
+
88
+ $customFields = Campaignmonitor_Createsend_Model_Customer_Observer::generateCustomFields($customer);
89
+
90
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
91
+ $api = Mage::getModel('createsend/api');
92
+
93
+ $scope = 'stores';
94
+ $scopeId = $customer->getStoreId();
95
+
96
+ $storeId = $customer->getStoreId();
97
+
98
+ if ($subscribed) {
99
+ /* If the customer either:
100
+ 1) Already exists (i.e. has an old email address)
101
+ 2) Has changed their email address
102
+ unsubscribe their old address. */
103
+ if ($oldEmail && $newEmail !== $oldEmail) {
104
+ $api->call(
105
+ Zend_Http_Client::POST,
106
+ "subscribers/{$helper->getListId($storeId)}/unsubscribe",
107
+ array(
108
+ 'EmailAddress' => $oldEmail
109
+ ),
110
+ array(),
111
+ $scope,
112
+ $scopeId
113
+ );
114
+ }
115
+
116
+ // Resubscribing during the adding process; otherwise someone who was unsubscribed will remain unsubscribed
117
+ $api->call(
118
+ Zend_Http_Client::POST,
119
+ 'subscribers/' . $helper->getListId($storeId),
120
+ array(
121
+ 'EmailAddress' => $newEmail,
122
+ 'Name' => $name,
123
+ 'CustomFields' => $customFields,
124
+ 'Resubscribe' => true,
125
+ 'RestartSubscriptionBasedAutoresponders' => true
126
+ ),
127
+ array(),
128
+ $scope,
129
+ $scopeId
130
+ );
131
+
132
+ } else {
133
+ $api->call(
134
+ Zend_Http_Client::POST,
135
+ "subscribers/{$helper->getListId($storeId)}/unsubscribe",
136
+ array(
137
+ 'EmailAddress' => $oldEmail
138
+ ),
139
+ array(),
140
+ $scope,
141
+ $scopeId
142
+ );
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Unsubscribes a customer when they are deleted.
148
+ *
149
+ * @param Varien_Event_Observer $observer
150
+ * @listen customer_delete_before
151
+ */
152
+ public function customerDeleted($observer)
153
+ {
154
+ $customer = $observer->getEvent()->getCustomer();
155
+ $email = $customer->getEmail();
156
+
157
+ $scope = 'stores';
158
+ $scopeId = $customer->getStoreId();
159
+
160
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
161
+ $api = Mage::getModel('createsend/api');
162
+
163
+ $api->unsubscribe($email, $scope, $scopeId);
164
+ }
165
+
166
+ /**
167
+ * Creates custom fields in Campaign Monitor based on custom field mapping defined by Magento admin
168
+ *
169
+ * @param Varien_Event_Observer $observer
170
+ * @listen admin_system_config_changed_section_createsend_customer
171
+ * @throws Mage_Core_Exception if the API returns a bad result
172
+ */
173
+ public function createCustomFields(Varien_Event_Observer $observer)
174
+ {
175
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
176
+ $scopeModel = Mage::getSingleton('createsend/config_scope');
177
+ list($scope, $scopeId) = $scopeModel->_getScope($observer->getWebsite(), $observer->getStore());
178
+
179
+ /** @var Campaignmonitor_Createsend_Helper_Config $apiHelper */
180
+ $apiHelper = Mage::helper('createsend/config');
181
+
182
+ // Check that there haven't been duplicate custom fields
183
+ $duplicateCustomerAttributes = $apiHelper->getDuplicateAttributes(
184
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_M_TO_CM_ATTRIBUTES,
185
+ $scope,
186
+ $scopeId
187
+ );
188
+ if (count($duplicateCustomerAttributes)) {
189
+ // Show warning if admin tries to add the same custom field multiple times
190
+ Mage::getSingleton('adminhtml/session')->addWarning(
191
+ sprintf(
192
+ self::MSG_DUPLICATE_CUSTOMER_FIELDS,
193
+ implode(
194
+ ', ',
195
+ $this->getAttributeLabels($duplicateCustomerAttributes, 'createsend/config_customerAttributes')
196
+ )
197
+ )
198
+ );
199
+ }
200
+
201
+ // Check that there haven't been duplicate product fields
202
+ $duplicateProductAttributes = $apiHelper->getDuplicateAttributes(
203
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_WISHLIST_PRODUCT_ATTRIBUTES,
204
+ $scope,
205
+ $scopeId
206
+ );
207
+ if (count($duplicateProductAttributes)) {
208
+ // Show warning if admin tries to add the same custom product field multiple times
209
+ Mage::getSingleton('adminhtml/session')->addWarning(
210
+ sprintf(
211
+ self::MSG_DUPLICATE_PRODUCT_FIELDS,
212
+ implode(
213
+ ', ',
214
+ $this->getAttributeLabels($duplicateProductAttributes, 'createsend/config_productAttributes')
215
+ )
216
+ )
217
+ );
218
+ }
219
+
220
+ // Do not allow deleting of default/'core' custom fields
221
+ $newFieldCount = $apiHelper->createDefaultCustomFields($scope, $scopeId);
222
+ if ($newFieldCount > 0) {
223
+ // Show warning message when a default/core custom field was attempted to be deleted
224
+ Mage::getSingleton('adminhtml/session')->addWarning(self::MSG_CANNOT_DELETE_CORE_CUSTOM_FIELDS);
225
+ }
226
+
227
+ if ($observer->hasDataChanges()) {
228
+ // Create customer custom fields
229
+ $this->createAllCustomFields($scope, $scopeId);
230
+ }
231
+ }
232
+
233
+ /**
234
+ * Returns all the attribute labels for the list of attributes in $attributes
235
+ * using the source model $classSpec
236
+ *
237
+ * @param array $attributes List of customer/product attributes
238
+ * @param string $classSpec of class Campaignmonitor_Createsend_Model_Config_Attributes_Abstract
239
+ * @return array
240
+ */
241
+ protected function getAttributeLabels($attributes, $classSpec)
242
+ {
243
+ /** @var Campaignmonitor_Createsend_Model_Config_Attributes_Abstract $source */
244
+ $source = Mage::getModel($classSpec);
245
+
246
+ $labels = array();
247
+ foreach ($attributes as $attribute) {
248
+ $labels[] = $source->getFieldLabel($attribute);
249
+ }
250
+
251
+ return $labels;
252
+ }
253
+
254
+ /**
255
+ * Creates custom fields in Campaign Monitor for the scope/scopeId
256
+ *
257
+ * @param string $scope
258
+ * @param int $scopeId
259
+ * @throws Mage_Core_Exception
260
+ */
261
+ public function createAllCustomFields($scope, $scopeId)
262
+ {
263
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
264
+ $helper = Mage::helper('createsend');
265
+
266
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
267
+ $api = Mage::getModel('createsend/api');
268
+
269
+ $customerErrors = $api->createCustomerCustomFields($scope, $scopeId);
270
+ $wishlistErrors = $api->createWishlistCustomFields($scope, $scopeId);
271
+
272
+ $errors = array_merge_recursive($customerErrors, $wishlistErrors);
273
+
274
+ if (count($errors)) {
275
+ foreach ($errors as $error => $fields) {
276
+ $errorMsg = sprintf(
277
+ $api::ERR_CANNOT_CREATE_CUSTOM_FIELD,
278
+ implode(', ', $fields),
279
+ $error
280
+ );
281
+
282
+ Mage::getSingleton('adminhtml/session')->addError($errorMsg);
283
+ }
284
+ }
285
+ }
286
+
287
+ /**
288
+ * Generate an array of custom fields based on a config setting and customer data.
289
+ * Customer data includes purchase and wish list products data.
290
+ *
291
+ * @param Mage_Customer_Model_Customer $customer
292
+ * @return array
293
+ */
294
+ public static function generateCustomFields($customer)
295
+ {
296
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
297
+ $helper = Mage::helper('createsend');
298
+
299
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
300
+ $api = Mage::getModel('createsend/api');
301
+
302
+ /** @var Campaignmonitor_Createsend_Model_Config_CustomerAttributes $attrSource */
303
+ $attrSource = Mage::getSingleton('createsend/config_customerAttributes');
304
+
305
+ if ($customer->getId()) {
306
+ $storeId = $customer->getStoreId();
307
+ } else {
308
+ $storeId = Mage_Core_Model_App::ADMIN_STORE_ID;
309
+ }
310
+ $linkedAttributes = @unserialize(Mage::getStoreConfig($helper::XML_PATH_M_TO_CM_ATTRIBUTES, $storeId));
311
+
312
+ $customFields = array();
313
+ if (!empty($linkedAttributes)) {
314
+ if ($customer->getId()) {
315
+ $customerData = $customer->getData();
316
+ } else {
317
+ $customerData = array();
318
+ }
319
+ foreach ($linkedAttributes as $la) {
320
+ $magentoAtt = $la['magento'];
321
+ $cmAtt = $api->formatCustomFieldName($attrSource->getCustomFieldName($la['magento'], true));
322
+
323
+ // try and translate IDs to names where possible
324
+ if ($magentoAtt == 'group_id') {
325
+ if ($customer->getId()) {
326
+ $d = Mage::getModel('customer/group')->load($customer->getGroupId())->getData();
327
+ if (array_key_exists('customer_group_code', $d)) {
328
+ $customFields[] = array("Key" => $cmAtt, "Value" => $d['customer_group_code']);
329
+ }
330
+ }
331
+ } elseif ($magentoAtt == 'website_id') {
332
+ if ($customer->getId()) {
333
+ $d = Mage::app()->getWebsite($customer->getWebsiteId())->getData();
334
+ if (array_key_exists('name', $d)) {
335
+ $customFields[] = array("Key" => $cmAtt, "Value" => $d['name']);
336
+ }
337
+ }
338
+ } elseif ($magentoAtt == 'store_id') {
339
+ if ($customer->getId()) {
340
+ $d = Mage::app()->getStore($customer->getStoreId())->getData();
341
+ if (array_key_exists('name', $d)) {
342
+ $customFields[] = array("Key" => $cmAtt, "Value" => $d['name']);
343
+ }
344
+ }
345
+ } elseif ($magentoAtt == 'gender') {
346
+ $gender = $customer->getAttribute($magentoAtt)->getSource()->getOptionText($customerData[$magentoAtt]);
347
+ $customFields[] = array("Key" => $cmAtt, "Value" => $gender);
348
+ } elseif ($magentoAtt == 'confirmation') {
349
+ // This attribute should have been named confirmation_key
350
+ // If not yet confirmed, this attribute will contain the confirmation key
351
+ // Once confirmed, this attribute will be empty
352
+ $confirmed = empty($customerData[$magentoAtt]) ? 'Yes' : 'No';
353
+ $customFields[] = array("Key" => $cmAtt, "Value" => $confirmed);
354
+ } elseif ($magentoAtt == 'FONTIS-has-account') {
355
+ if ($customer->getId()) {
356
+ $customFields[] = array('Key' => $cmAtt, 'Value' => 'Yes');
357
+ } else {
358
+ $customFields[] = array('Key' => $cmAtt, 'Value' => 'No');
359
+ }
360
+ } elseif ($magentoAtt == 'FONTIS-number-of-wishlist-items') {
361
+ if ($customer->getId()) {
362
+ /** @var Mage_Wishlist_Model_Wishlist $wishList */
363
+ $wishList = Mage::getModel('wishlist/wishlist')->loadByCustomer($customer);
364
+
365
+ $customFields[] = array('Key' => $cmAtt, 'Value' => $wishList->getItemsCount());
366
+ }
367
+ } elseif (strncmp('FONTIS-sales', $magentoAtt, 12) == 0) {
368
+ $purchaseData = array();
369
+
370
+ if ($customer->getId()) {
371
+ if (strncmp('FONTIS-sales-last-order', $magentoAtt, 23) == 0) {
372
+ // get last order
373
+ $lastOrder = self::_getEndOrder(
374
+ $customer->getId(), 'DESC', array(
375
+ 'grand_total',
376
+ 'created_at'
377
+ )
378
+ );
379
+ $purchaseData['last-order-value'] = $lastOrder->getGrandTotal();
380
+ $purchaseData['last-order-date'] = $lastOrder->getCreatedAt();
381
+ } elseif (strncmp('FONTIS-sales-first-order', $magentoAtt, 24) == 0) {
382
+ // get first order
383
+ $firstOrder = self::_getEndOrder($customer->getId(), 'ASC', array('created_at'));
384
+ $purchaseData['first-order-date'] = $firstOrder->getCreatedAt();
385
+ } else {
386
+ $orderCollection = Mage::getModel('sales/order')->getCollection()
387
+ ->addFieldToFilter('customer_id', $customer->getId())
388
+ ->addFieldToFilter('status', array('neq' => 'canceled'))
389
+ ->addAttributeToSelect('grand_total')
390
+ ->addAttributeToSelect('total_qty_ordered');
391
+
392
+ $orderTotals = $orderCollection->getColumnValues('grand_total');
393
+
394
+ // get total order value
395
+ $purchaseData['total-order-value'] = array_sum($orderTotals);
396
+
397
+ // get total number of orders
398
+ $purchaseData['total-number-of-orders'] = count($orderTotals);
399
+
400
+ // get average order value
401
+ if ($purchaseData['total-number-of-orders'] > 0) {
402
+ $purchaseData['average-order-value'] =
403
+ round($purchaseData['total-order-value'] / $purchaseData['total-number-of-orders'], 4);
404
+ } else {
405
+ $purchaseData['average-order-value'] = 0;
406
+ }
407
+
408
+ // get total number of products ordered
409
+ $productTotals = $orderCollection->getColumnValues('total_qty_ordered');
410
+ $purchaseData['total-number-of-products-ordered'] = array_sum($productTotals);
411
+ }
412
+
413
+ $purchaseAtt = substr($magentoAtt, 13, strlen($magentoAtt));
414
+ $customFields[] = array("Key" => $cmAtt, "Value" => $purchaseData[$purchaseAtt]);
415
+ }
416
+
417
+ } elseif (strncmp('FONTIS', $magentoAtt, 6) == 0) {
418
+ if ($customer->getId()) {
419
+ if (strncmp('FONTIS-billing', $magentoAtt, 14) == 0) {
420
+ $d = $customer->getDefaultBillingAddress();
421
+ if ($d) {
422
+ $d = $d->getData();
423
+ $addressAtt = substr($magentoAtt, 15, strlen($magentoAtt));
424
+ }
425
+ } else {
426
+ $d = $customer->getDefaultShippingAddress();
427
+ if ($d) {
428
+ $d = $d->getData();
429
+ $addressAtt = substr($magentoAtt, 16, strlen($magentoAtt));
430
+ }
431
+ }
432
+
433
+ if ($d && $addressAtt == 'region_id') {
434
+ if (array_key_exists('region_id', $d)) {
435
+ $region = Mage::getModel('directory/region')->load($d['region_id']);
436
+ $customFields[] = array("Key" => $cmAtt, "Value" => $region->getName());
437
+ }
438
+ } elseif ($d) {
439
+ if (array_key_exists($addressAtt, $d)) {
440
+ $customFields[] = array("Key" => $cmAtt, "Value" => $d[$addressAtt]);
441
+ }
442
+ }
443
+ }
444
+ } else {
445
+ if (array_key_exists($magentoAtt, $customerData)) {
446
+ $attribute = $customer->getAttribute($magentoAtt);
447
+ if ($attribute->getFrontendInput() == 'select' || $attribute->getSourceModel()) {
448
+ $label = $attribute->getSource()->getOptionText($customerData[$magentoAtt]);
449
+ $customFields[] = array("Key" => $cmAtt, "Value" => $label);
450
+ } else {
451
+ $customFields[] = array("Key" => $cmAtt, "Value" => $customerData[$magentoAtt]);
452
+ }
453
+ }
454
+ }
455
+ }
456
+ }
457
+
458
+ if ($customer->getId()) {
459
+ /** @var Campaignmonitor_Createsend_Model_Config_ProductAttributes $attrSource */
460
+ $attrSource = Mage::getSingleton('createsend/config_productAttributes');
461
+
462
+ $productAttributes = @unserialize(
463
+ Mage::getStoreConfig($helper::XML_PATH_WISHLIST_PRODUCT_ATTRIBUTES, $storeId)
464
+ );
465
+
466
+ /** @var Mage_Wishlist_Model_Wishlist $wishList */
467
+ $wishList = Mage::getModel('wishlist/wishlist')->loadByCustomer($customer);
468
+ $wishListItemCollection = $wishList->getItemCollection();
469
+
470
+ $maxWishlistItems = $helper->getMaxWistlistItems($storeId);
471
+
472
+ if (!empty($productAttributes) & !empty($maxWishlistItems)) {
473
+ $count = 0;
474
+ foreach ($wishListItemCollection as $item) {
475
+ if ($count >= $maxWishlistItems) {
476
+ break;
477
+ }
478
+
479
+ $count++;
480
+ $product = $item->getProduct();
481
+
482
+ foreach ($productAttributes as $pa) {
483
+ $magentoAtt = $pa['magento'];
484
+ $cmAtt = $attrSource->getCustomFieldName($pa['magento'], true);
485
+
486
+ if (strncmp($magentoAtt, "price", 5) == 0) {
487
+ $value = $product->getFinalPrice();
488
+ } else {
489
+ $value = $product->getData($magentoAtt);
490
+ }
491
+
492
+ $customFields[] = array(
493
+ "Key" => $api->formatCustomFieldName(
494
+ sprintf(
495
+ $api::WISHLIST_CUSTOM_FIELD_PATTERN, $api::WISHLIST_CUSTOM_FIELD_PREFIX, $count, $cmAtt
496
+ )
497
+ ),
498
+ "Value" => $value
499
+ );
500
+ }
501
+ }
502
+
503
+ // Clear out other items, if any
504
+ for ($i = $count + 1; $i <= $maxWishlistItems; $i++) {
505
+ foreach ($productAttributes as $pa) {
506
+ $cmAtt = $attrSource->getCustomFieldName($pa['magento'], true);
507
+
508
+ $customFields[] = array(
509
+ "Key" => $api->formatCustomFieldName(
510
+ sprintf($api::WISHLIST_CUSTOM_FIELD_PATTERN, $api::WISHLIST_CUSTOM_FIELD_PREFIX, $i, $cmAtt)
511
+ ),
512
+ "Clear" => true
513
+ );
514
+ }
515
+ }
516
+ }
517
+ }
518
+
519
+ return $customFields;
520
+ }
521
+
522
+ /**
523
+ * Returns the first or last order of customer given the customer's customerId.
524
+ * Excludes cancelled orders.
525
+ *
526
+ * @param int $customerId Customer ID
527
+ * @param string $sortOrder Use "ASC" to return first order, "DESC" to return last order
528
+ * @param array $selectFields fields to be selected
529
+ * @return Mage_Sales_Model_Order
530
+ */
531
+ protected static function _getEndOrder($customerId, $sortOrder, $selectFields) {
532
+ /** @var Mage_Sales_Model_Order[]|Mage_Sales_Model_Resource_Order_Collection $orders */
533
+ $orders = Mage::getModel('sales/order')->getCollection()
534
+ ->addAttributeToFilter('customer_id', $customerId)
535
+ ->addFieldToFilter('status', array('neq' => 'canceled'))
536
+ ->addAttributeToSort('created_at', $sortOrder)
537
+ ->setPageSize(1);
538
+
539
+ foreach ($selectFields as $field) {
540
+ $orders->addFieldToSelect($field);
541
+ }
542
+
543
+ return $orders->getFirstItem();
544
+ }
545
+ }
app/code/community/Campaignmonitor/Createsend/Model/Email.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Email extends Mage_Core_Model_Abstract
19
+ {
20
+ const STATUS_SENT = 'Sent';
21
+ const STATUS_ACCEPTED = 'Accepted';
22
+ const STATUS_DELIVERED = 'Delivered';
23
+ const STATUS_BOUNCED = 'Bounced';
24
+ const STATUS_SPAM = 'Spam';
25
+
26
+ static $statusCodes = array(
27
+ self::STATUS_SENT => 'Sent',
28
+ self::STATUS_ACCEPTED => 'Accepted',
29
+ self::STATUS_DELIVERED => 'Delivered',
30
+ self::STATUS_BOUNCED => 'Bounced',
31
+ self::STATUS_SPAM => 'Spam'
32
+ );
33
+
34
+ protected function _construct()
35
+ {
36
+ $this->_init('createsend/email');
37
+ }
38
+ }
app/code/community/Campaignmonitor/Createsend/Model/Email/Cron.php ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Email_Cron extends Campaignmonitor_Createsend_Model_Cron
19
+ {
20
+ const ERR_API_ERROR = 'API Error: %s';
21
+ const MAX_EMAIL_PER_REQUEST = 200;
22
+ const MAX_REQUEST_LOOPS = 100; // To prevent endless loops in the email retrieval process
23
+ const DATE_MIN = '1972-01-01 00:00:00';
24
+
25
+ const LOG_DELETING_EMAILS = 'Deleting email sent before %1$s for scope/scopeId (%2$s/%3$s)...';
26
+ const LOG_ROWS_DELETED = '%d email rows deleted.';
27
+
28
+ /**
29
+ * Performs email headers download for all scopes w/ non-inherited List ID
30
+ */
31
+ public function runJob()
32
+ {
33
+ $this->iterateScopes(
34
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_LIST_ID,
35
+ 'isTransactionalEmailsEnabled',
36
+ array(
37
+ array(
38
+ 'class' => $this,
39
+ 'method' => '_downloadEmailFromCM',
40
+ ),
41
+ array(
42
+ 'class' => $this,
43
+ 'method' => '_performEmailTableMaintenance',
44
+ ),
45
+ )
46
+ );
47
+ }
48
+
49
+ /**
50
+ * Downloads email headers for scope/scopeId
51
+ *
52
+ * @param string $listId Unused in this function because List ID is not required for sending transactional emails
53
+ * @param string $scope The configuration Scope for which to perform this action
54
+ * @param int $scopeId The configuration Scope ID for which to perform this action
55
+ */
56
+ protected function _downloadEmailFromCM($listId, $scope, $scopeId)
57
+ {
58
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
59
+ $helper = Mage::helper('createsend');
60
+
61
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
62
+ $api = Mage::getSingleton('createsend/api');
63
+
64
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
65
+ $scopeModel = Mage::getModel('createsend/config_scope');
66
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
67
+
68
+ /** @var array $params */
69
+ $params = array(
70
+ 'clientID' => $helper->getClientId($storeId),
71
+ 'count' => self::MAX_EMAIL_PER_REQUEST,
72
+ );
73
+
74
+ // Get last message id for this scope/scopeId from the database
75
+ /** @var array $row */
76
+ $row = Mage::getModel('createsend/email')->getCollection()
77
+ ->addFieldToFilter('scope', $scope)
78
+ ->addFieldToFilter('scope_id', $scopeId)
79
+ ->setOrder('sent_at', 'DESC')
80
+ ->setPageSize(1)
81
+ ->getFirstItem();
82
+
83
+ $lastMessageId = null;
84
+ $lastMessageDate = self::DATE_MIN;
85
+ if ($row) {
86
+ $lastMessageId = $row['message_id'];
87
+ $lastMessageDate = $row['sent_at'];
88
+
89
+ $params['sentAfterID'] = $lastMessageId;
90
+ }
91
+
92
+ $loopCount = 0;
93
+ do {
94
+ // Get "Message timeline" from CM
95
+ $result = $api->call(
96
+ Zend_Http_Client::GET,
97
+ "transactional/messages",
98
+ array(),
99
+ $params,
100
+ $scope,
101
+ $scopeId
102
+ );
103
+
104
+ $count = 0;
105
+ if ($result['success'] !== false) {
106
+ foreach ($result['data'] as $message) {
107
+ $count++;
108
+
109
+ /** @var Campaignmonitor_Createsend_Model_Email $email */
110
+ $email = Mage::getModel('createsend/email');
111
+ $email->setMessageId($message['MessageID']);
112
+ $email->setStatus($message['Status']);
113
+ $email->setSentAt($message['SentAt']);
114
+ $email->setRecipient(iconv_mime_decode($message['Recipient']));
115
+ $email->setSender($message['From']);
116
+ $email->setSubject(iconv_mime_decode($message['Subject']));
117
+ $email->setTotalOpens($message['TotalOpens']);
118
+ $email->setTotalClicks($message['TotalClicks']);
119
+ $email->setCanBeResent($message['CanBeResent']);
120
+ $email->setScope($scope);
121
+ $email->setScopeId($scopeId);
122
+ $email->save();
123
+
124
+ // Compare dates, don't assume message dates are in order
125
+ if ($message['SentAt'] >= $lastMessageDate) {
126
+ $lastMessageId = $message['MessageID'];
127
+ $lastMessageDate = $message['SentAt'];
128
+ }
129
+ }
130
+
131
+ $params['sentAfterID'] = $lastMessageId;
132
+ } else {
133
+ $helper->log(sprintf(self::ERR_API_ERROR, var_export($result, true)), Zend_Log::ERR);
134
+ }
135
+
136
+ } while (($count >= self::MAX_EMAIL_PER_REQUEST) && (++$loopCount < self::MAX_REQUEST_LOOPS));
137
+ }
138
+
139
+ /**
140
+ * Deletes all email with sent_at earlier than the email retention days configuration
141
+ * for the given scope/scopeId.
142
+ *
143
+ * @param string $listId Unused in this function because List ID is not required for sending transactional emails
144
+ * @param string $scope The configuration Scope for which to perform this action
145
+ * @param int $scopeId The configuration Scope ID for which to perform this action
146
+ */
147
+ protected function _performEmailTableMaintenance($listId, $scope, $scopeId)
148
+ {
149
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
150
+ $helper = Mage::helper('createsend');
151
+
152
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
153
+ $scopeModel = Mage::getModel('createsend/config_scope');
154
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
155
+
156
+ $retentionDays = $helper->getEmailRetentionDays($storeId);
157
+
158
+ $daysAgo = Mage::getModel('core/date')->timestamp(strtotime(sprintf('%d days ago', $retentionDays)));
159
+ $daysAgoStr = date('Y-m-d', $daysAgo);
160
+
161
+ $helper->log(
162
+ sprintf(self::LOG_DELETING_EMAILS, $daysAgoStr, $scope, $scopeId),
163
+ Zend_Log::DEBUG
164
+ );
165
+
166
+ /** @var Varien_Data_Collection_Db $collection */
167
+ $collection = Mage::getModel('createsend/email')->getCollection()
168
+ ->addFieldToFilter('scope', $scope)
169
+ ->addFieldToFilter('scope_id', $scopeId)
170
+ ->addFieldToFilter('sent_at', array('lt' => $daysAgoStr))
171
+ ->load();
172
+
173
+ $count = 0;
174
+ /** @var Campaignmonitor_Createsend_Model_Email $email */
175
+ foreach ($collection as $email) {
176
+ $email->delete();
177
+ $count++;
178
+ }
179
+
180
+ $helper->log(sprintf(self::LOG_ROWS_DELETED, $count), Zend_Log::DEBUG);
181
+ }
182
+ }
app/code/community/Campaignmonitor/Createsend/Model/Email/Template.php ADDED
@@ -0,0 +1,204 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Email_Template extends Mage_Core_Model_Email_Template
19
+ {
20
+ const ERR_CANNOT_SEND_EMAIL = 'Cannot send email via Campaign Monitor Transactional API: %s';
21
+
22
+ /**
23
+ * Overrides the Mage_Core_Model_Email_Template send() method to send email via Campaign Monitor Transactional API.
24
+ * Some of the code are from the original parent send() method. Unused code from the original method are
25
+ * commented out for reference.
26
+ *
27
+ * @param array|string $email E-mail(s)
28
+ * @param array|string|null $name receiver name(s)
29
+ * @param array $variables Template variables
30
+ * @return bool
31
+ * @throws Exception when the letter cannot be sent because it it not valid
32
+ */
33
+ public function send($email, $name = null, array $variables = array())
34
+ {
35
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
36
+ $helper = Mage::helper("createsend");
37
+
38
+ $storeId = Mage::app()->getStore()->getStoreId();
39
+
40
+ // Only send emails through Campaign Monitor is the admin has selected to do so
41
+ $transactionalEmailEnabled = $helper->isTransactionalEmailsEnabled($storeId);
42
+ if ($transactionalEmailEnabled == false) {
43
+ return parent::send($email, $name, $variables);
44
+ }
45
+
46
+ if (!$this->isValidForSend()) {
47
+ Mage::logException(new Exception('This letter cannot be sent.')); // translation is intentionally omitted
48
+ return false;
49
+ }
50
+
51
+ $emails = array_values((array) $email);
52
+ $names = is_array($name) ? $name : (array)$name;
53
+ $names = array_values($names);
54
+ foreach ($emails as $key => $email) {
55
+ if (!isset($names[$key])) {
56
+ $names[$key] = substr($email, 0, strpos($email, '@'));
57
+ }
58
+ }
59
+
60
+ $variables['email'] = reset($emails);
61
+ $variables['name'] = reset($names);
62
+
63
+ // TODO: Partition into logical groups such as "Orders", "Shipments"
64
+ $group = 'Magento';
65
+
66
+ $emailData = array(
67
+ 'Subject' => null,
68
+ 'From' => null,
69
+ 'ReplyTo' => null,
70
+ 'To' => null,
71
+ 'CC' => null,
72
+ 'BCC' => null,
73
+ 'Html' => '',
74
+ 'Text' => '',
75
+ 'Attachments' => null,
76
+ 'TrackOpens' => true,
77
+ 'TrackClicks' => true,
78
+ 'InlineCSS' => true,
79
+ 'Group' => $group // Used for grouping email for reporting
80
+ );
81
+
82
+ $setReturnPath = Mage::getStoreConfig(self::XML_PATH_SENDING_SET_RETURN_PATH);
83
+ switch ($setReturnPath) {
84
+ case 1:
85
+ $returnPathEmail = $this->getSenderEmail();
86
+ break;
87
+ case 2:
88
+ $returnPathEmail = Mage::getStoreConfig(self::XML_PATH_SENDING_RETURN_PATH_EMAIL);
89
+ break;
90
+ default:
91
+ $returnPathEmail = null;
92
+ break;
93
+ }
94
+
95
+ if ($returnPathEmail !== null) {
96
+ $emailData['ReplyTo'] = $returnPathEmail;
97
+ }
98
+
99
+ $recipients = array();
100
+ foreach ($emails as $key => $email) {
101
+ $recipients[] = $names[$key] . '<' . $email . '>';
102
+ }
103
+
104
+ $emailData['To'] = $recipients;
105
+
106
+ $this->setUseAbsoluteLinks(true);
107
+ $text = $this->getProcessedTemplate($variables, true);
108
+
109
+ if ($this->isPlain()) {
110
+ $emailData['Text'] = $text;
111
+ } else {
112
+ $emailData['Html'] = $text;
113
+ }
114
+
115
+ $emailData['Subject'] = $this->getProcessedTemplateSubject($variables);
116
+ $emailData['From'] = '"' . $this->getSenderName() . '" <' . $this->getSenderEmail() .'>';
117
+
118
+ try {
119
+ $this->_send($emailData, $variables);
120
+ $this->_mail = null;
121
+ } catch (Exception $e) {
122
+ $this->_mail = null;
123
+ $helper->log(sprintf(self::ERR_CANNOT_SEND_EMAIL, $e), Zend_Log::ERR);
124
+ return false;
125
+ }
126
+
127
+ return true;
128
+ }
129
+
130
+ /**
131
+ * Sends a 'classic email' using the Campaign Monitor Transactional Email API.
132
+ *
133
+ * @link https://www.campaignmonitor.com/api/transactional/#send_a_basic_email
134
+ *
135
+ * Expects an array of the form:
136
+ * <pre>
137
+ * {
138
+ * "Subject": "Thanks for signing up to web app 123",
139
+ * "From": "Mike Smith <mike@webapp123.com>",
140
+ * "ReplyTo": "support@webapp123.com",
141
+ * "To": [
142
+ * "Joe Smith <joesmith@example.com>",
143
+ * "jamesmith@example.com"
144
+ * ],
145
+ * "CC": [
146
+ * "Joe Smith <joesmith@example.com>"
147
+ * ],
148
+ * "BCC": null,
149
+ * "Html": "",
150
+ * "Text": "",
151
+ * "Attachments": [
152
+ * {
153
+ * "Type": "application/pdf",
154
+ * "Name": "Invoice.pdf",
155
+ * "Content": "base64encoded"
156
+ * }
157
+ * ],
158
+ * "TrackOpens": true,
159
+ * "TrackClicks": true,
160
+ * "InlineCSS": true,
161
+ * "Group": "Password Reset",
162
+ * "AddRecipientsToListID": "62eaaa0338245ca68e5e93daa6f591e9"
163
+ * }
164
+ * </pre>
165
+ *
166
+ * @param array $emailData Data to send
167
+ * @param array $variables Template variables
168
+ * @throws Exception
169
+ */
170
+ protected function _send(array $emailData, array $variables = array())
171
+ {
172
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
173
+ $helper = Mage::helper('createsend');
174
+
175
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
176
+ $api = Mage::getModel('createsend/api');
177
+
178
+ // Use current store's configuration to send the email
179
+ $storeId = Mage::app()->getStore()->getStoreId();
180
+
181
+ if ($storeId) {
182
+ $scope = 'stores';
183
+ $scopeId = $storeId;
184
+ } else {
185
+ $scope = 'default';
186
+ $scopeId = 0;
187
+ }
188
+
189
+ $result = $api->call(
190
+ Zend_Http_Client::POST,
191
+ 'transactional/classicEmail/send',
192
+ $emailData,
193
+ array(
194
+ 'clientID' => $helper->getClientId($storeId)
195
+ ),
196
+ $scope,
197
+ $scopeId
198
+ );
199
+
200
+ if (!$result['success']) {
201
+ throw new Exception($result['data']['Message']);
202
+ }
203
+ }
204
+ }
app/code/community/Campaignmonitor/Createsend/Model/List/Cron.php ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_List_Cron extends Campaignmonitor_Createsend_Model_Cron
19
+ {
20
+ const SYNC_INCLUSION_PERIOD = 'yesterday'; // Relative date/time format
21
+ const ERR_API_ERROR = 'API Error: %s';
22
+
23
+ /**
24
+ * Performs list subscribers synchronisation for all scopes w/ non-inherited List ID
25
+ */
26
+ public function runJob()
27
+ {
28
+ $this->iterateScopes(
29
+ Campaignmonitor_Createsend_Helper_Data::XML_PATH_LIST_ID,
30
+ 'isSubscriberSynchronisationEnabled',
31
+ array(
32
+ array(
33
+ 'class' => $this,
34
+ 'method' => '_synchroniseFromCm',
35
+ ),
36
+ )
37
+ );
38
+
39
+ $this->synchroniseFromMagento();
40
+ }
41
+
42
+ /**
43
+ * Synchronises list subscribers using Campaign Monitor subscribers as base list.
44
+ *
45
+ * @link https://www.campaignmonitor.com/api/lists/#active_subscribers
46
+ *
47
+ * @param string $listId The ID of the Campaign Monitor list to synchronise
48
+ * @param string $scope
49
+ * @param int $scopeId
50
+ */
51
+ public function _synchroniseFromCm($listId, $scope, $scopeId)
52
+ {
53
+ $dateTimestamp = Mage::getModel('core/date')->timestamp(strtotime(self::SYNC_INCLUSION_PERIOD));
54
+ $yesterday = date('Y-m-d', $dateTimestamp);
55
+
56
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
57
+ $helper = Mage::helper('createsend');
58
+
59
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
60
+ $api = Mage::getSingleton('createsend/api');
61
+
62
+ // Get List of Active Subscribers
63
+ $result = $api->call(
64
+ Zend_Http_Client::GET,
65
+ "lists/{$listId}/active",
66
+ array(),
67
+ array('date' => $yesterday),
68
+ $scope,
69
+ $scopeId
70
+ );
71
+
72
+ if ($result['success'] !== false) {
73
+ foreach ($result['data']['Results'] as $subscriber) {
74
+ $email = $subscriber['EmailAddress'];
75
+
76
+ /** @var Mage_Newsletter_Model_Subscriber $mageNewsletter */
77
+ $mageNewsletter = Mage::getModel('newsletter/subscriber');
78
+ $mageNewsletter->loadByEmail($email);
79
+
80
+ if (!$mageNewsletter->isSubscribed() || $mageNewsletter->getId() === null) {
81
+ $mageTimestamp = null;
82
+ if ($mageNewsletter->getId() !== null) {
83
+ $mageTime = Mage::getModel('core/date')->timestamp($mageNewsletter->getChangeStatusAt());
84
+ $mageTimestamp = date('Y-m-d H:i:s', $mageTime);
85
+ }
86
+
87
+ // CM in local time
88
+ $cmTimestamp = null;
89
+ if (isset($subscriber['Date'])) {
90
+ $cmTimestamp = $subscriber['Date'];
91
+ }
92
+
93
+ $this->_applyResolutionMethod(
94
+ Campaignmonitor_Createsend_Model_Config_SubscriptionSources::SOURCE_CAMPAIGN_MONITOR,
95
+ $email, $mageTimestamp, $cmTimestamp, $scope, $scopeId
96
+ );
97
+ }
98
+ }
99
+ } else {
100
+ $helper->log(sprintf(self::ERR_API_ERROR, $result['data']['Message']), Zend_Log::ERR);
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Synchronises list subscribers using Magento subscribers from all stores as the base list.
106
+ *
107
+ */
108
+ public function synchroniseFromMagento()
109
+ {
110
+ $stores = Mage::app()->getStores(true);
111
+ foreach ($stores as $storeId => $store) {
112
+ $this->_synchroniseFromMagento($storeId);
113
+ }
114
+ }
115
+
116
+ /**
117
+ * Synchronises list subscribers using Magento newsletter subscribers from the particular store as the base list.
118
+ *
119
+ * @param int $storeId
120
+ */
121
+ public function _synchroniseFromMagento($storeId)
122
+ {
123
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
124
+ $helper = Mage::helper('createsend');
125
+
126
+ $listId = $helper->getListId($storeId);
127
+ $scope = 'stores';
128
+ $scopeId = $storeId;
129
+
130
+ /* @var Mage_Newsletter_Model_Subscriber $subscribers */
131
+ $mageNewsletter = Mage::getModel('newsletter/subscriber');
132
+
133
+ $collection = $mageNewsletter->getCollection()
134
+ ->addFieldToFilter('store_id', $storeId)
135
+ ->addFieldToFilter('subscriber_status', Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED);
136
+
137
+ foreach ($collection as $subscriber) {
138
+ $email = $subscriber->getEmail();
139
+
140
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
141
+ $api = Mage::getSingleton('createsend/api');
142
+
143
+ // Check CM subscriber status
144
+ $result = $api->call(
145
+ Zend_Http_Client::GET,
146
+ "subscribers/{$listId}",
147
+ array(),
148
+ array('email' => $email),
149
+ $scope,
150
+ $scopeId
151
+ );
152
+
153
+ if ($result['success'] || $result['data']['Code'] == $api::CODE_SUBSCRIBER_NOT_IN_LIST) {
154
+ if (isset($result['data']['State'])) {
155
+ $subscriptionState = $result['data']['State'];
156
+ } else {
157
+ $subscriptionState = $api::SUBSCRIBER_STATUS_DELETED;
158
+ }
159
+
160
+ if ($subscriptionState !== $api::SUBSCRIBER_STATUS_ACTIVE) {
161
+ // Convert to local time
162
+ $mageTime = Mage::getModel('core/date')->timestamp($subscriber->getChangeStatusAt());
163
+ $mageTimeStamp = date('Y-m-d H:i:s', $mageTime);
164
+
165
+ // CM in local time
166
+ $cmTimestamp = null;
167
+ if (isset($result['data']['Date'])) {
168
+ $cmTimestamp = $result['data']['Date'];
169
+ }
170
+
171
+ $this->_applyResolutionMethod(
172
+ Campaignmonitor_Createsend_Model_Config_SubscriptionSources::SOURCE_MAGENTO,
173
+ $email, $mageTimeStamp, $cmTimestamp, $scope, $scopeId
174
+ );
175
+ }
176
+ }
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Performs conflict resolution based on source list and resolution method of scope/scopeId
182
+ *
183
+ * @param string $source The source where the email address is subscribed
184
+ * @param string $email The email address to be subscribed/unsubscribed
185
+ * @param string $mageTimestamp Date when magento newsletter subscription was last updated, format: 'Y-m-d H:i:s'
186
+ * @param string $cmTimestamp Date when CM list subscription was last updated, format: 'Y-m-d H:i:s'
187
+ * @param string $scope
188
+ * @param int $scopeId
189
+ */
190
+ protected function _applyResolutionMethod($source, $email, $mageTimestamp, $cmTimestamp, $scope, $scopeId)
191
+ {
192
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
193
+ $helper = Mage::helper('createsend');
194
+
195
+ $helper->log(
196
+ sprintf('RESOLVE (%s): From(%s); Magento(%s); CM(%s)', $email, $source, $mageTimestamp, $cmTimestamp)
197
+ );
198
+
199
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
200
+ $scopeModel = Mage::getModel('createsend/config_scope');
201
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
202
+
203
+ $resolutionMethod = $helper->getSubscriberSynchronisationResolutionMethod($storeId);
204
+
205
+ switch ($resolutionMethod) {
206
+ case Campaignmonitor_Createsend_Model_Config_ConflictResolutionMethod::RESOLUTION_METHOD_TIMESTAMP:
207
+ if ($mageTimestamp === null) {
208
+ $this->_preferCM($source, $email, $storeId);
209
+ } elseif ($cmTimestamp === null) {
210
+ $this->_preferMagento($source, $email, $scope, $scopeId);
211
+ } elseif ($mageTimestamp < $cmTimestamp) {
212
+ $this->_preferCM($source, $email, $storeId);
213
+ } else {
214
+ $this->_preferMagento($source, $email, $scope, $scopeId);
215
+ }
216
+
217
+ break;
218
+
219
+ case Campaignmonitor_Createsend_Model_Config_ConflictResolutionMethod::RESOLUTION_METHOD_SOURCE:
220
+ $preferredSource = $helper->getSubscriberSynchronisationPreferredSource($storeId);
221
+
222
+ switch ($preferredSource) {
223
+ case Campaignmonitor_Createsend_Model_Config_SubscriptionSources::SOURCE_MAGENTO:
224
+ $this->_preferMagento($source, $email, $scope, $scopeId);
225
+ break;
226
+
227
+ case Campaignmonitor_Createsend_Model_Config_SubscriptionSources::SOURCE_CAMPAIGN_MONITOR:
228
+ default: // If not set, use CM as preferred source
229
+ $this->_preferCM($source, $email, $storeId);
230
+ break;
231
+ }
232
+ break;
233
+ }
234
+ }
235
+
236
+ /**
237
+ * Uses the CM subscription status to update Magento newsletter subscription
238
+ *
239
+ * @param string $source The source where the email address is subscribed
240
+ * @param string $email The email address to be subscribed/unsubscribed
241
+ * @param int $storeId Store ID of the Magento newsletter object
242
+ */
243
+ protected function _preferCM($source, $email, $storeId)
244
+ {
245
+ /** @var Campaignmonitor_Createsend_Model_Newsletter $newsletter */
246
+ $newsletter = Mage::getModel('createsend/newsletter');
247
+
248
+ if ($source === Campaignmonitor_Createsend_Model_Config_SubscriptionSources::SOURCE_CAMPAIGN_MONITOR) {
249
+ $newsletter->subscribe($email, $storeId);
250
+ } else {
251
+ $newsletter->unsubscribe($email);
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Uses the Magento newsletter subscription status to update CM subscription
257
+ *
258
+ * @param string $source The source where the email address is subscribed
259
+ * @param string $email The email address to be subscribed/unsubscribed
260
+ * @param string $scope
261
+ * @param int $scopeId
262
+ */
263
+ protected function _preferMagento($source, $email, $scope, $scopeId)
264
+ {
265
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
266
+ $api = Mage::getModel('createsend/api');
267
+
268
+ if ($source === Campaignmonitor_Createsend_Model_Config_SubscriptionSources::SOURCE_CAMPAIGN_MONITOR) {
269
+ $api->unsubscribe($email, $scope, $scopeId);
270
+ } else {
271
+ $api->subscribe($email, $scope, $scopeId);
272
+ }
273
+ }
274
+ }
app/code/community/Campaignmonitor/Createsend/Model/List/Initial/Cron.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_List_Initial_Cron extends Campaignmonitor_Createsend_Model_Cron
19
+ {
20
+ const PROCESS_ID = 'list_initial_cron';
21
+
22
+ /**
23
+ * Performs list subscribers synchronisation for all scopes w/ non-inherited List ID
24
+ */
25
+ public function runJob()
26
+ {
27
+ $this->_fullSync();
28
+ }
29
+
30
+ /**
31
+ * Synchronises list subscribers from Magento to Campaign Monitor
32
+ *
33
+ */
34
+ public function _fullSync()
35
+ {
36
+ $flagClass = 'createsend/config_listFlag';
37
+
38
+ /** @var Campaignmonitor_Createsend_Helper_Config $configHelper */
39
+ $configHelper = Mage::helper('createsend/config');
40
+
41
+ /** @var array $processData */
42
+ $processData = $configHelper->getFlagData($flagClass, self::PROCESS_ID);
43
+
44
+ if (!is_array($processData)) {
45
+ $processData = array(
46
+ 'status' => $configHelper::FLAG_PROCESS_STOPPED,
47
+ 'start' => null,
48
+ 'end' => null,
49
+ );
50
+ }
51
+
52
+ // Check for stale process
53
+ if ($processData['status'] === $configHelper::FLAG_PROCESS_RUNNING) {
54
+ $startDate = new DateTime($processData['start']);
55
+ $now = new DateTime('now');
56
+ $dateDiff = $startDate->diff($now);
57
+
58
+ if ($dateDiff->days < 1) {
59
+ // running less than one day, not yet stale
60
+ return;
61
+ }
62
+
63
+ // If this stage is reached, process is considered stale.
64
+ // Continue processing
65
+ }
66
+
67
+ // Set and save the flag so that this process does not run more than once
68
+ $processData['status'] = $configHelper::FLAG_PROCESS_RUNNING;
69
+ $processData['start'] = date('Y-m-d H:i:s');
70
+ $configHelper->addFlagData($flagClass, self::PROCESS_ID, $processData);
71
+
72
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
73
+ $helper = Mage::helper('createsend');
74
+
75
+ /** @var Campaignmonitor_Createsend_Helper_Api $apiHelper */
76
+ $apiHelper = Mage::helper('createsend/api');
77
+
78
+ $updatedLists = array();
79
+
80
+ $stores = Mage::app()->getStores(true);
81
+ foreach ($stores as $storeId => $store) {
82
+ $listId = $helper->getListId($storeId);
83
+
84
+ if (!$listId) {
85
+ // Don't have a list to use
86
+ continue;
87
+ }
88
+
89
+ $flagData = $configHelper->getFlagData($flagClass, $listId);
90
+
91
+ if (!$flagData) {
92
+ // No list data has been saved yet
93
+ continue;
94
+ }
95
+
96
+ if (isset($flagData[$configHelper::INDEX_INITIAL_SYNC]) &&
97
+ $flagData[$configHelper::INDEX_INITIAL_SYNC] === $configHelper::FLAG_STATUS_NEW) {
98
+ // We have initial sync info and it's in the appropriate state so run the full sync
99
+ $apiHelper->performFullSync($storeId);
100
+
101
+ $updatedLists[$listId] = true;
102
+ }
103
+ }
104
+
105
+ foreach (array_keys($updatedLists) as $listId) {
106
+ // Set flag status to 'done' for all synchronized lists
107
+ $listFlagData[$configHelper::INDEX_INITIAL_SYNC] = $configHelper::FLAG_STATUS_DONE;
108
+ $configHelper->addFlagData($flagClass, $listId, $listFlagData);
109
+ }
110
+
111
+ // Done processing, update flag for this process
112
+ $processData['status'] = $configHelper::FLAG_PROCESS_STOPPED;
113
+ $processData['end'] = date('Y-m-d H:i:s');
114
+ $configHelper->addFlagData($flagClass, self::PROCESS_ID, $processData);
115
+ }
116
+ }
app/code/community/Campaignmonitor/Createsend/Model/Newsletter.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Newsletter
19
+ {
20
+ const ERR_NO_EMAIL_FOUND = 'The email "%s" appears to have no matching entries in Magento';
21
+ const ERR_USER_SUBSCRIBED = 'The user "%s" is already subscribed in Magento';
22
+ const ERR_USER_UNSUBSCRIBED = 'The user "%s" has already unsubscribed in Magento';
23
+
24
+ const LOG_SUBSCRIBED_USER = 'Successfully subscribed customer "%s": %s';
25
+ const LOG_UNSUBSCRIBED_USER = 'Successfully unsubscribed customer "%s": %s';
26
+
27
+ /**
28
+ * Subscribes an email address to the Magento newsletter.
29
+ *
30
+ * @param string $email The email address to subscribe to the Magento newsletter
31
+ * @param int $storeId The store ID to set for the newsletter subscription
32
+ * @throws Exception if newsletter object cannot be saved
33
+ */
34
+ public function subscribe($email, $storeId)
35
+ {
36
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
37
+ $helper = Mage::helper('createsend');
38
+
39
+ /** @var Mage_Newsletter_Model_Subscriber $newsletters */
40
+ $newsletters = Mage::getModel('newsletter/subscriber');
41
+ $newsletters->loadByEmail($email);
42
+
43
+ if ($newsletters->getId() === null) {
44
+ // Create new subscriber, without sending confirmation email
45
+ Mage::getModel('newsletter/subscriber')->setImportMode(true)->subscribe($email);
46
+ $newsletters->loadByEmail($email);
47
+
48
+ $websiteId = Mage::app()->getStore($storeId)->getWebsiteId();
49
+
50
+ /** @var Mage_Customer_Model_Customer $customer */
51
+ $customer = Mage::getModel("customer/customer")
52
+ ->setWebsiteId($websiteId)
53
+ ->loadByEmail($email);
54
+
55
+ if ($customer->getId()) {
56
+ $newsletters->setCustomerId($customer->getId());
57
+ }
58
+
59
+ $newsletters->setStoreId($storeId);
60
+
61
+ $newsletters->setStatus(Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED);
62
+ $newsletters->save();
63
+
64
+ $helper->log(
65
+ sprintf(self::LOG_SUBSCRIBED_USER, $newsletters->getCustomerId(), $newsletters->getEmail()),
66
+ Zend_Log::DEBUG
67
+ );
68
+ } else {
69
+ if ($newsletters->isSubscribed() === false) {
70
+ $newsletters->setStatus(Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED);
71
+ $newsletters->save();
72
+
73
+ $helper->log(
74
+ sprintf(self::LOG_SUBSCRIBED_USER, $newsletters->getCustomerId(), $newsletters->getEmail()),
75
+ Zend_Log::DEBUG
76
+ );
77
+ } else {
78
+ $helper->log(sprintf(self::ERR_USER_SUBSCRIBED, $email), Zend_Log::WARN);
79
+ }
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Unsubscribes an email address from the Magento newsletter.
85
+ *
86
+ * @param string $email The email address to unsubscribe from Magento newsletter
87
+ */
88
+ public function unsubscribe($email)
89
+ {
90
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
91
+ $helper = Mage::helper('createsend');
92
+
93
+ /** @var Mage_Newsletter_Model_Subscriber $newsletters */
94
+ $newsletters = Mage::getModel('newsletter/subscriber');
95
+ $newsletters->loadByEmail($email);
96
+
97
+ if ($newsletters->getId() === null) {
98
+ $helper->log(sprintf(self::ERR_NO_EMAIL_FOUND, $email), Zend_Log::WARN);
99
+ return;
100
+ }
101
+
102
+ if ($newsletters->isSubscribed() === false) {
103
+ $helper->log(sprintf(self::ERR_USER_UNSUBSCRIBED, $email), Zend_Log::NOTICE);
104
+ return;
105
+ }
106
+
107
+ $newsletters->setImportMode(true)->unsubscribe();
108
+ $helper->log(
109
+ sprintf(self::LOG_UNSUBSCRIBED_USER, $newsletters->getCustomerId(), $newsletters->getEmail()),
110
+ Zend_Log::DEBUG
111
+ );
112
+ }
113
+ }
app/code/community/Campaignmonitor/Createsend/Model/Newsletter/Observer.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Bug fix for Magento newsletter's change_status_at field non-update bug.
20
+ */
21
+ class Campaignmonitor_Createsend_Model_Newsletter_Observer
22
+ {
23
+ /**
24
+ * Updates the change_status_at field. Fixes a bug in Magento where the field is not updated
25
+ * because the field's auto update "ON UPDATE CURRENT_TIMESTAMP" was omitted in recent versions.
26
+ *
27
+ * @param Varien_Event_Observer $observer
28
+ * @listen newsletter_subscriber_save_before
29
+ */
30
+ public function setChangeStatusAt(Varien_Event_Observer $observer)
31
+ {
32
+ $subscriber = $observer->getSubscriber();
33
+ $subscriber['change_status_at'] = date("Y-m-d H:i:s", time());
34
+ }
35
+ }
app/code/community/Campaignmonitor/Createsend/Model/Product/Observer.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Responsible for updating subscribers' custom field values when a product is changed
20
+ */
21
+ class Campaignmonitor_Createsend_Model_Product_Observer
22
+ {
23
+ /**
24
+ * Updates the (wishlist) custom fields of a user on campaign monitor based on new product data in Magento
25
+ *
26
+ * @param Varien_Event_Observer $observer
27
+ * @listen catalog_product_save_after
28
+ */
29
+ public function updateWishlistFields($observer)
30
+ {
31
+ /** @var Mage_Catalog_Model_Product $product */
32
+ $product = $observer->getProduct();
33
+
34
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
35
+ $api = Mage::getModel('createsend/api');
36
+
37
+ // Get all subscribers having the product in their wishlists
38
+ $wishlistCollection = Mage::getModel('wishlist/item')
39
+ ->getCollection()
40
+ ->addFieldToFilter('product_id', $product->getId())
41
+ ->addFieldToSelect('wishlist_id')
42
+ ->join(
43
+ array('wishlist' => 'wishlist/wishlist'),
44
+ 'main_table.wishlist_id = wishlist.wishlist_id',
45
+ array('customer_id')
46
+ );
47
+
48
+ foreach ($wishlistCollection as $wishlist) {
49
+ $customerId = $wishlist->getCustomerId();
50
+
51
+ /** @var Mage_Customer_Model_Customer $customer */
52
+ $customer = Mage::getSingleton('customer/customer')->load($customerId);
53
+ if ($customer) {
54
+ /** @var Mage_Newsletter_Model_Subscriber $newsletter */
55
+ $subscriber = Mage::getModel('newsletter/subscriber')->loadByCustomer($customer);
56
+ $isSubscribed = $subscriber->isSubscribed();
57
+
58
+ if ($isSubscribed) {
59
+ $scope = 'stores';
60
+ $scopeId = $subscriber->getStoreId();
61
+
62
+ $api->subscribe($subscriber->getSubscriberEmail(), $scope, $scopeId);
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
app/code/community/Campaignmonitor/Createsend/Model/Resource/Email.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Resource_Email extends Mage_Core_Model_Resource_Db_Abstract
19
+ {
20
+ const PK_FIELD = "email_id";
21
+
22
+ protected function _construct()
23
+ {
24
+ $this->_init('createsend/email', self::PK_FIELD);
25
+ }
26
+ }
app/code/community/Campaignmonitor/Createsend/Model/Resource/Email/Collection.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Model_Resource_Email_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract
19
+ {
20
+ protected function _construct()
21
+ {
22
+ $this->_init('createsend/email');
23
+ }
24
+ }
app/code/community/Campaignmonitor/Createsend/controllers/Adminhtml/Createsend/ApiController.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Adminhtml_Createsend_ApiController extends Mage_Adminhtml_Controller_Action
19
+ {
20
+ const ADMINHTML_SYSTEM_CONFIG_EDIT = 'adminhtml/system_config/edit';
21
+
22
+ const ERR_API_CALL_ERROR = 'API Test Error: %s';
23
+ const LOG_API_CALL_SUCCESSFUL = 'API Test Successful.';
24
+
25
+ /**
26
+ * Performs a test API call.
27
+ *
28
+ * @link https://www.campaignmonitor.com/api/
29
+ *
30
+ * @return Mage_Core_Controller_Varien_Action
31
+ */
32
+ public function testAction()
33
+ {
34
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
35
+ $helper = Mage::helper("createsend");
36
+
37
+ $scope = $this->getRequest()->getQuery('scope');
38
+ $scopeId = $this->getRequest()->getQuery('scopeId');
39
+
40
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
41
+ $scopeModel = Mage::getModel('createsend/config_scope');
42
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
43
+
44
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
45
+ $api = Mage::getModel('createsend/api');
46
+
47
+ $reply = $api->call(
48
+ Zend_Http_Client::GET,
49
+ 'lists/' . $helper->getListId($storeId),
50
+ array(),
51
+ array(),
52
+ $scope,
53
+ $scopeId
54
+ );
55
+
56
+ if ($reply['success'] === false) {
57
+ $jsonData = json_encode(
58
+ array(
59
+ 'messages' => array(
60
+ array(
61
+ 'status' => 'error',
62
+ 'message' => sprintf(self::ERR_API_CALL_ERROR, $reply['data']['Message'])
63
+ )
64
+ )
65
+ )
66
+ );
67
+ } else {
68
+ $jsonData = json_encode(
69
+ array(
70
+ 'messages' => array(
71
+ array(
72
+ 'status' => 'success',
73
+ 'message' => self::LOG_API_CALL_SUCCESSFUL
74
+ )
75
+ )
76
+ )
77
+ );
78
+ }
79
+
80
+ $this->getResponse()->setHeader('Content-type', 'application/json');
81
+ $this->getResponse()->setBody($jsonData);
82
+ }
83
+
84
+
85
+ /**
86
+ * Returns a list of Campaign Monitor clients given the API Key.
87
+ * Also saves the API Key for the scope.
88
+ * If there is only one client, the lists for that client is also queried and returned.
89
+ * Prints out the client list in JSON format.
90
+ */
91
+ public function getClientsAction()
92
+ {
93
+ $scope = $this->getRequest()->getQuery('scope');
94
+ $scopeId = $this->getRequest()->getQuery('scopeId');
95
+ $apiKey = $this->getRequest()->getQuery('apiKey');
96
+
97
+ Mage::getConfig()->saveConfig(Campaignmonitor_Createsend_Helper_Data::XML_PATH_API_ID, $apiKey, $scope, $scopeId);
98
+
99
+ /** @var $apiHelper Campaignmonitor_Createsend_Helper_Api */
100
+ $apiHelper = Mage::helper("createsend/api");
101
+
102
+ $clients = $apiHelper->getClients($scope, $scopeId);
103
+ if ($clients !== null) {
104
+ if (count($clients) == 2) {
105
+ // Automatically get the lists if only one client
106
+ $clients[1]['lists'] = $apiHelper->getLists($clients[1]['value'], $scope, $scopeId);
107
+ }
108
+ }
109
+
110
+ $jsonData = json_encode(
111
+ array (
112
+ 'status' => 'success',
113
+ 'items' => $clients
114
+ )
115
+ );
116
+
117
+ $this->getResponse()->setHeader('Content-type', 'application/json');
118
+ $this->getResponse()->setBody($jsonData);
119
+ }
120
+
121
+ /**
122
+ * Returns the Campaign Monitor subscription lists for the client.
123
+ * Prints out the lists in JSON format.
124
+ */
125
+ public function getListsAction()
126
+ {
127
+ $scope = $this->getRequest()->getQuery('scope');
128
+ $scopeId = $this->getRequest()->getQuery('scopeId');
129
+ $clientId = $this->getRequest()->getQuery('clientId');
130
+
131
+ /** @var $apiHelper Campaignmonitor_Createsend_Helper_Api */
132
+ $apiHelper = Mage::helper("createsend/api");
133
+
134
+ $lists = $apiHelper->getLists($clientId, $scope, $scopeId);
135
+
136
+ $jsonData = json_encode(
137
+ array (
138
+ 'status' => 'success',
139
+ 'items' => $lists
140
+ )
141
+ );
142
+
143
+ $this->getResponse()->setHeader('Content-type', 'application/json');
144
+ $this->getResponse()->setBody($jsonData);
145
+ }
146
+ }
app/code/community/Campaignmonitor/Createsend/controllers/Adminhtml/Createsend/EmailController.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_Adminhtml_Createsend_EmailController extends Mage_Adminhtml_Controller_Action
19
+ {
20
+ const ERR_UNABLE_TO_RESEND_EMAIL = 'Unable to resend email: %s';
21
+ const ERR_EMAIL_NOT_FOUND = 'Email not found.';
22
+ const ERR_API_ERROR = 'API Error: %s';
23
+ const ERR_EMAIL_CANNOT_BE_RESENT = 'Email cannot be resent';
24
+ const LOG_EMAIL_RESENT = 'Email resend status: %s';
25
+
26
+ const PATH_EMAIL_VIEW = 'adminhtml/createsend_email/view';
27
+ const PATH_EMAIL_INDEX = 'adminhtml/createsend_email/index';
28
+
29
+ public function indexAction()
30
+ {
31
+ $this->loadLayout();
32
+ $this->_setActiveMenu('system');
33
+ $this->renderLayout();
34
+ }
35
+
36
+ public function gridAction()
37
+ {
38
+ $this->loadLayout();
39
+ $this->renderLayout();
40
+ }
41
+
42
+ public function viewAction()
43
+ {
44
+ $emailId = $this->getRequest()->getParam('email_id');
45
+ $display = $this->getRequest()->getParam('display');
46
+
47
+ /** @var Campaignmonitor_Createsend_Model_Email $email */
48
+ $email = Mage::getModel('createsend/email')->load($emailId);
49
+
50
+ $messageId = $email->getMessageId();
51
+
52
+ if (empty($messageId)) {
53
+ Mage::getSingleton('adminhtml/session')->addError(sprintf(self::ERR_EMAIL_NOT_FOUND));
54
+ return $this->_redirectReferer();
55
+ }
56
+
57
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
58
+ $api = Mage::getModel('createsend/api');
59
+
60
+ $scope = $email->getScope();
61
+ $scopeId = $email->getScopeId();
62
+
63
+ $reply = $api->call(
64
+ Zend_Http_Client::GET,
65
+ "transactional/messages/${messageId}",
66
+ array(),
67
+ array('statistics' => 'true'),
68
+ $scope,
69
+ $scopeId
70
+ );
71
+
72
+ if (!$reply['success']) {
73
+ Mage::getSingleton('adminhtml/session')->addError(sprintf(self::ERR_API_ERROR, $reply['data']['Message']));
74
+ return $this->_redirectReferer();
75
+ }
76
+
77
+ $reply['data']['email_id'] = $emailId;
78
+
79
+ if ($display === 'body') {
80
+ if (isset($reply['data']['Message']['Body']['Html'])) {
81
+ print $reply['data']['Message']['Body']['Html'];
82
+ } else {
83
+ print '';
84
+ }
85
+ } else {
86
+ Mage::register('createsend_email', $reply['data']);
87
+
88
+ $this->loadLayout();
89
+
90
+ $request = Mage::app()->getRequest();
91
+ $customerId = $request->getUserParam('customer_id');
92
+ if ($customerId) {
93
+ $this->_setActiveMenu('customer');
94
+ } else {
95
+ $this->_setActiveMenu('system');
96
+ }
97
+
98
+ return $this->renderLayout();
99
+ }
100
+ }
101
+
102
+ public function resendAction()
103
+ {
104
+ $emailId = $this->getRequest()->getParam('email_id');
105
+
106
+ /** @var Campaignmonitor_Createsend_Model_Email $email */
107
+ $email = Mage::getModel('createsend/email')->load($emailId);
108
+
109
+ $messageId = $email->getMessageId();
110
+
111
+ if (empty($messageId)) {
112
+ Mage::getSingleton('adminhtml/session')->addError(sprintf(self::ERR_EMAIL_NOT_FOUND));
113
+ return $this->_redirect(self::PATH_EMAIL_VIEW, array('email_id' => $emailId));
114
+ }
115
+
116
+ if (!$email->getCanBeResent()) {
117
+ Mage::getSingleton('adminhtml/session')->addError(sprintf(self::ERR_EMAIL_CANNOT_BE_RESENT));
118
+ return $this->_redirect(self::PATH_EMAIL_VIEW, array('email_id' => $emailId));
119
+ }
120
+
121
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
122
+ $api = Mage::getModel('createsend/api');
123
+
124
+ $scope = $email->getScope();
125
+ $scopeId = $email->getScopeId();
126
+
127
+ $reply = $api->call(
128
+ Zend_Http_Client::POST,
129
+ "transactional/messages/${messageId}/resend",
130
+ array(),
131
+ array(),
132
+ $scope,
133
+ $scopeId
134
+ );
135
+
136
+ if ($reply['success'] !== false) {
137
+ Mage::getSingleton('adminhtml/session')
138
+ ->addSuccess(sprintf(self::LOG_EMAIL_RESENT, $reply['data']['Status']));
139
+ } else {
140
+ Mage::getSingleton('adminhtml/session')
141
+ ->addError(sprintf(self::ERR_UNABLE_TO_RESEND_EMAIL, $reply['data']['Message']));
142
+ }
143
+
144
+ return $this->_redirect(self::PATH_EMAIL_VIEW, array('email_id' => $emailId));
145
+ }
146
+ }
app/code/community/Campaignmonitor/Createsend/controllers/Adminhtml/Createsend/SegmentController.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+ class Campaignmonitor_Createsend_Adminhtml_Createsend_SegmentController extends Mage_Adminhtml_Controller_Action
18
+ {
19
+ const ADMINHTML_SYSTEM_CONFIG_EDIT = 'adminhtml/system_config/edit';
20
+
21
+ /**
22
+ * Responsible for creating Campaign Monitor segments.
23
+ *
24
+ * @link https://www.campaignmonitor.com/api/segments/
25
+ *
26
+ * @return Mage_Core_Controller_Varien_Action
27
+ */
28
+ public function createExamplesAction()
29
+ {
30
+ $scope = $this->getRequest()->getQuery('scope');
31
+ $scopeId = $this->getRequest()->getQuery('scopeId');
32
+
33
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
34
+ $api = Mage::getModel('createsend/api');
35
+
36
+ $responses = $api->createExampleSegments($scope, $scopeId);
37
+
38
+ print json_encode(
39
+ array(
40
+ 'messages' => $responses
41
+ )
42
+ );
43
+ }
44
+ }
app/code/community/Campaignmonitor/Createsend/controllers/OauthController.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_OauthController extends Mage_Adminhtml_Controller_Action
19
+ {
20
+ const HTTP_OK = 200;
21
+ const HTTP_BAD_REQUEST = 400;
22
+ const HTTP_METHOD_NOT_ALLOWED = 405;
23
+
24
+ const LOG_TOKEN_REDIRECT = 'Campaign Monitor API Redirect: %s';
25
+
26
+ const ERR_OAUTH_EXCHANGE = 'Error in OAuth Exchange: %s';
27
+ const ERR_INVALID_SCOPE = 'Invalid state/scope: %s';
28
+ const ERR_UNABLE_TO_AUTHENTICATE = 'Unable to authenticate: %s';
29
+ const ERR_UNABLE_TO_SAVE_TOKEN = 'Unable to save OAuth Token: %s';
30
+ const MSG_OAUTH_TOKEN_SAVED = 'OAuth Token saved.';
31
+
32
+ const ADMINHTML_SYSTEM_CONFIG_EDIT = 'adminhtml/system_config/edit';
33
+
34
+ // Disable validation of admin url key to allow redirection from frontend to system config section
35
+ protected $_publicActions = array('getToken');
36
+
37
+ /**
38
+ * Responsible for requesting Campaign Monitor OAuth Permission
39
+ * and storage of access_token, expires_in and refresh_token.
40
+ *
41
+ * @link https://www.campaignmonitor.com/api/getting-started/#authenticating_with_oauth
42
+ */
43
+ public function getTokenAction()
44
+ {
45
+ $configSection = array('section' => 'createsend_general');
46
+
47
+ /** @var $helper Campaignmonitor_Createsend_Helper_Data */
48
+ $helper = Mage::helper("createsend");
49
+
50
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
51
+ $api = Mage::getModel('createsend/api');
52
+
53
+ $helper->log(
54
+ sprintf(self::LOG_TOKEN_REDIRECT, implode(',', $this->getRequest()->getParams())),
55
+ Zend_Log::DEBUG
56
+ );
57
+
58
+ $request = $this->getRequest();
59
+ $state = explode(',', $request->getQuery('state'));
60
+
61
+ if (sizeof($state) == 2) {
62
+ $scope = $state[0];
63
+ $scopeId = $state[1];
64
+ } else {
65
+ $helper->log(sprintf(self::ERR_INVALID_SCOPE, $state), Zend_Log::DEBUG);
66
+
67
+ Mage::getSingleton('adminhtml/session')->addError(sprintf(self::ERR_INVALID_SCOPE, $state));
68
+ return $this->_redirect(self::ADMINHTML_SYSTEM_CONFIG_EDIT, $configSection);
69
+ }
70
+
71
+ /** @var Campaignmonitor_Createsend_Model_Config_Scope $scopeModel */
72
+ $scopeModel = Mage::getModel('createsend/config_scope');
73
+ $storeId = $scopeModel->getStoreIdFromScope($scope, $scopeId);
74
+ $websiteId = $scopeModel->getWebsiteIdFromScope($scope, $scopeId);
75
+
76
+ $store = Mage::app()->getStore($storeId)->getCode();
77
+ $website = Mage::app()->getWebsite($websiteId)->getCode();
78
+
79
+ $configSection['website'] = $website;
80
+ $configSection['store'] = $store;
81
+
82
+ $errorMessage = $request->getQuery('error_description');
83
+ if (!empty($errorMessage)) {
84
+ $helper->log(
85
+ sprintf(self::ERR_OAUTH_EXCHANGE, $errorMessage),
86
+ Zend_Log::DEBUG
87
+ );
88
+
89
+ Mage::getSingleton('adminhtml/session')->addError(sprintf(self::ERR_UNABLE_TO_AUTHENTICATE, $errorMessage));
90
+ return $this->_redirect(self::ADMINHTML_SYSTEM_CONFIG_EDIT, $configSection);
91
+ }
92
+
93
+ $reply = $api->call(
94
+ Zend_Http_Client::POST,
95
+ 'token',
96
+ array(),
97
+ array(
98
+ 'grant_type' => 'authorization_code',
99
+ 'client_id' => $helper->getOAuthClientId($storeId),
100
+ 'client_secret' => $helper->getOAuthClientSecret($storeId),
101
+ 'code' => $request->getQuery('code'),
102
+ 'redirect_uri' => $api->getOauthRedirectUri($scope, $scopeId),
103
+ ),
104
+ $scope,
105
+ $scopeId
106
+ );
107
+
108
+ if (!empty($reply['data']['access_token'])) {
109
+ $result = $helper->saveOauthTokenData($reply['data'], $scope, $scopeId);
110
+
111
+ if ($result) {
112
+ Mage::getSingleton('adminhtml/session')->addSuccess(
113
+ sprintf(self::MSG_OAUTH_TOKEN_SAVED, $reply['data']['access_token'])
114
+ );
115
+ } else {
116
+ Mage::getSingleton('adminhtml/session')->addError(
117
+ sprintf(self::ERR_UNABLE_TO_SAVE_TOKEN, $reply['data']['access_token'])
118
+ );
119
+ }
120
+
121
+ $webhookId = $helper->getScopedConfig(Campaignmonitor_Createsend_Helper_Data::XML_PATH_WEBHOOK_ID, $scope, $scopeId);
122
+ $webhookEnabled = $helper->isWebhookEnabled($storeId);
123
+
124
+ if ($webhookEnabled && $webhookId === false) {
125
+ // Register webhooks after successfully getting the OAuth token
126
+ /** @var Campaignmonitor_Createsend_Model_Api $api */
127
+ $api = Mage::getModel('createsend/api');
128
+ $reply = $api->updateWebhooks($scope, $scopeId);
129
+
130
+ if ($reply['success'] === false) {
131
+ Mage::getSingleton('adminhtml/session')->addError(
132
+ sprintf(Campaignmonitor_Createsend_Model_Api::ERR_CANNOT_UPDATE_WEBHOOK, $reply['data']['Message'])
133
+ );
134
+ } else {
135
+ if ($reply['data']['Message']) {
136
+ Mage::getSingleton('adminhtml/session')->addSuccess(sprintf($reply['data']['Message']));
137
+ }
138
+ }
139
+ }
140
+ } else {
141
+ Mage::getSingleton('adminhtml/session')->addError(
142
+ sprintf(self::ERR_UNABLE_TO_AUTHENTICATE, $reply['data']['Message'])
143
+ );
144
+ }
145
+
146
+ return $this->_redirect(self::ADMINHTML_SYSTEM_CONFIG_EDIT, $configSection);
147
+ }
148
+ }
app/code/community/Campaignmonitor/Createsend/controllers/UnsubscribeController.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ class Campaignmonitor_Createsend_UnsubscribeController extends Mage_Core_Controller_Front_Action
19
+ {
20
+ //
21
+ // /**
22
+ // * Responsible for unsubscribing users already unsubscribed by Campaign Monitor.
23
+ // *
24
+ // * @deprecated in 1.0.0 in favour of Webhooks. See Campaignmonitor_Createsend_WebhooksController.
25
+ // */
26
+ //
27
+ // public function indexAction()
28
+ // {
29
+ // /** @var $helper Campaignmonitor_Createsend_Helper_Data */
30
+ // $helper = Mage::helper("createsend");
31
+ // $email = $this->getRequest()->getQuery('email');
32
+ //
33
+ // // don't do anything if we didn't get the email parameter
34
+ // if (!$email) {
35
+ // return $this->_redirect('customer/account/');
36
+ // }
37
+ // /** @var Campaignmonitor_Createsend_Model_Api $api */
38
+ // $api = Mage::getModel('createsend/api');
39
+ //
40
+ // // Check that the email address actually is unsubscribed in Campaign Monitor
41
+ // $result = $api->call(
42
+ // Zend_Http_Client::GET,
43
+ // 'subscribers/' . $helper->getListId(),
44
+ // null,
45
+ // array(
46
+ // 'email' => $email
47
+ // )
48
+ // );
49
+ //
50
+ // if ($result['success'] === false) {
51
+ // return $this->_redirect('customer/account');
52
+ // }
53
+ //
54
+ // // If customer is unsubscribed in Campaign Monitor mark as such in Magento
55
+ // if (in_array($result['Data']['State'], array('Unsubscribed', 'Deleted'))) {
56
+ // $helper->log("Unsubscribing $email");
57
+ // Mage::getModel('newsletter/subscriber')
58
+ // ->loadByEmail($email)
59
+ // ->unsubscribe();
60
+ // Mage::getSingleton('customer/session')->addSuccess($this->__('You were successfully unsubscribed'));
61
+ // } else {
62
+ // Mage::getSingleton('customer/session')->addWarning($this->__('Please unsubscribe from Campaign Monitor first'));
63
+ // }
64
+ //
65
+ // return $this->_redirect('customer/account/');
66
+ // }
67
+ }
app/code/community/Campaignmonitor/Createsend/controllers/WebhooksController.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /**
19
+ * Responsible for handling the webhooks posted by Campaign Monitor
20
+ */
21
+ class Campaignmonitor_Createsend_WebhooksController extends Mage_Core_Controller_Front_Action
22
+ {
23
+ const ERR_HOOK_LIST_DOESNT_MATCH = 'The list stored in config "%s" does not match the webhook list "%s"';
24
+
25
+ const HTTP_OK = 200;
26
+ const HTTP_BAD_REQUEST = 400;
27
+ const HTTP_METHOD_NOT_ALLOWED = 405;
28
+
29
+ /**
30
+ * Process the deactivate webhook
31
+ *
32
+ * Expects an array of the form:
33
+ * [ListID] => fc6d0b8414e11d3a747ea73b05b23737
34
+ * [Events] => Array
35
+ * [0] => Array
36
+ * [Type] => Deactivate
37
+ * [Date] => 2010-01-01
38
+ * [State] => Unsubscribed
39
+ * [EmailAddress] => test@example.org
40
+ * [Name] => Test Subscriber
41
+ * [CustomFields] => Array
42
+ * => Array
43
+ * [Key] => website
44
+ * [Value] => http://example.org
45
+ *
46
+ * @throws Zend_Controller_Response_Exception if the response code given is not in range
47
+ */
48
+ public function indexAction()
49
+ {
50
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
51
+ $helper = Mage::helper('createsend');
52
+
53
+ $helper->log(
54
+ sprintf('Webhook callback: ', implode(',', $this->getRequest()->getParams())),
55
+ Zend_Log::DEBUG
56
+ );
57
+
58
+ // Do nothing if accessed outside of POST action
59
+ if ($this->getRequest()->isPost() === false) {
60
+ $this->getResponse()->setHttpResponseCode(self::HTTP_METHOD_NOT_ALLOWED);
61
+ return;
62
+ }
63
+
64
+ try {
65
+ $hookData = Zend_Json::decode($this->getRequest()->getRawBody());
66
+ } catch (Zend_Json_Exception $e) {
67
+ $helper->log('Error decoding webhook body: ' . $e->getMessage());
68
+ $this->getResponse()->setHttpResponseCode(self::HTTP_BAD_REQUEST);
69
+ return;
70
+ }
71
+
72
+ // Get scope/scopeId from the config for the LIST ID supplied by CM
73
+ $configModel = Mage::getModel('core/config_data')->getCollection()
74
+ ->addFieldToFilter('path', Campaignmonitor_Createsend_Helper_Data::XML_PATH_LIST_ID)
75
+ ->addFieldToFilter('value', $hookData['ListID'])
76
+ ->addFieldToSelect('scope')
77
+ ->addFieldToSelect('scope_id')
78
+ ->setPageSize(1)
79
+ ->getFirstItem();
80
+
81
+ if (!$configModel) {
82
+ $this->getResponse()->setHttpResponseCode(self::HTTP_BAD_REQUEST);
83
+ return;
84
+ }
85
+
86
+ $scope = $configModel['scope'];
87
+ $scopeId = $configModel['scope_id'];
88
+
89
+ $storeId = Mage::getModel('createsend/config_scope')->getStoreIdFromScope($scope, $scopeId);
90
+
91
+ /** @var Campaignmonitor_Createsend_Model_Newsletter $newsletter */
92
+ $newsletter = Mage::getModel('createsend/newsletter');
93
+
94
+ foreach ($hookData['Events'] as $event) {
95
+ $email = $event['EmailAddress'];
96
+
97
+ if ($event['Type'] === Campaignmonitor_Createsend_Model_Api::WEBHOOK_EVENT_SUBSCRIBE) {
98
+ $newsletter->subscribe($email, $storeId);
99
+ } elseif ($event['Type'] === Campaignmonitor_Createsend_Model_Api::WEBHOOK_EVENT_DEACTIVATE) {
100
+ $newsletter->unsubscribe($email);
101
+ } elseif ($event['Type'] === Campaignmonitor_Createsend_Model_Api::WEBHOOK_EVENT_UPDATE) {
102
+ $oldEmail = $event['OldEmailAddress'];
103
+ $state = $event['State'];
104
+
105
+ if ($state === Campaignmonitor_Createsend_Model_Api::WEBHOOK_STATUS_ACTIVE) {
106
+ if ($oldEmail && $email !== $oldEmail) {
107
+ $newsletter->unsubscribe($oldEmail);
108
+ }
109
+
110
+ $newsletter->subscribe($email, $storeId);
111
+ } elseif ($state === Campaignmonitor_Createsend_Model_Api::WEBHOOK_STATUS_UNSUBSCRIBED
112
+ || $state === Campaignmonitor_Createsend_Model_Api::WEBHOOK_STATUS_DELETED) {
113
+
114
+ if ($oldEmail && $email !== $oldEmail) {
115
+ $newsletter->unsubscribe($oldEmail);
116
+ }
117
+
118
+ $newsletter->unsubscribe($email);
119
+ }
120
+ }
121
+ }
122
+
123
+ $this->getResponse()->setHttpResponseCode(self::HTTP_OK);
124
+ }
125
+ }
app/code/community/Campaignmonitor/Createsend/etc/adminhtml.xml ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Campaign Monitor Magento Extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you are unable to obtain it through the world-wide-web, please
12
+ * send an email to license@magento.com and you will be sent a copy.
13
+ *
14
+ * @package Campaignmonitor_Createsend
15
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+ -->
19
+ <config>
20
+ <menu>
21
+ <system>
22
+ <children>
23
+ <createsend translate="title" module="createsend">
24
+ <title>Campaign Monitor</title>
25
+ <sort_order>61</sort_order>
26
+ <children>
27
+ <createsend_tracking>
28
+ <title>Email Tracking</title>
29
+ <sort_order>0</sort_order>
30
+ <action>adminhtml/createsend_email</action>
31
+ </createsend_tracking>
32
+ </children>
33
+ </createsend>
34
+ </children>
35
+ </system>
36
+ </menu>
37
+ <acl>
38
+ <resources>
39
+ <all>
40
+ <title>Allow Everything</title>
41
+ </all>
42
+ <admin>
43
+ <children>
44
+ <system>
45
+ <children>
46
+ <createsend module="createsend">
47
+ <title>Campaign Monitor</title>
48
+ <children>
49
+ <createsend_tracking translate="title" module="createsend">
50
+ <title>Email Tracking</title>
51
+ <sort_order>20</sort_order>
52
+ </createsend_tracking>
53
+ </children>
54
+ </createsend>
55
+ </children>
56
+ </system>
57
+ </children>
58
+ </admin>
59
+ </resources>
60
+ </acl>
61
+ </config>
app/code/community/Campaignmonitor/Createsend/etc/config.xml ADDED
@@ -0,0 +1,292 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Campaign Monitor Magento Extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you are unable to obtain it through the world-wide-web, please
12
+ * send an email to license@magento.com and you will be sent a copy.
13
+ *
14
+ * @package Campaignmonitor_Createsend
15
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+ -->
19
+ <config>
20
+ <modules>
21
+ <Campaignmonitor_Createsend>
22
+ <version>1.0.0</version>
23
+ </Campaignmonitor_Createsend>
24
+ </modules>
25
+ <adminhtml>
26
+ <layout>
27
+ <updates>
28
+ <campaignmonitor_createsend>
29
+ <file>campaignmonitor/createsend.xml</file>
30
+ </campaignmonitor_createsend>
31
+ </updates>
32
+ </layout>
33
+ <acl>
34
+ <resources>
35
+ <admin>
36
+ <children>
37
+ <system>
38
+ <children>
39
+ <config>
40
+ <children>
41
+ <createsend_general>
42
+ <title>Campaign Monitor General Section</title>
43
+ </createsend_general>
44
+ <createsend_customers>
45
+ <title>Campaign Monitor Customers Section</title>
46
+ </createsend_customers>
47
+ <createsend_transactional>
48
+ <title>Campaign Monitor Transactional Section</title>
49
+ </createsend_transactional>
50
+ </children>
51
+ </config>
52
+ </children>
53
+ </system>
54
+ </children>
55
+ </admin>
56
+ </resources>
57
+ </acl>
58
+ <events>
59
+ <controller_action_layout_generate_blocks_after>
60
+ <observers>
61
+ <campaignmonitor_createsend_addjs>
62
+ <type>singleton</type>
63
+ <class>createsend/config_api</class>
64
+ <method>addJavascriptBlock</method>
65
+ </campaignmonitor_createsend_addjs>
66
+ </observers>
67
+ </controller_action_layout_generate_blocks_after>
68
+ </events>
69
+ </adminhtml>
70
+ <global>
71
+ <models>
72
+ <createsend>
73
+ <class>Campaignmonitor_Createsend_Model</class>
74
+ <resourceModel>createsend_resource</resourceModel>
75
+ </createsend>
76
+ <createsend_resource>
77
+ <class>Campaignmonitor_Createsend_Model_Resource</class>
78
+ <entities>
79
+ <email>
80
+ <table>campaignmonitor_createsend_email</table>
81
+ </email>
82
+ </entities>
83
+ </createsend_resource>
84
+ <core>
85
+ <rewrite>
86
+ <email_template>Campaignmonitor_Createsend_Model_Email_Template</email_template>
87
+ </rewrite>
88
+ </core>
89
+ </models>
90
+ <resources>
91
+ <campaignmonitor_createsend_setup>
92
+ <setup>
93
+ <module>Campaignmonitor_Createsend</module>
94
+ </setup>
95
+ <connection>
96
+ <use>core_setup</use>
97
+ </connection>
98
+ </campaignmonitor_createsend_setup>
99
+ </resources>
100
+ <helpers>
101
+ <createsend>
102
+ <class>Campaignmonitor_Createsend_Helper</class>
103
+ </createsend>
104
+ </helpers>
105
+ <blocks>
106
+ <createsend>
107
+ <class>Campaignmonitor_Createsend_Block</class>
108
+ </createsend>
109
+ </blocks>
110
+ <events>
111
+ <customer_save_before>
112
+ <observers>
113
+ <campaignmonitor_createsend_check_subscription_status>
114
+ <type>singleton</type>
115
+ <class>createsend/customer_observer</class>
116
+ <method>checkSubscriptionStatus</method>
117
+ </campaignmonitor_createsend_check_subscription_status>
118
+ </observers>
119
+ </customer_save_before>
120
+ <customer_delete_before>
121
+ <observers>
122
+ <campaignmonitor_createsend_customer_deleted>
123
+ <type>singleton</type>
124
+ <class>createsend/customer_observer</class>
125
+ <method>customerDeleted</method>
126
+ </campaignmonitor_createsend_customer_deleted>
127
+ </observers>
128
+ </customer_delete_before>
129
+ <sales_order_save_after>
130
+ <observers>
131
+ <campaignmonitor_createsend_check_subscription_status>
132
+ <type>singleton</type>
133
+ <class>createsend/customer_observer</class>
134
+ <method>checkSubscriptionStatus</method>
135
+ </campaignmonitor_createsend_check_subscription_status>
136
+ </observers>
137
+ </sales_order_save_after>
138
+ <wishlist_product_add_after>
139
+ <observers>
140
+ <campaignmonitor_createsend_check_subscription_status>
141
+ <type>singleton</type>
142
+ <class>createsend/customer_observer</class>
143
+ <method>checkSubscriptionStatus</method>
144
+ </campaignmonitor_createsend_check_subscription_status>
145
+ </observers>
146
+ </wishlist_product_add_after>
147
+ <admin_system_config_changed_section_createsend_general>
148
+ <observers>
149
+ <campaignmonitor_createsend_update_webhook>
150
+ <type>singleton</type>
151
+ <class>createsend/api_observer</class>
152
+ <method>checkConfig</method>
153
+ </campaignmonitor_createsend_update_webhook>
154
+ </observers>
155
+ </admin_system_config_changed_section_createsend_general>
156
+ <admin_system_config_changed_section_createsend_customers>
157
+ <observers>
158
+ <campaignmonitor_createsend_create_custom_fields>
159
+ <type>singleton</type>
160
+ <class>createsend/customer_observer</class>
161
+ <method>createCustomFields</method>
162
+ </campaignmonitor_createsend_create_custom_fields>
163
+ </observers>
164
+ </admin_system_config_changed_section_createsend_customers>
165
+ <controller_action_predispatch_adminhtml_newsletter_subscriber_massUnsubscribe>
166
+ <observers>
167
+ <campaignmonitor_createsend_update_user_massaction>
168
+ <type>singleton</type>
169
+ <class>createsend/api_observer</class>
170
+ <method>massUnsubscribeUsers</method>
171
+ </campaignmonitor_createsend_update_user_massaction>
172
+ </observers>
173
+ </controller_action_predispatch_adminhtml_newsletter_subscriber_massUnsubscribe>
174
+ <controller_action_predispatch_adminhtml_newsletter_subscriber_massDelete>
175
+ <observers>
176
+ <campaignmonitor_createsend_update_user_massaction>
177
+ <type>singleton</type>
178
+ <class>createsend/api_observer</class>
179
+ <method>massUnsubscribeUsers</method>
180
+ </campaignmonitor_createsend_update_user_massaction>
181
+ </observers>
182
+ </controller_action_predispatch_adminhtml_newsletter_subscriber_massDelete>
183
+ <controller_action_predispatch_newsletter_subscriber_new>
184
+ <observers>
185
+ <campaignmonitor_createsend_subscribe_new_user>
186
+ <type>singleton</type>
187
+ <class>createsend/api_observer</class>
188
+ <method>subscribeNewUser</method>
189
+ </campaignmonitor_createsend_subscribe_new_user>
190
+ </observers>
191
+ </controller_action_predispatch_newsletter_subscriber_new>
192
+ <!-- Bug fix for Magento newsletter's change_status_at field non-update bug. -->
193
+ <newsletter_subscriber_save_before>
194
+ <observers>
195
+ <campaignmonitor_createsend_newsletter_change_status_update>
196
+ <type>singleton</type>
197
+ <class>createsend/newsletter_observer</class>
198
+ <method>setChangeStatusAt</method>
199
+ </campaignmonitor_createsend_newsletter_change_status_update>
200
+ </observers>
201
+ </newsletter_subscriber_save_before>
202
+ <catalog_product_save_after>
203
+ <observers>
204
+ <campaignmonitor_createsend_product_update>
205
+ <type>singleton</type>
206
+ <class>createsend/product_observer</class>
207
+ <method>updateWishlistFields</method>
208
+ </campaignmonitor_createsend_product_update>
209
+ </observers>
210
+ </catalog_product_save_after>
211
+ </events>
212
+ </global>
213
+ <admin>
214
+ <routers>
215
+ <adminhtml>
216
+ <args>
217
+ <modules>
218
+ <Campaignmonitor_Createsend before="Mage_Adminhtml">Campaignmonitor_Createsend_Adminhtml</Campaignmonitor_Createsend>
219
+ </modules>
220
+ </args>
221
+ </adminhtml>
222
+ </routers>
223
+ </admin>
224
+ <frontend>
225
+ <routers>
226
+ <createsend>
227
+ <use>standard</use>
228
+ <args>
229
+ <module>Campaignmonitor_Createsend</module>
230
+ <frontName>createsend</frontName>
231
+ </args>
232
+ </createsend>
233
+ </routers>
234
+ </frontend>
235
+ <default>
236
+ <createsend_general>
237
+ <api>
238
+ <authentication_method>api_key</authentication_method>
239
+ </api>
240
+ <advanced>
241
+ <logging>1</logging>
242
+ <webhook_enabled>1</webhook_enabled>
243
+ <subscriber_synchronisation_enabled>1</subscriber_synchronisation_enabled>
244
+ <subscriber_synchronisation_resolution_method>timestamp</subscriber_synchronisation_resolution_method>
245
+ <magento_cron_enabled>1</magento_cron_enabled>
246
+ </advanced>
247
+ </createsend_general>
248
+ <createsend_customers>
249
+ <attributes>
250
+ <m_to_cm_attributes>a:19:{i:0;a:1:{s:7:"magento";s:18:"FONTIS-has-account";}i:1;a:1:{s:7:"magento";s:10:"created_in";}i:2;a:1:{s:7:"magento";s:8:"group_id";}i:3;a:1:{s:7:"magento";s:10:"created_at";}i:4;a:1:{s:7:"magento";s:9:"firstname";}i:5;a:1:{s:7:"magento";s:8:"lastname";}i:6;a:1:{s:7:"magento";s:3:"dob";}i:7;a:1:{s:7:"magento";s:6:"gender";}i:8;a:1:{s:7:"magento";s:12:"confirmation";}i:9;a:1:{s:7:"magento";s:10:"website_id";}i:10;a:1:{s:7:"magento";s:8:"store_id";}i:11;a:1:{s:7:"magento";s:32:"FONTIS-sales-average-order-value";}i:12;a:1:{s:7:"magento";s:29:"FONTIS-sales-first-order-date";}i:13;a:1:{s:7:"magento";s:29:"FONTIS-sales-last-order-value";}i:14;a:1:{s:7:"magento";s:28:"FONTIS-sales-last-order-date";}i:15;a:1:{s:7:"magento";s:30:"FONTIS-sales-total-order-value";}i:16;a:1:{s:7:"magento";s:35:"FONTIS-sales-total-number-of-orders";}i:17;a:1:{s:7:"magento";s:45:"FONTIS-sales-total-number-of-products-ordered";}i:18;a:1:{s:7:"magento";s:31:"FONTIS-number-of-wishlist-items";}}</m_to_cm_attributes>
251
+ </attributes>
252
+ <wishlists>
253
+ <max_wishlist_items>1</max_wishlist_items>
254
+ <wishlist_product_attributes>a:4:{i:0;a:1:{s:7:"magento";s:4:"name";}i:1;a:1:{s:7:"magento";s:5:"price";}i:2;a:1:{s:7:"magento";s:17:"short_description";}i:3;a:1:{s:7:"magento";s:3:"sku";}}</wishlist_product_attributes>
255
+ </wishlists>
256
+ </createsend_customers>
257
+ <createsend_transactional>
258
+ <emails>
259
+ <transactional_email_enabled>0</transactional_email_enabled>
260
+ <transactional_email_retention_days>90</transactional_email_retention_days>
261
+ </emails>
262
+ </createsend_transactional>
263
+ </default>
264
+ <crontab>
265
+ <jobs>
266
+ <campaignmonitor_createsend_subscriber_synchronise_initial>
267
+ <schedule>
268
+ <cron_expr>*/5 * * * *</cron_expr>
269
+ </schedule>
270
+ <run>
271
+ <model>createsend/list_initial_cron::runFromMagentoCron</model>
272
+ </run>
273
+ </campaignmonitor_createsend_subscriber_synchronise_initial>
274
+ <campaignmonitor_createsend_subscriber_synchronise>
275
+ <schedule>
276
+ <cron_expr>0 1 * * *</cron_expr>
277
+ </schedule>
278
+ <run>
279
+ <model>createsend/list_cron::runFromMagentoCron</model>
280
+ </run>
281
+ </campaignmonitor_createsend_subscriber_synchronise>
282
+ <campaignmonitor_createsend_email_download>
283
+ <schedule>
284
+ <cron_expr>0 * * * *</cron_expr>
285
+ </schedule>
286
+ <run>
287
+ <model>createsend/email_cron::runFromMagentoCron</model>
288
+ </run>
289
+ </campaignmonitor_createsend_email_download>
290
+ </jobs>
291
+ </crontab>
292
+ </config>
app/code/community/Campaignmonitor/Createsend/etc/system.xml ADDED
@@ -0,0 +1,300 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Campaign Monitor Magento Extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you are unable to obtain it through the world-wide-web, please
12
+ * send an email to license@magento.com and you will be sent a copy.
13
+ *
14
+ * @package Campaignmonitor_Createsend
15
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+ -->
19
+ <config>
20
+ <tabs>
21
+ <campaignmonitor translate="label" module="createsend">
22
+ <label>Campaign Monitor</label>
23
+ <sort_order>101</sort_order>
24
+ </campaignmonitor>
25
+ </tabs>
26
+
27
+ <sections>
28
+ <createsend_general translate="label" module="createsend">
29
+ <label>General</label>
30
+ <tab>campaignmonitor</tab>
31
+ <frontend_type>text</frontend_type>
32
+ <sort_order>10</sort_order>
33
+ <show_in_default>1</show_in_default>
34
+ <show_in_website>1</show_in_website>
35
+ <show_in_store>1</show_in_store>
36
+ <groups>
37
+ <api translate="label">
38
+ <label>API</label>
39
+ <frontend_type>text</frontend_type>
40
+ <sort_order>100</sort_order>
41
+ <show_in_default>1</show_in_default>
42
+ <show_in_website>1</show_in_website>
43
+ <show_in_store>1</show_in_store>
44
+ <fields>
45
+ <api_key translate="label comment">
46
+ <label>API Key</label>
47
+ <frontend_type>text</frontend_type>
48
+ <backend_model>createsend/config_backend_apikey</backend_model>
49
+ <sort_order>100</sort_order>
50
+ <show_in_default>1</show_in_default>
51
+ <show_in_website>1</show_in_website>
52
+ <show_in_store>1</show_in_store>
53
+ <comment><![CDATA[If you have multiple clients, you can find your client's API key <a href="https://www.campaignmonitor.com/api/getting-started/?#clientid" target="_blank">here</a>.<br />
54
+ If you're sending for yourself, you can find your own API key <a href="http://help.campaignmonitor.com/topic.aspx?t=1240" target="_blank">here</a>.
55
+ <div id="createsend_api_key_error_message"></div>]]></comment>
56
+ </api_key>
57
+ <api_client_id translate="label comment">
58
+ <label>Select your Campaign Monitor Client</label>
59
+ <frontend_type>select</frontend_type>
60
+ <backend_model>createsend/config_backend_listid</backend_model>
61
+ <source_model>createsend/config_clientSelection</source_model>
62
+ <sort_order>110</sort_order>
63
+ <show_in_default>1</show_in_default>
64
+ <show_in_website>1</show_in_website>
65
+ <show_in_store>1</show_in_store>
66
+ </api_client_id>
67
+ <list_id translate="label comment">
68
+ <label>Select a List</label>
69
+ <frontend_type>select</frontend_type>
70
+ <source_model>createsend/config_listSelection</source_model>
71
+ <backend_model>createsend/config_backend_listid</backend_model>
72
+ <sort_order>120</sort_order>
73
+ <show_in_default>1</show_in_default>
74
+ <show_in_website>1</show_in_website>
75
+ <show_in_store>1</show_in_store>
76
+ <comment>The Campaign Monitor subscriber list your Magento users will subscribe to or unsubscribe from.</comment>
77
+ </list_id>
78
+ <new_list_name translate="label comment">
79
+ <label>Create a new list in Campaign Monitor</label>
80
+ <frontend_type>text</frontend_type>
81
+ <sort_order>130</sort_order>
82
+ <show_in_default>1</show_in_default>
83
+ <show_in_website>1</show_in_website>
84
+ <show_in_store>1</show_in_store>
85
+ <depends><list_id>NEW_LIST</list_id></depends>
86
+ <comment>Name this new list</comment>
87
+ </new_list_name>
88
+ </fields>
89
+ </api>
90
+ <advanced translate="label">
91
+ <label>Advanced</label>
92
+ <frontend_type>text</frontend_type>
93
+ <sort_order>200</sort_order>
94
+ <show_in_default>1</show_in_default>
95
+ <show_in_website>1</show_in_website>
96
+ <show_in_store>1</show_in_store>
97
+ <fields>
98
+ <api_test_button translate="label comment">
99
+ <label>Test API</label>
100
+ <frontend_type>button</frontend_type>
101
+ <frontend_model>campaignmonitor_createsend_block_testApi</frontend_model>
102
+ <sort_order>60</sort_order>
103
+ <show_in_default>1</show_in_default>
104
+ <show_in_website>1</show_in_website>
105
+ <show_in_store>1</show_in_store>
106
+ <comment>Test your credentials are correct and can connect to Campaign Monitor's API. Make sure to click Save Config after entering your API key before testing.</comment>
107
+ </api_test_button>
108
+ <create_segment_button translate="label">
109
+ <label>Create Example Segments</label>
110
+ <frontend_type>button</frontend_type>
111
+ <frontend_model>campaignmonitor_createsend_block_createExampleSegments</frontend_model>
112
+ <sort_order>70</sort_order>
113
+ <show_in_default>1</show_in_default>
114
+ <show_in_website>1</show_in_website>
115
+ <show_in_store>1</show_in_store>
116
+ <comment>Create a set of Campaign Monitor example segments to target sub-groups of subscribers based on conditions.</comment>
117
+ </create_segment_button>
118
+ <logging translate="label comment">
119
+ <label>Enable Logging</label>
120
+ <frontend_type>select</frontend_type>
121
+ <source_model>adminhtml/system_config_source_yesno</source_model>
122
+ <sort_order>80</sort_order>
123
+ <show_in_default>1</show_in_default>
124
+ <show_in_website>0</show_in_website>
125
+ <show_in_store>0</show_in_store>
126
+ <comment>Log Campaign Monitor extension information and API requests. Requires Magento logging to be enabled.</comment>
127
+ </logging>
128
+ <webhook_enabled translate="label comment">
129
+ <label>Enable Webhooks</label>
130
+ <frontend_type>select</frontend_type>
131
+ <source_model>adminhtml/system_config_source_yesno</source_model>
132
+ <sort_order>100</sort_order>
133
+ <show_in_default>1</show_in_default>
134
+ <show_in_website>1</show_in_website>
135
+ <show_in_store>1</show_in_store>
136
+ <comment>Synchronize subscribes and unsubscribes performed in Campaign Monitor with Magento.</comment>
137
+ </webhook_enabled>
138
+ <subscriber_synchronisation_enabled translate="label comment">
139
+ <label>Enable Batch Subscriber Synchronization</label>
140
+ <frontend_type>select</frontend_type>
141
+ <source_model>adminhtml/system_config_source_yesno</source_model>
142
+ <sort_order>200</sort_order>
143
+ <show_in_default>1</show_in_default>
144
+ <show_in_website>1</show_in_website>
145
+ <show_in_store>1</show_in_store>
146
+ <comment>If 'Yes', perform a nightly batch synchronization of list subscribers.</comment>
147
+ </subscriber_synchronisation_enabled>
148
+ <subscriber_synchronisation_resolution_method translate="label comment">
149
+ <label>Subscription Synchronization Conflict Resolution Method</label>
150
+ <frontend_type>select</frontend_type>
151
+ <source_model>campaignmonitor_createsend_model_config_ConflictResolutionMethod</source_model>
152
+ <sort_order>210</sort_order>
153
+ <show_in_default>1</show_in_default>
154
+ <show_in_website>1</show_in_website>
155
+ <show_in_store>1</show_in_store>
156
+ <depends><subscriber_synchronisation_enabled>1</subscriber_synchronisation_enabled></depends>
157
+ <comment><![CDATA[Set to "Timestamp" to resolve subscription status conflicts by using the latest timestamp found in either Campaign Monitor or Magento.
158
+ <br />
159
+ Set to "Preferred Source" to resolve subscription status conflicts by choosing Campaign Monitor or Magento.]]></comment>
160
+ </subscriber_synchronisation_resolution_method>
161
+ <subscriber_synchronisation_preferred_source translate="label comment">
162
+ <label>Preferred Source</label>
163
+ <frontend_type>select</frontend_type>
164
+ <source_model>campaignmonitor_createsend_model_config_SubscriptionSources</source_model>
165
+ <sort_order>220</sort_order>
166
+ <show_in_default>1</show_in_default>
167
+ <show_in_website>1</show_in_website>
168
+ <show_in_store>1</show_in_store>
169
+ <depends>
170
+ <subscriber_synchronisation_enabled>1</subscriber_synchronisation_enabled>
171
+ <subscriber_synchronisation_resolution_method>source</subscriber_synchronisation_resolution_method>
172
+ </depends>
173
+ </subscriber_synchronisation_preferred_source>
174
+ <magento_cron_enabled translate="label comment">
175
+ <label>Use Magento cron</label>
176
+ <frontend_type>select</frontend_type>
177
+ <source_model>adminhtml/system_config_source_yesno</source_model>
178
+ <sort_order>300</sort_order>
179
+ <show_in_default>1</show_in_default>
180
+ <show_in_website>0</show_in_website>
181
+ <show_in_store>0</show_in_store>
182
+ <comment>Perform subscriber synchronization and email retrieval using Magento's cron system. If set to "No," a system cron job will need to be set up.</comment>
183
+ </magento_cron_enabled>
184
+ <create_segment_button translate="label comment">
185
+ <label>Create Example Segments</label>
186
+ <frontend_type>button</frontend_type>
187
+ <frontend_model>campaignmonitor_createsend_block_createExampleSegments</frontend_model>
188
+ <sort_order>700</sort_order>
189
+ <show_in_default>1</show_in_default>
190
+ <show_in_website>1</show_in_website>
191
+ <show_in_store>1</show_in_store>
192
+ <comment>Create a set of Campaign Monitor example segments to target sub-groups of subscribers based on purchasing habits.</comment>
193
+ </create_segment_button>
194
+ </fields>
195
+ </advanced>
196
+ </groups>
197
+ </createsend_general>
198
+ <createsend_customers translate="label" module="createsend">
199
+ <label>Customers</label>
200
+ <tab>campaignmonitor</tab>
201
+ <frontend_type>text</frontend_type>
202
+ <sort_order>20</sort_order>
203
+ <show_in_default>1</show_in_default>
204
+ <show_in_website>1</show_in_website>
205
+ <show_in_store>1</show_in_store>
206
+ <groups>
207
+ <attributes translate="label">
208
+ <label>Attributes</label>
209
+ <frontend_type>text</frontend_type>
210
+ <sort_order>100</sort_order>
211
+ <show_in_default>1</show_in_default>
212
+ <show_in_website>1</show_in_website>
213
+ <show_in_store>1</show_in_store>
214
+ <fields>
215
+ <m_to_cm_attributes translate="label comment">
216
+ <label>Custom Field Mapping</label>
217
+ <frontend_model>campaignmonitor_createsend_block_linkedattributes</frontend_model>
218
+ <backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
219
+ <sort_order>100</sort_order>
220
+ <show_in_default>1</show_in_default>
221
+ <show_in_website>1</show_in_website>
222
+ <show_in_store>1</show_in_store>
223
+ </m_to_cm_attributes>
224
+ </fields>
225
+ </attributes>
226
+ <wishlists translate="label">
227
+ <label>Wishlists</label>
228
+ <frontend_type>text</frontend_type>
229
+ <sort_order>200</sort_order>
230
+ <show_in_default>1</show_in_default>
231
+ <show_in_website>1</show_in_website>
232
+ <show_in_store>1</show_in_store>
233
+ <fields>
234
+ <max_wishlist_items translate="label comment">
235
+ <label>Number of wishlist products to include</label>
236
+ <frontend_type>text</frontend_type>
237
+ <sort_order>100</sort_order>
238
+ <show_in_default>1</show_in_default>
239
+ <show_in_website>1</show_in_website>
240
+ <show_in_store>1</show_in_store>
241
+ <validate>validate-zero-or-greater</validate>
242
+ <comment>Sets the maximum number of products from a customer's wishlist to send to Campaign Monitor's custom fields. Set to 0 to not send any wishlist data.</comment>
243
+ </max_wishlist_items>
244
+ <wishlist_product_attributes translate="label">
245
+ <label>Custom Field Mapping</label>
246
+ <frontend_model>campaignmonitor_createsend_block_wishlistattributes</frontend_model>
247
+ <backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
248
+ <sort_order>200</sort_order>
249
+ <show_in_default>1</show_in_default>
250
+ <show_in_website>1</show_in_website>
251
+ <show_in_store>1</show_in_store>
252
+ </wishlist_product_attributes>
253
+ </fields>
254
+ </wishlists>
255
+ </groups>
256
+ </createsend_customers>
257
+ <createsend_transactional translate="label" module="createsend">
258
+ <label>Transactional</label>
259
+ <tab>campaignmonitor</tab>
260
+ <frontend_type>text</frontend_type>
261
+ <sort_order>30</sort_order>
262
+ <show_in_default>1</show_in_default>
263
+ <show_in_website>1</show_in_website>
264
+ <show_in_store>1</show_in_store>
265
+ <groups>
266
+ <emails translate="label">
267
+ <label>Transactional Emails</label>
268
+ <frontend_type>text</frontend_type>
269
+ <sort_order>100</sort_order>
270
+ <show_in_default>1</show_in_default>
271
+ <show_in_website>1</show_in_website>
272
+ <show_in_store>1</show_in_store>
273
+ <fields>
274
+ <transactional_email_enabled translate="label comment">
275
+ <label>Enable Transactional Emails</label>
276
+ <frontend_type>select</frontend_type>
277
+ <source_model>adminhtml/system_config_source_yesno</source_model>
278
+ <sort_order>100</sort_order>
279
+ <show_in_default>1</show_in_default>
280
+ <show_in_website>1</show_in_website>
281
+ <show_in_store>1</show_in_store>
282
+ <comment>Send Magento generated transactional emails via Campaign Monitor. You will be able to view recently sent emails using the Magento Admin Panel.</comment>
283
+ </transactional_email_enabled>
284
+ <transactional_email_retention_days translate="label comment">
285
+ <label>Email Data Retention (days)</label>
286
+ <frontend_type>text</frontend_type>
287
+ <sort_order>200</sort_order>
288
+ <show_in_default>1</show_in_default>
289
+ <show_in_website>1</show_in_website>
290
+ <show_in_store>1</show_in_store>
291
+ <validate>validate-zero-or-greater</validate>
292
+ <comment>Number of days to retain email data in Magento. This will determine how long you are able to view emails in the Magento Admin Panel.</comment>
293
+ <depends><transactional_email_enabled>1</transactional_email_enabled></depends>
294
+ </transactional_email_retention_days>
295
+ </fields>
296
+ </emails>
297
+ </groups>
298
+ </createsend_transactional>
299
+ </sections>
300
+ </config>
app/code/community/Campaignmonitor/Createsend/sql/campaignmonitor_createsend_setup/install-1.0.0.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ /** @var $this Mage_Core_Model_Resource_Setup */
19
+ $this->startSetup();
20
+ $connection = $this->getConnection();
21
+
22
+ $emailTableName = $this->getTable("createsend/email");
23
+
24
+ $emailTable = $connection->newTable($emailTableName)
25
+ ->addColumn('email_id',
26
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
27
+ null,
28
+ array(
29
+ 'unsigned' => true,
30
+ 'nullable' => false,
31
+ 'primary' => true,
32
+ 'identity' => true,
33
+ ),
34
+ 'Email ID'
35
+ )
36
+ ->addColumn(
37
+ 'message_id',
38
+ Varien_Db_Ddl_Table::TYPE_VARCHAR,
39
+ 64,
40
+ array(
41
+ 'nullable' => false,
42
+ ),
43
+ 'Message ID'
44
+ )
45
+ ->addColumn(
46
+ 'status',
47
+ Varien_Db_Ddl_Table::TYPE_VARCHAR,
48
+ 64,
49
+ array(
50
+ 'nullable' => false,
51
+ ),
52
+ 'Status'
53
+ )
54
+ ->addColumn(
55
+ 'sent_at',
56
+ Varien_Db_Ddl_Table::TYPE_DATETIME,
57
+ null,
58
+ array(
59
+ 'nullable' => true,
60
+ 'default' => null,
61
+ ),
62
+ 'Date Sent'
63
+ )
64
+ ->addColumn(
65
+ 'recipient',
66
+ Varien_Db_Ddl_Table::TYPE_VARCHAR,
67
+ 1024,
68
+ array(
69
+ 'nullable' => false,
70
+ ),
71
+ 'Recipient'
72
+ )
73
+ ->addColumn(
74
+ 'sender',
75
+ Varien_Db_Ddl_Table::TYPE_VARCHAR,
76
+ 1024,
77
+ array(
78
+ 'nullable' => false,
79
+ ),
80
+ 'Sender'
81
+ )
82
+ ->addColumn(
83
+ 'subject',
84
+ Varien_Db_Ddl_Table::TYPE_TEXT,
85
+ null,
86
+ array(
87
+ 'nullable' => false,
88
+ ),
89
+ 'Subject'
90
+ )
91
+ ->addColumn(
92
+ 'total_opens',
93
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
94
+ null,
95
+ array(
96
+ 'nullable' => false,
97
+ ),
98
+ 'Total Opens'
99
+ )
100
+ ->addColumn(
101
+ 'total_clicks',
102
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
103
+ null,
104
+ array(
105
+ 'nullable' => false,
106
+ ),
107
+ 'Total Clicks'
108
+ )
109
+ ->addColumn(
110
+ 'can_be_resent',
111
+ Varien_Db_Ddl_Table::TYPE_BOOLEAN,
112
+ null,
113
+ array(
114
+ 'nullable' => false,
115
+ ),
116
+ 'Can be Resent'
117
+ )
118
+ ->addColumn(
119
+ 'scope',
120
+ Varien_Db_Ddl_Table::TYPE_VARCHAR,
121
+ 8,
122
+ array(
123
+ 'nullable' => false,
124
+ ),
125
+ 'Scope'
126
+ )
127
+ ->addColumn(
128
+ 'scope_id',
129
+ Varien_Db_Ddl_Table::TYPE_INTEGER,
130
+ 11,
131
+ array(
132
+ 'nullable' => false,
133
+ ),
134
+ 'Scope ID'
135
+ );
136
+
137
+ $connection->createTable($emailTable);
138
+
139
+ $this->endSetup();
app/design/adminhtml/default/default/layout/campaignmonitor/createsend.xml ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Campaign Monitor Magento Extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you are unable to obtain it through the world-wide-web, please
12
+ * send an email to license@magento.com and you will be sent a copy.
13
+ *
14
+ * @package Campaignmonitor_Createsend
15
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+ -->
19
+ <layout version="0.1.0">
20
+ <adminhtml_customer_edit>
21
+ <reference name="customer_edit_tabs">
22
+ <block type="createsend/adminhtml_customer_edit_grid" name="createsend_email_grid" after="-">
23
+ <action method="setTabLabel" module="createsend" translate="label">
24
+ <label>Campaign Monitor Emails</label>
25
+ </action>
26
+ <action method="setTabTitle" module="createsend" translate="title">
27
+ <title>Campaign Monitor Emails</title>
28
+ </action>
29
+ </block>
30
+ <action method="addTab">
31
+ <name>createsend_email_grid</name>
32
+ <block>createsend_email_grid</block>
33
+ </action>
34
+ </reference>
35
+ </adminhtml_customer_edit>
36
+
37
+ <adminhtml_createsend_email_index>
38
+ <reference name="content">
39
+ <block type="createsend/adminhtml_switcher" name="scope_switcher"/>
40
+ <block type="createsend/adminhtml_email" name="email_list"/>
41
+ </reference>
42
+ </adminhtml_createsend_email_index>
43
+
44
+ <adminhtml_createsend_email_grid>
45
+ <remove name="root"/>
46
+ <block type="createsend/adminhtml_email_grid" name="email_grid" output="toHtml"/>
47
+ </adminhtml_createsend_email_grid>
48
+
49
+ <adminhtml_createsend_email_view>
50
+ <reference name="left">
51
+ <block type="createsend/adminhtml_email_view_tabs" name="email_tabs">
52
+ <block type="createsend/adminhtml_email_view_tab_details"
53
+ name="email_details"
54
+ template="campaignmonitor/createsend/email/details.phtml">
55
+ <action method="setTabLabel" module="createsend" translate="label">
56
+ <label>Details</label>
57
+ </action>
58
+ <action method="setTabTitle" module="createsend" translate="title">
59
+ <title>Email Details</title>
60
+ </action>
61
+ </block>
62
+ <action method="addTab">
63
+ <name>email_details</name>
64
+ <block>email_details</block>
65
+ </action>
66
+
67
+ <block type="createsend/adminhtml_email_view_tab_html"
68
+ name="email_html"
69
+ template="campaignmonitor/createsend/email/html.phtml">
70
+ <action method="setTabLabel" module="createsend" translate="label">
71
+ <label>Body (HTML)</label>
72
+ </action>
73
+ <action method="setTabTitle" module="createsend" translate="title">
74
+ <title>Email Body (HTML Format)</title>
75
+ </action>
76
+ </block>
77
+ <action method="addTab">
78
+ <name>email_html</name>
79
+ <block>email_html</block>
80
+ </action>
81
+
82
+ <block type="createsend/adminhtml_email_view_tab_text"
83
+ name="email_text"
84
+ template="campaignmonitor/createsend/email/text.phtml">
85
+ <action method="setTabLabel" module="createsend" translate="label">
86
+ <label>Body (Text)</label>
87
+ </action>
88
+ <action method="setTabTitle" module="createsend" translate="title">
89
+ <title>Email Body (Text Format)</title>
90
+ </action>
91
+ </block>
92
+ <action method="addTab">
93
+ <name>email_text</name>
94
+ <block>email_text</block>
95
+ </action>
96
+
97
+ <block type="createsend/adminhtml_email_view_tab_opens"
98
+ name="email_opens"
99
+ template="campaignmonitor/createsend/email/tracking.phtml">
100
+ <action method="setTabLabel" module="createsend" translate="label">
101
+ <label>Opens</label>
102
+ </action>
103
+ <action method="setTabTitle" module="createsend" translate="title">
104
+ <title>Opens</title>
105
+ </action>
106
+ </block>
107
+ <action method="addTab">
108
+ <name>email_opens</name>
109
+ <block>email_opens</block>
110
+ </action>
111
+
112
+ <block type="createsend/adminhtml_email_view_tab_clicks"
113
+ name="email_clicks"
114
+ template="campaignmonitor/createsend/email/tracking.phtml">
115
+ <action method="setTabLabel" module="createsend" translate="label">
116
+ <label>Clicks</label>
117
+ </action>
118
+ <action method="setTabTitle" module="createsend" translate="title">
119
+ <title>Clicks</title>
120
+ </action>
121
+ </block>
122
+ <action method="addTab">
123
+ <name>email_clicks</name>
124
+ <block>email_clicks</block>
125
+ </action>
126
+ </block>
127
+ </reference>
128
+
129
+ <reference name="content">
130
+ <block type="createsend/adminhtml_email_view" name="email_view"/>
131
+ </reference>
132
+
133
+ </adminhtml_createsend_email_view>
134
+ </layout>
app/design/adminhtml/default/default/template/campaignmonitor/createsend/ajax.phtml ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** @var Campaignmonitor_Createsend_Block_AjaxButton $this */
3
+ ?>
4
+ <script type="text/javascript">
5
+ //<![CDATA[
6
+ function <?php echo $this->getAjaxFunction() ?>()
7
+ {
8
+ document.getElementById('<?php echo $this->getAjaxFunction() ?>_status')['innerHTML'] = 'Sending request...';
9
+ new Ajax.Request(
10
+ '<?php echo $this->getAjaxUrl() ?>',
11
+ {
12
+ method: 'get',
13
+ onSuccess: function(response)
14
+ {
15
+ if (response.responseText) {
16
+ var reply = eval ("(" + response.responseText + ")");
17
+ setMessage<?php echo $this->getAjaxFunction() ?>(reply.messages);
18
+ }
19
+ }
20
+ }
21
+ );
22
+ }
23
+
24
+ function setMessage<?php echo $this->getAjaxFunction() ?>(messages)
25
+ {
26
+ var d = document.getElementById('<?php echo $this->getAjaxFunction() ?>_status');
27
+
28
+ var html = '<ul class="messages">';
29
+
30
+ for (index = 0; index < messages.length; ++index) {
31
+ message = messages[index];
32
+ html += '<li class="' + message.status + '-msg">' + message.message;
33
+ }
34
+ html += '</ul>';
35
+
36
+ d['innerHTML'] = html;
37
+ }
38
+ //]]>
39
+ </script>
40
+
41
+ <?php echo $this->getButtonHtml() ?>
42
+ <div id="<?php echo $this->getAjaxFunction() ?>_status"></div>
app/design/adminhtml/default/default/template/campaignmonitor/createsend/apiclient.phtml ADDED
@@ -0,0 +1,282 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** @var $this Mage_Adminhtml_Block_Template */
3
+ $website = $this->getRequest()->getParam('website');
4
+ $store = $this->getRequest()->getParam('store');
5
+
6
+ list($scope, $scopeId) = Mage::getSingleton('createsend/config_scope')->_getScope($website, $store);
7
+
8
+ /** @var Campaignmonitor_Createsend_Helper_Data $helper */
9
+ $helper = Mage::helper('createsend');
10
+
11
+ $savedClientId = $helper->getApiClientId($store);
12
+ $savedListId = $helper->getListId($store);
13
+
14
+ $getClientsUrl = $this->getUrl(
15
+ 'adminhtml/createsend_api/getClients',
16
+ array(
17
+ '_query' => array(
18
+ 'scope' => $scope,
19
+ 'scopeId' => $scopeId,
20
+ )
21
+ )
22
+ );
23
+
24
+ $getListsUrl = $this->getUrl(
25
+ 'adminhtml/createsend_api/getLists',
26
+ array(
27
+ '_query' => array(
28
+ 'scope' => $scope,
29
+ 'scopeId' => $scopeId,
30
+ )
31
+ )
32
+ );
33
+
34
+ ?>
35
+ <script type="text/javascript">
36
+ //<![CDATA[
37
+ function initObservers()
38
+ {
39
+ $('createsend_general_api_api_key').observe(
40
+ 'blur',
41
+ function()
42
+ {
43
+ clearApiError();
44
+ setClients($('createsend_general_api_api_client_id'), []);
45
+
46
+ new Ajax.Request(
47
+ '<?php echo $getClientsUrl ?>',
48
+ {
49
+ method: 'get',
50
+ parameters: {
51
+ scope: '<?php echo $scope; ?>',
52
+ scopeId: '<?php echo $scopeId; ?>',
53
+ apiKey: $('createsend_general_api_api_key').value
54
+ },
55
+ onSuccess: function(response)
56
+ {
57
+ if (response.responseText) {
58
+ var reply = eval ("(" + response.responseText + ")");
59
+ if (reply.error) {
60
+ alert(reply.message);
61
+ } else {
62
+ setClients($('createsend_general_api_api_client_id'), reply.items);
63
+ }
64
+ }
65
+ }
66
+ }
67
+ );
68
+ }
69
+ );
70
+
71
+ $('createsend_general_api_api_client_id').observe(
72
+ 'change',
73
+ function()
74
+ {
75
+ clearApiError();
76
+ if (!$F('createsend_general_api_api_client_id')) {
77
+ setLists($('createsend_general_api_list_id'), []);
78
+ return;
79
+ }
80
+ new Ajax.Request(
81
+ '<?php echo $getListsUrl ?>',
82
+ {
83
+ method: 'get',
84
+ parameters: {
85
+ scope: '<?php echo $scope; ?>',
86
+ scopeId: '<?php echo $scopeId; ?>',
87
+ clientId: $F('createsend_general_api_api_client_id')
88
+ },
89
+ onSuccess: function(response)
90
+ {
91
+ if (response.responseText) {
92
+ var reply = eval ("(" + response.responseText + ")");
93
+ if (reply.error) {
94
+ alert(reply.message);
95
+ } else {
96
+ setLists($('createsend_general_api_list_id'), reply.items);
97
+ }
98
+ }
99
+ }
100
+ }
101
+ );
102
+ }
103
+ );
104
+ }
105
+
106
+ function setClients(field, data)
107
+ {
108
+ var savedClientId = '<?php echo $savedClientId; ?>';
109
+
110
+ field.options.length = 0;
111
+
112
+ data.each(
113
+ function(c) {
114
+ if (c.value == savedClientId) {
115
+ field.options.add(new Option(c.label, c.value, true, true));
116
+ $('createsend_general_api_api_client_id').triggerEvent('change');
117
+ } else {
118
+ field.options.add(new Option(c.label, c.value));
119
+ }
120
+ }
121
+ );
122
+
123
+ if (data.length == 1 && data[0].value == 'error') {
124
+ // API Error
125
+ displayApiError(data[0].message);
126
+
127
+ // Reset List ID selection
128
+ setLists($('createsend_general_api_list_id'), [{value: '', label: 'Enter your API Key'}]);
129
+ }
130
+
131
+ // data contains selection prompt
132
+ if (data.length <= 2) {
133
+ hideClientSelector();
134
+ } else {
135
+ showClientSelector();
136
+ setLists($('createsend_general_api_list_id'), []);
137
+ }
138
+
139
+ if (data.length == 2) {
140
+ // Only one client (plus selection prompt), auto-select the single client
141
+ field.selectedIndex = 1;
142
+
143
+ // Auto-load the subscription lists
144
+ setLists($('createsend_general_api_list_id'), data[1].lists);
145
+ }
146
+ }
147
+
148
+ var groupCmLists;
149
+ var groupNewList;
150
+
151
+ function setLists(field, data)
152
+ {
153
+ var savedListId = '<?php echo $savedListId; ?>';
154
+
155
+ field.options.length = 0;
156
+
157
+ if (groupCmLists === undefined && data.length > 1) {
158
+ // Reset new list group because we want it after the CM lists
159
+ if (groupNewList !== undefined) {
160
+ groupNewList.remove();
161
+ groupNewList = undefined;
162
+ }
163
+
164
+ groupCmLists = new Element('optgroup');
165
+ groupCmLists.label = "Lists in Campaign Monitor";
166
+ $('createsend_general_api_list_id').insert(groupCmLists);
167
+ }
168
+
169
+ if (groupNewList === undefined && data.length > 1) {
170
+ groupNewList = new Element('optgroup');
171
+ groupNewList.label = "New list";
172
+ $('createsend_general_api_list_id').insert(groupNewList);
173
+ }
174
+
175
+ var listCount = 0;
176
+ var newCount = 0;
177
+ data.each(
178
+ function(c) {
179
+ var selected = false;
180
+ if (c.value == savedListId) {
181
+ selected = true;
182
+ }
183
+ var option = new Option(c.label, c.value, selected, selected);
184
+ if (c.value == 'NEW_LIST') {
185
+ groupNewList.insert(option);
186
+ newCount++;
187
+ } else {
188
+ if (c.value == '' || c.value == 'error') {
189
+ // prompt only
190
+ field.options.add(option);
191
+ } else {
192
+ groupCmLists.insert(option);
193
+ listCount++;
194
+ }
195
+ }
196
+ }
197
+ );
198
+ if (groupCmLists !== undefined && listCount == 0) {
199
+ groupCmLists.remove();
200
+ groupCmLists = undefined;
201
+ }
202
+
203
+ if (groupNewList !== undefined && newCount == 0) {
204
+ groupNewList.remove();
205
+ groupNewList = undefined;
206
+ }
207
+
208
+ if (data.length == 3) {
209
+ // Only one list (+ selection prompt + create new list), auto-select the single list
210
+ field.selectedIndex = 1;
211
+ }
212
+
213
+ if (data.length == 1 && data[0].value == 'error') {
214
+ // API Error
215
+ displayApiError(data[0].message);
216
+ }
217
+
218
+ hideNewList();
219
+ }
220
+
221
+ function hideClientIfSingle()
222
+ {
223
+ if ($('createsend_general_api_api_client_id').options.length < 3) {
224
+ hideClientSelector();
225
+ }
226
+ }
227
+
228
+ function hideClientSelector()
229
+ {
230
+ $('row_createsend_general_api_api_client_id').hide();
231
+ }
232
+
233
+ function showClientSelector()
234
+ {
235
+ $('row_createsend_general_api_api_client_id').show();
236
+ }
237
+
238
+ function hideNewList()
239
+ {
240
+ $('row_createsend_general_api_new_list_name').hide();
241
+ }
242
+
243
+ function displayApiError(message)
244
+ {
245
+ $('createsend_api_key_error_message').innerHTML =
246
+ '<ul class="messages"><li class="error-msg">' + message + '</li></ul>';
247
+ }
248
+
249
+ function clearApiError()
250
+ {
251
+ $('createsend_api_key_error_message').innerHTML = '';
252
+ }
253
+
254
+ Element.prototype.triggerEvent = function(eventName)
255
+ {
256
+ if (document.createEvent) {
257
+ var evt = document.createEvent('HTMLEvents');
258
+ evt.initEvent(eventName, true, true);
259
+
260
+ return this.dispatchEvent(evt);
261
+ }
262
+
263
+ if (this.fireEvent) {
264
+ return this.fireEvent('on' + eventName);
265
+ }
266
+ }
267
+
268
+ document.observe(
269
+ 'dom:loaded',
270
+ function()
271
+ {
272
+ if ($('createsend_general_api_api_key') != undefined
273
+ && $('createsend_general_api_api_client_id') != undefined
274
+ ) {
275
+ hideClientIfSingle();
276
+ initObservers();
277
+ $('createsend_general_api_api_key').triggerEvent('blur');
278
+ }
279
+ }
280
+ );
281
+ //]]>
282
+ </script>
app/design/adminhtml/default/default/template/campaignmonitor/createsend/email/details.phtml ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+ ?>
18
+
19
+ <?php
20
+ /**
21
+ * Template for block Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Tab_Details
22
+ */
23
+ ?>
24
+ <?php
25
+ $email = $this->getEmail();
26
+ ?>
27
+ <div class="entry-edit">
28
+ <div class="entry-edit-head"><h4 class="icon-head head-customer-view"><?php echo Mage::helper('createsend')->__('Message Details') ?></h4></div>
29
+ <fieldset>
30
+ <table cellspacing="2" class="box-left">
31
+ <tr>
32
+ <td><strong><?php echo $this->__('Status:') ?></strong></td>
33
+ <td><?php if (isset($email['Status'])){ echo htmlentities($email['Status']); } ?></td>
34
+ </tr>
35
+ <tr>
36
+ <td><strong><?php echo $this->__('Sent At:') ?></strong></td>
37
+ <td><?php if (isset($email['SentAt'])){ echo htmlentities($email['SentAt']); } ?></td>
38
+ </tr>
39
+ <tr>
40
+ <td><strong><?php echo $this->__('Recipient:') ?></strong></td>
41
+ <td>
42
+ <?php
43
+ if (isset($email['Recipient'])){
44
+ echo htmlentities(iconv_mime_decode($email['Recipient']));
45
+ }
46
+ ?>
47
+ </td>
48
+ </tr>
49
+ <tr>
50
+ <td><strong><?php echo $this->__('Subject:') ?></strong></td>
51
+ <td>
52
+ <?php
53
+ if (isset($email['Message']['Subject'])){
54
+ echo htmlentities(iconv_mime_decode($email['Message']['Subject']));
55
+ }
56
+ ?>
57
+ </td>
58
+ </tr>
59
+ <tr>
60
+ <td><strong><?php echo $this->__('Can Be Resent:') ?></strong></td>
61
+ <td><?php if (isset($email['CanBeResent'])){ echo ($email['CanBeResent'] ? 'Yes' : 'No'); } ?></td>
62
+ </tr>
63
+ <tr>
64
+ <td><strong><?php echo $this->__('Total Opens:') ?></strong></td>
65
+ <td><?php if (isset($email['TotalOpens'])){ echo htmlentities($email['TotalOpens']); } ?></td>
66
+ </tr>
67
+ <tr>
68
+ <td><strong><?php echo $this->__('Total Clicks:') ?></strong></td>
69
+ <td><?php if (isset($email['TotalClicks'])){ echo htmlentities($email['TotalClicks']); } ?></td>
70
+ </tr>
71
+
72
+ </table>
73
+ <table cellspacing="2" class="box-right">
74
+ <tr>
75
+ <td><strong><?php echo $this->__('From:') ?></strong></td>
76
+ <td>
77
+ <?php
78
+ if (isset($email['Message']['From'])){
79
+ echo htmlentities(iconv_mime_decode($email['Message']['From']));
80
+ }
81
+ ?>
82
+ </td>
83
+ </tr>
84
+ <tr>
85
+ <td><strong><?php echo $this->__('To:') ?></strong></td>
86
+ <td>
87
+ <?php
88
+ if (isset($email['Message']['To'])) {
89
+ $count = 0;
90
+ foreach ($email['Message']['To'] as $emailTo) {
91
+ if ($count++ > 0) {
92
+ echo ', ';
93
+ }
94
+
95
+ echo htmlentities(iconv_mime_decode($emailTo));
96
+ }
97
+ }
98
+ ?>
99
+ </td>
100
+ </tr>
101
+ <tr>
102
+ <td><strong><?php echo $this->__('BCC:') ?></strong></td>
103
+ <td>
104
+ <?php
105
+ if (isset($email['Message']['BCC'])){
106
+ echo htmlentities(iconv_mime_decode($email['Message']['BCC']));
107
+ }
108
+ ?>
109
+ </td>
110
+ </tr>
111
+ <tr>
112
+ <td><strong><?php echo $this->__('ReplyTo:') ?></strong></td>
113
+ <td>
114
+ <?php
115
+ if (isset($email['Message']['ReplyTo'])){
116
+ echo htmlentities(iconv_mime_decode($email['Message']['ReplyTo']));
117
+ }
118
+ ?>
119
+ </td>
120
+ </tr>
121
+ </table>
122
+ </fieldset>
123
+ </div>
124
+ <?php echo $this->getChildHtml('', true, true); ?>
app/design/adminhtml/default/default/template/campaignmonitor/createsend/email/html.phtml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+ ?>
18
+
19
+ <?php
20
+ /**
21
+ * Template for block Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Tab_Html
22
+ */
23
+ ?>
24
+ <?php
25
+ /** @var Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Tab_Html $this */
26
+ /** @var array $email */
27
+ $email = $this->getEmail();
28
+ ?>
29
+ <div class="entry-edit">
30
+ <div class="entry-edit-head">
31
+ <h4 class="icon-head head-customer-view"><?php echo Mage::helper('createsend')->__('Message Body (HTML)') ?>
32
+ </h4>
33
+ </div>
34
+
35
+ <div>
36
+ <iframe sandbox="allow-same-origin" src="<?php echo $this->getEmailViewUrl($email['email_id']); ?>" width="100%" height="800">
37
+ </iframe>
38
+ </div>
39
+ </div>
40
+ <?php echo $this->getChildHtml('', true, true); ?>
app/design/adminhtml/default/default/template/campaignmonitor/createsend/email/text.phtml ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+ ?>
18
+
19
+ <?php
20
+ /**
21
+ * Template for block Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Tab_Text
22
+ */
23
+ ?>
24
+ <?php
25
+ $email = $this->getEmail();
26
+ ?>
27
+ <div class="entry-edit">
28
+ <div class="entry-edit-head">
29
+ <h4 class="icon-head head-customer-view"><?php echo Mage::helper('createsend')->__('Message Body (Text)') ?>
30
+ </h4>
31
+ </div>
32
+
33
+ <div>
34
+ <pre><?php if (isset($email['Message']['Body']['Text'])){ echo htmlentities($email['Message']['Body']['Text']); } ?></pre>
35
+ </div>
36
+ </div>
37
+ <?php echo $this->getChildHtml('', true, true); ?>
app/design/adminhtml/default/default/template/campaignmonitor/createsend/email/tracking.phtml ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+ ?>
18
+
19
+ <?php
20
+ /**
21
+ * Template for block Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Tab_Opens
22
+ * Template for block Campaignmonitor_Createsend_Block_Adminhtml_Email_View_Tab_Clicks
23
+ *
24
+ */
25
+ ?>
26
+ <?php
27
+
28
+ $email = $this->getEmail();
29
+ if (array_key_exists($this->getTrackIndex(), $email)) {
30
+ $tracks = $email[$this->getTrackIndex()];
31
+ } else {
32
+ $tracks = array();
33
+ }
34
+
35
+ $fieldNames = array(
36
+ 'EmailAddress' => 'Email Address',
37
+ 'Date' => 'Date',
38
+ 'IPAddress' => 'IP Address',
39
+ );
40
+
41
+ $clickFields = array(
42
+ 'URL' => 'URL',
43
+ );
44
+
45
+ $geoFields = array(
46
+ 'Latitude' => 'Latitude',
47
+ 'Longitude' => 'Longitude',
48
+ 'City' => 'City',
49
+ 'Region' => 'Region',
50
+ 'CountryCode' => 'Country Code',
51
+ 'CountryName' => 'Country Name',
52
+ );
53
+
54
+ $clientFields = array(
55
+ 'Name' => 'Name',
56
+ 'Version' => 'Version',
57
+ );
58
+
59
+ ?>
60
+
61
+ <div class="entry-edit-head"><h4 class="icon-head"><?php echo $this->__($this->getTrackIndex()) ?></h4></div>
62
+ <div class="grid">
63
+ <table cellspacing="0" class="data">
64
+ <thead>
65
+ <tr class="headings">
66
+ <?php
67
+
68
+ if ($this->getTrackIndex() === 'Clicks') {
69
+ $fieldNames = array_merge($fieldNames, $clickFields);
70
+ }
71
+ $allFields = array_merge($fieldNames, $geoFields);
72
+ if ($this->getTrackIndex() === 'Opens') {
73
+ $allFields = array_merge($allFields, $clientFields);
74
+ }
75
+ foreach ($allFields as $fieldName => $displayName) {
76
+ echo '<th>' . htmlentities($this->__($displayName)) . '</th>';
77
+ }
78
+ ?>
79
+ </tr>
80
+ </thead>
81
+
82
+ <tbody>
83
+ <?php foreach ($tracks as $track) { ?>
84
+ <tr>
85
+ <?php
86
+ foreach ($fieldNames as $fieldName => $displayName) {
87
+ echo '<td>';
88
+ if (isset($track[$fieldName])) {
89
+ echo htmlentities($track[$fieldName]);
90
+ } else {
91
+ echo '&nbsp;';
92
+ }
93
+ echo '</td>';
94
+ }
95
+ foreach ($geoFields as $fieldName => $displayName) {
96
+ echo '<td>';
97
+ if (isset($track['Geolocation'][$fieldName])) {
98
+ echo htmlentities($track['Geolocation'][$fieldName]);
99
+ } else {
100
+ echo '&nbsp;';
101
+ }
102
+ echo '</td>';
103
+ }
104
+ if ($this->getTrackIndex() === 'Opens') {
105
+ foreach ($clientFields as $fieldName => $displayName) {
106
+ echo '<td>';
107
+ if (isset($track['MailClient'][$fieldName])) {
108
+ echo htmlentities($track['MailClient'][$fieldName]);
109
+ } else {
110
+ echo '&nbsp;';
111
+ }
112
+ echo '</td>';
113
+ }
114
+ }
115
+ ?>
116
+ </tr>
117
+ <?php } ?>
118
+ </tbody>
119
+ </table>
120
+ </div>
121
+ <?php echo $this->getChildHtml('', true, true); ?>
app/design/adminhtml/default/default/template/campaignmonitor/createsend/switcher.phtml ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+ ?>
18
+
19
+ <?php /* @var $this Mage_Core_Block_Template */ ?>
20
+ <div class="switcher">
21
+ <label for="store_switcher"><?php echo $this->__('Scope:') ?></label>
22
+ <?php echo $this->getHintHtml() ?>
23
+ <select id="store_switcher" class="system-config-store-switcher" onchange="location.href=this.options[this.selectedIndex].getAttribute('url')">
24
+ <?php foreach ($this->getStoreSelectOptions() as $_value => $_option): ?>
25
+ <?php if (isset($_option['is_group'])): ?>
26
+ <?php if ($_option['is_close']): ?>
27
+ </optgroup>
28
+ <?php else: ?>
29
+ <optgroup label="<?php echo $this->escapeHtml($_option['label']) ?>" style="<?php echo $_option['style'] ?>">
30
+ <?php endif; ?>
31
+ <?php continue ?>
32
+ <?php endif; ?>
33
+ <option value="<?php echo $this->escapeHtml($_value) ?>" url="<?php echo $_option['url'] ?>" <?php echo $_option['selected'] ? 'selected="selected"' : '' ?> style="<?php echo $_option['style'] ?>">
34
+ <?php echo $this->escapeHtml($_option['label']) ?>
35
+ </option>
36
+ <?php endforeach ?>
37
+ </select>
38
+ </div>
app/design/adminhtml/default/default/template/campaignmonitor/createsend/system/config/form/field/array_dropdown.phtml ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+ ?>
18
+
19
+ <?php
20
+ $_htmlId = $this->getHtmlId() ? $this->getHtmlId() : '_' . uniqid();
21
+
22
+ $_colspan = 2;
23
+ if (!$this->_addAfter) {
24
+ $_colspan -= 1;
25
+ }
26
+ $_colspan = $_colspan > 1 ? 'colspan="' . $_colspan . '"' : '';
27
+ ?>
28
+
29
+ <div class="grid" id="grid<?php echo $_htmlId; ?>">
30
+ <table cellpadding="0" cellspacing="0" class="border">
31
+ <tbody>
32
+
33
+ <tr class="headings" id="headings<?php echo $_htmlId; ?>">
34
+ <?php foreach ($this->_columns as $columnName => $column): ?>
35
+ <th><?php echo $column['label']; ?></th>
36
+ <?php endforeach; ?>
37
+ <th <?php echo $_colspan; ?>></th>
38
+ </tr>
39
+
40
+ <tr id="addRow<?php echo $_htmlId; ?>">
41
+ <td colspan="<?php echo count($this->_columns); ?>"></td>
42
+ <td <?php echo $_colspan; ?>>
43
+ <button style="" onclick="" class="scalable add" type="button" id="addToEndBtn<?php echo $_htmlId; ?>">
44
+ <span><span><span><?php echo $this->_addButtonLabel; ?></span></span></span>
45
+ </button>
46
+ </td>
47
+ </tr>
48
+
49
+ </tbody>
50
+ </table>
51
+ <input type="hidden" name="<?php echo $this->getElement()->getName(); ?>[__empty]" value="" />
52
+ </div>
53
+ <div id="empty<?php echo $_htmlId; ?>">
54
+ <button style="" onclick="" class="scalable add" type="button" id="emptyAddBtn<?php echo $_htmlId; ?>">
55
+ <span><span><span><?php echo $this->_addButtonLabel; ?></span></span></span>
56
+ </button>
57
+ </div>
58
+
59
+ <script type="text/javascript">
60
+ // <!--
61
+ // create row creator
62
+ var arrayRow<?php echo $_htmlId; ?> = {
63
+ // define row prototypeJS template
64
+ template : new Template(
65
+ '<tr id="<?php echo $_htmlId; ?>-#{_id}">'
66
+ <?php foreach ($this->_columns as $columnName => $column):?>
67
+ +'<td class="#{_id}-<?php echo $columnName?>">'
68
+ +'<?php echo $this->_renderCellTemplate($columnName); ?>'
69
+ +'</td>'
70
+ <?php endforeach; ?>
71
+ <?php if ($this->_addAfter): ?>
72
+ +'<td><button onclick="" class="scalable add" type="button" id="addAfterBtn#{_id}"><span><span><span><?php echo Mage::helper('adminhtml')->__('Add after') ?></span></span></span></button></td>'
73
+ <?php endif; ?>
74
+ +'<td><button onclick="arrayRow<?php echo $_htmlId ?>.del(\'#{_id}\')" class="scalable delete" type="button"><span><span><span><?php echo Mage::helper('adminhtml')->__('Delete') ?></span></span></span></button></td>'
75
+ +'</tr>'
76
+ ),
77
+
78
+ rowsCount : 0,
79
+
80
+ add : function(templateData, insertAfterId)
81
+ {
82
+ var dataProvided = true;
83
+
84
+ // generate default template data
85
+ if ('' == templateData) {
86
+ dataProvided = false;
87
+
88
+ var d = new Date();
89
+ var templateData = {
90
+ <?php foreach ($this->_columns as $columnName => $column): ?>
91
+ <?php echo $columnName ?> : '',
92
+ <?php endforeach; ?>
93
+ _id : '_' + d.getTime() + '_' + d.getMilliseconds()
94
+ };
95
+ }
96
+
97
+ if ('' == insertAfterId) {
98
+ // insert before last row
99
+ new Insertion.Before(
100
+ $('addRow<?php echo $_htmlId ?>'),
101
+ this.template.evaluate(templateData)
102
+ );
103
+ } else {
104
+ // insert after specified row
105
+ new Insertion.After(
106
+ $(insertAfterId),
107
+ this.template.evaluate(templateData)
108
+ );
109
+ }
110
+
111
+ <?php // Following only works with a single column ?>
112
+ if (!dataProvided) {
113
+ // Get array of values which have already been selected
114
+ var values = [];
115
+ $('grid<?php echo $_htmlId; ?>').select('select').each(function(e) {
116
+ values.push($F(e));
117
+ });
118
+
119
+ // Remove any values which have already been selected from the dropdown
120
+ var options = $$('td.' + templateData._id + '-' + 'magento' + ' option')
121
+ for (var i = 0; i < options.length; ++i) {
122
+ var option = options[i]
123
+ var value = option.getAttribute('value');
124
+
125
+ for (var j = 0; j < values.length; ++j) {
126
+ if (value == values[j]) {
127
+ option.parentNode.removeChild(option);
128
+ break;
129
+ }
130
+ }
131
+ }
132
+ }
133
+
134
+ // set the selected drop-down list item
135
+ <?php foreach ($this->_columns as $columnName => $column): ?>
136
+ var options = $$('td.' + templateData._id + '-' + '<?php echo $columnName; ?>' + ' option')
137
+ for (var index = 0; index < options.length; ++index) {
138
+ var option = options[index]
139
+ if (option.getAttribute('value') == templateData.<?php echo $columnName; ?>) {
140
+ option.selected = true
141
+ }
142
+ }
143
+ <?php endforeach; ?>
144
+
145
+ <?php if ($this->_addAfter): ?>
146
+ Event.observe('addAfterBtn' + templateData._id, 'click', this.add.bind(this, '', templateData._id));
147
+ <?php endif; ?>
148
+
149
+ this.rowsCount += 1;
150
+ },
151
+
152
+ del : function(rowId)
153
+ {
154
+ $('<?php echo $_htmlId ?>' + '-' + rowId).remove();
155
+ this.rowsCount -= 1;
156
+ if (0 == this.rowsCount) {
157
+ this.showButtonOnly();
158
+ }
159
+ },
160
+
161
+ showButtonOnly : function()
162
+ {
163
+ $('grid<?php echo $_htmlId ?>').hide();
164
+ $('empty<?php echo $_htmlId ?>').show();
165
+ }
166
+ }
167
+
168
+ // bind add action to "Add" button in last row
169
+ Event.observe('addToEndBtn<?php echo $_htmlId; ?>', 'click', arrayRow<?php echo $_htmlId; ?>.add.bind(arrayRow<?php echo $_htmlId; ?>, '', ''));
170
+
171
+ // add existing rows
172
+ <?php
173
+ $_addAfterId = "headings{$_htmlId}";
174
+ foreach ($this->getArrayRows() as $_rowId => $_row) {
175
+ echo "arrayRow{$_htmlId}.add(" . $_row->toJson() . ", '{$_addAfterId}');\n";
176
+ $_addAfterId = "{$_htmlId}-{$_rowId}";
177
+ }
178
+ ?>
179
+
180
+ // initialize standalone button
181
+ $('empty<?php echo $_htmlId; ?>').hide();
182
+ Event.observe('emptyAddBtn<?php echo $_htmlId ?>', 'click', function () {
183
+ $('grid<?php echo $_htmlId; ?>').show();
184
+ $('empty<?php echo $_htmlId; ?>').hide();
185
+ arrayRow<?php echo $_htmlId; ?>.add('', '');
186
+ });
187
+
188
+ // if no rows, hide grid and show button only
189
+ <?php if (!$this->getArrayRows()):?>
190
+ arrayRow<?php echo $_htmlId; ?>.showButtonOnly();
191
+ <?php endif;?>
192
+
193
+ // toggle the grid, if element is disabled (depending on scope)
194
+ <?php if ($this->getElement()->getDisabled()): ?>
195
+ toggleValueElements({checked:true}, $('grid<?php echo $_htmlId; ?>').parentNode);
196
+ <?php endif;?>
197
+ // -->
198
+ </script>
app/etc/modules/Campaignmonitor_Createsend.xml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * Campaign Monitor Magento Extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you are unable to obtain it through the world-wide-web, please
12
+ * send an email to license@magento.com and you will be sent a copy.
13
+ *
14
+ * @package Campaignmonitor_Createsend
15
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
16
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
+ */
18
+ -->
19
+ <config>
20
+ <modules>
21
+ <Campaignmonitor_Createsend>
22
+ <active>true</active>
23
+ <codePool>community</codePool>
24
+ </Campaignmonitor_Createsend>
25
+ </modules>
26
+ </config>
package.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Campaignmonitor_Createsend</name>
4
+ <version>1.0.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">Open Software License (OSL 3.0)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Integrates subscriber list with Campaign Monitor.</summary>
10
+ <description>Integrates subscriber list with Campaign Monitor.</description>
11
+ <notes>Initial release.</notes>
12
+ <authors><author><name>Fontis</name><user>fontis</user><email>connect@fontis.com.au</email></author></authors>
13
+ <date>2016-01-14</date>
14
+ <time>01:00:05</time>
15
+ <contents><target name="magecommunity"><dir name="Campaignmonitor"><dir name="Createsend"><dir name="Block"><dir name="Adminhtml"><dir name="Customer"><dir name="Edit"><file name="Grid.php" hash="48e28e2303623522c1a29365b94744df"/></dir></dir><dir name="Email"><file name="Grid.php" hash="1693e7a7d2dd6eaf024ed6dda06dafd0"/><dir name="View"><file name="Abstract.php" hash="480c6ac7134e47bf43c4fd6a3213b3c7"/><file name="Form.php" hash="5661cfe457e8526b2c47313fc264cd55"/><dir name="Tab"><file name="Clicks.php" hash="42f4a1ba85451b34617eeecd4a4a34d3"/><file name="Details.php" hash="2b8a673ccbbf0172c6d750259724c910"/><file name="Html.php" hash="ab99f5396dd23e2c874bdcbea2c9f064"/><file name="Opens.php" hash="5c7c80be07535869099b9adb35d4b5a1"/><file name="Text.php" hash="8448dd4755d6b0fac8136188a4259e95"/></dir><file name="Tabs.php" hash="ab071552f0a18c06f6c6b5deba46ad39"/></dir><file name="View.php" hash="da2d91894a55ff5dadcc3052f76ea4a2"/></dir><file name="Email.php" hash="d515199f4b0a380bbdb18ed4646406ab"/><file name="Switcher.php" hash="a652b662a97986b2a6e9d482c4dd91de"/></dir><dir name="AjaxButton"><file name="Abstract.php" hash="c1fc0f3a54612e2a1a29b2334ce7596e"/></dir><file name="CreateExampleSegments.php" hash="275651dd04e7d33aa59979c420c2970b"/><file name="Linkedattributes.php" hash="1d5418092958834750addbdece0b0d9a"/><file name="OauthPermissionRequest.php" hash="500f081e10b335c5f8a48dc4e66c6cf5"/><file name="OauthRedirectUrl.php" hash="c620189b986869119ef663c1219d3638"/><file name="TestApi.php" hash="18becb7036d41b984e1ef3b8610e9fbe"/><file name="Wishlistattributes.php" hash="215c9f748b4dc961bb55c855a5cd05a0"/></dir><dir name="Helper"><file name="Api.php" hash="bc3ca8d7b919ed6c5e3726cc8ae77f6d"/><file name="Config.php" hash="a3fb0f14af014d75e408fc7b8d082b20"/><file name="Data.php" hash="19c555bc15be41c0e27ebded59176acf"/></dir><dir name="Model"><dir name="Api"><file name="Observer.php" hash="7ddceb0ca6cd952716cb9551ab220fd7"/></dir><file name="Api.php" hash="dada39c6c5c6abbc499a626aaa731689"/><dir name="Config"><file name="Api.php" hash="16c3d74c28fa1e1fd7ccd339a01790b2"/><dir name="Attributes"><file name="Abstract.php" hash="a9253efd2e6e57d8a00ce6daf04de7e0"/></dir><file name="AuthenticationMethod.php" hash="90307b668c7ba94867823aba983b2fdc"/><dir name="Backend"><file name="Apikey.php" hash="82d8bafbdcbbb74078bc8427e7569290"/><file name="Listid.php" hash="ebebd820797f3aa4b5bf69e75771a513"/></dir><file name="ClientSelection.php" hash="0adc61c13342da28e8a1815f4f65ae0d"/><file name="ConflictResolutionMethod.php" hash="48938666ddfd96e6b3b5c13c01a4c36c"/><file name="CustomerAttributes.php" hash="5cf999910a27b44d4c7747e2e10b4179"/><file name="DefaultCustomFields.php" hash="fbca6fc17b394e5f38511760a10a9aa1"/><file name="ExampleSegments.php" hash="4ab29a0f8a62c18b3d846ae4901ae2fb"/><file name="ListFlag.php" hash="b259912cdf6a68883a58534079f4db71"/><file name="ListSelection.php" hash="763601cc87f4948c0f3ee93eea3093eb"/><file name="ProductAttributes.php" hash="1a3c82d010fa5aec93d56b1bbabf6568"/><file name="Scope.php" hash="f6c06f4344c1db712925314a7dce7c3d"/><file name="SubscriptionSources.php" hash="e9291723ce6420cb9ebfeff4c994372a"/></dir><file name="Cron.php" hash="4eb2cf346c0705237a402d24053c8ea2"/><dir name="Customer"><file name="Observer.php" hash="4b5bf5a8caa90538ea159bb0314edd38"/></dir><dir name="Email"><file name="Cron.php" hash="00b7d38721fde5732a92d9d733f32439"/><file name="Template.php" hash="16a81f1059dff3b9e7162ff68991360c"/></dir><file name="Email.php" hash="b587fc5062c33e2f2b97111e11095b2c"/><dir name="List"><file name="Cron.php" hash="010417a44ddaaf4d5cf254dedb5f188e"/><dir name="Initial"><file name="Cron.php" hash="1496b75f327a9dc7cee888dd602f496b"/></dir></dir><dir name="Newsletter"><file name="Observer.php" hash="0c194bd321eb4ce58d0859d505254a0d"/></dir><file name="Newsletter.php" hash="4bcb7a0970b9e55c905e753990263f56"/><dir name="Product"><file name="Observer.php" hash="70834ac17bd0ff931b9b9334d79980bb"/></dir><dir name="Resource"><dir name="Email"><file name="Collection.php" hash="85165381ae7416ecdb24cd11c88fd591"/></dir><file name="Email.php" hash="42f44bf5cbbbdb5dc6e7f4944dec9cf8"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><dir name="Createsend"><file name="ApiController.php" hash="3dfa90cd58af3ce08f77dfafc4485885"/><file name="EmailController.php" hash="14bf61eb251af1444335723475d67f38"/><file name="SegmentController.php" hash="d3aaf5498b92589f2a6ca816931a8978"/></dir></dir><file name="OauthController.php" hash="4f20e1a620363465aa33cda712282646"/><file name="UnsubscribeController.php" hash="062e972b753446efc1d226f83952aeda"/><file name="WebhooksController.php" hash="d51f3f5614001ba46b300b7269a86e42"/></dir><dir name="etc"><file name="adminhtml.xml" hash="4b9b24169fc9612fcf941022d7918071"/><file name="config.xml" hash="f6f92e00f212c58bd50e54bf0ee31f73"/><file name="system.xml" hash="aadf9a7a0bb9d018d8e90f51442c8935"/></dir><dir name="sql"><dir name="campaignmonitor_createsend_setup"><file name="install-1.0.0.php" hash="9ea2ce61dad34c51fbc60b9f9af24606"/></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Campaignmonitor_Createsend.xml" hash="e2b42c271a897551d0750506555af6d4"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="campaignmonitor"><dir name="createsend"><file name="ajax.phtml" hash="74eb59c4ad5b2f686536e33c929419ca"/><file name="apiclient.phtml" hash="753efb7fad644b1d4122689cd48123d6"/><dir name="email"><file name="details.phtml" hash="7a280f81e7fc737ab3a44de8fb3bdb01"/><file name="html.phtml" hash="e5c2f2d96fde96eb62887bb0cdb511f5"/><file name="text.phtml" hash="666a3bece1273f29d42044ee3054b08e"/><file name="tracking.phtml" hash="ca3cee04bf39c89001cb654cbc0acf1c"/></dir><file name="switcher.phtml" hash="f0ebd5e04640cba50b022ad77159ae2b"/><dir name="system"><dir name="config"><dir name="form"><dir name="field"><file name="array_dropdown.phtml" hash="9e47b2ee3ce33ca21cc95d2e360ecc77"/></dir></dir></dir></dir></dir></dir></dir><dir name="layout"><dir name="campaignmonitor"><file name="createsend.xml" hash="5e2dbc978680b1631759eb5664303d1b"/></dir></dir></dir></dir></dir></target><target name="mage"><dir name="shell"><file name="campaignmonitor_email.php" hash="8a1b04a4970e178c04351247de4ec59a"/><file name="campaignmonitor_list.php" hash="a6ef94412cf5f57fd31b4db409ca028d"/><file name="campaignmonitor_list_initial.php" hash="5dc090760799d568ab3906c84b7cbc6d"/></dir></target></contents>
16
+ <compatible/>
17
+ <dependencies><required><php><min>5.3.0</min><max>8.0.0</max></php></required></dependencies>
18
+ </package>
shell/campaignmonitor_email.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ require_once 'abstract.php';
19
+
20
+ /**
21
+ * Download email data from Campaign Monitor for viewing in the Magento admin panel
22
+ * and purge old email data from Magento database.
23
+ *
24
+ * To use this script, go to:
25
+ *
26
+ * ``System -> Configuration -> Campaign Monitor -> General -> Advanced``
27
+ *
28
+ * and set ``Use Magento cron`` to ``No``.
29
+ *
30
+ * Then add an entry in your Unix crontab to run this script every hour, or use an interval of your choice.
31
+ *
32
+ */
33
+ class Mage_Shell_Campaignmonitor_Email extends Mage_Shell_Abstract
34
+ {
35
+ /**
36
+ * Run script
37
+ *
38
+ */
39
+ public function run()
40
+ {
41
+ /** @var array $tasks */
42
+ $tasks = array();
43
+ $tasks[] = Mage::getModel('createsend/email_cron');
44
+
45
+ /** @var Campaignmonitor_Createsend_Model_Cron $task */
46
+ foreach ($tasks as $task) {
47
+ $task->runJob();
48
+ }
49
+ }
50
+ }
51
+
52
+ $shell = new Mage_Shell_Campaignmonitor_Email();
53
+ $shell->run();
shell/campaignmonitor_list.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ require_once 'abstract.php';
19
+
20
+ /**
21
+ * Synchronise list subscribers between Campaign Monitor and Magento.
22
+ *
23
+ * To use this script, go to:
24
+ *
25
+ * ``System -> Configuration -> Campaign Monitor -> General -> Advanced``
26
+ *
27
+ * and set ``Use Magento cron`` to ``No``.
28
+ *
29
+ * Then add an entry in your Unix crontab to run this script at least once a day.
30
+ *
31
+ */
32
+ class Mage_Shell_Campaignmonitor_List extends Mage_Shell_Abstract
33
+ {
34
+ /**
35
+ * Run script
36
+ *
37
+ */
38
+ public function run()
39
+ {
40
+ /** @var array $tasks */
41
+ $tasks = array();
42
+ $tasks[] = Mage::getModel('createsend/list_cron');
43
+
44
+ /** @var Campaignmonitor_Createsend_Model_Cron $task */
45
+ foreach ($tasks as $task) {
46
+ $task->runJob();
47
+ }
48
+ }
49
+ }
50
+
51
+ $shell = new Mage_Shell_Campaignmonitor_List();
52
+ $shell->run();
shell/campaignmonitor_list_initial.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Campaign Monitor Magento Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is available through the world-wide-web at this URL:
9
+ * http://opensource.org/licenses/osl-3.0.php
10
+ * If you are unable to obtain it through the world-wide-web, please
11
+ * send an email to license@magento.com and you will be sent a copy.
12
+ *
13
+ * @package Campaignmonitor_Createsend
14
+ * @copyright Copyright (c) 2015 Campaign Monitor (https://www.campaignmonitor.com/)
15
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
16
+ */
17
+
18
+ require_once 'abstract.php';
19
+
20
+ /**
21
+ * Perform Initial Sync from Magento to Campaign Monitor.
22
+ *
23
+ * To use this script, go to:
24
+ *
25
+ * ``System -> Configuration -> Campaign Monitor -> General -> Advanced``
26
+ *
27
+ * and set ``Use Magento cron`` to ``No``.
28
+ *
29
+ * Then add an entry in your Unix crontab to run this script every five minutes.
30
+ *
31
+ */
32
+ class Mage_Shell_Campaignmonitor_List_Initial extends Mage_Shell_Abstract
33
+ {
34
+ /**
35
+ * Run script
36
+ *
37
+ */
38
+ public function run()
39
+ {
40
+ /** @var array $tasks */
41
+ $tasks = array();
42
+ $tasks[] = Mage::getModel('createsend/list_initial_cron');
43
+
44
+ /** @var Campaignmonitor_Createsend_Model_Cron $task */
45
+ foreach ($tasks as $task) {
46
+ $task->runJob();
47
+ }
48
+ }
49
+ }
50
+
51
+ $shell = new Mage_Shell_Campaignmonitor_List_Initial();
52
+ $shell->run();