sendmachine - Version 1.0.0

Version Notes

Fist stable release.

Download this release

Release Info

Developer Sendmachine
Extension sendmachine
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

Files changed (45) hide show
  1. app/code/community/Sendmachine/Sendmachine/Block/AppContainer/Grid.php +68 -0
  2. app/code/community/Sendmachine/Sendmachine/Block/AppContainer/Main.php +34 -0
  3. app/code/community/Sendmachine/Sendmachine/Block/AppContainer/Tab/Email.php +100 -0
  4. app/code/community/Sendmachine/Sendmachine/Block/AppContainer/Tab/General.php +52 -0
  5. app/code/community/Sendmachine/Sendmachine/Block/AppContainer/Tab/Lists.php +135 -0
  6. app/code/community/Sendmachine/Sendmachine/Block/AppContainer/Tabs.php +38 -0
  7. app/code/community/Sendmachine/Sendmachine/Block/PopupBlock.php +66 -0
  8. app/code/community/Sendmachine/Sendmachine/Helper/Data.php +130 -0
  9. app/code/community/Sendmachine/Sendmachine/Model/...Observer.php +20 -0
  10. app/code/community/Sendmachine/Sendmachine/Model/Cronjobs.php +56 -0
  11. app/code/community/Sendmachine/Sendmachine/Model/Email/Queue.php +99 -0
  12. app/code/community/Sendmachine/Sendmachine/Model/Email/Template.php +120 -0
  13. app/code/community/Sendmachine/Sendmachine/Model/Mysql4/Sendmachine.php +10 -0
  14. app/code/community/Sendmachine/Sendmachine/Model/Mysql4/Sendmachine/Collection.php +10 -0
  15. app/code/community/Sendmachine/Sendmachine/Model/Observer.php +28 -0
  16. app/code/community/Sendmachine/Sendmachine/Model/Sendmachine.php +337 -0
  17. app/code/community/Sendmachine/Sendmachine/Model/Source/Contactlist.php +33 -0
  18. app/code/community/Sendmachine/Sendmachine/Model/Source/ImportExportLimit.php +18 -0
  19. app/code/community/Sendmachine/Sendmachine/Model/Source/Smtp.php +23 -0
  20. app/code/community/Sendmachine/Sendmachine/Model/Source/TransactionalCampAreas.php +20 -0
  21. app/code/community/Sendmachine/Sendmachine/controllers/SendmachineController.php +254 -0
  22. app/code/community/Sendmachine/Sendmachine/controllers/SubscribeController.php +44 -0
  23. app/code/community/Sendmachine/Sendmachine/etc/adminhtml.xml +14 -0
  24. app/code/community/Sendmachine/Sendmachine/etc/config.xml +133 -0
  25. app/code/community/Sendmachine/Sendmachine/sql/sendmachine_setup/mysql4-install-1.0.0.php +22 -0
  26. app/design/frontend/base/default/layout/sendmachine.xml +18 -0
  27. app/design/frontend/base/default/template/sendmachine/popup.phtml +39 -0
  28. app/etc/modules/Sendmachine_Sendmachine.xml +9 -0
  29. app/locale/en_US/Sendmachine_Sendmachine.csv +83 -0
  30. js/sendmachine/admin.js +89 -0
  31. lib/SendmachineApi/README.md +5 -0
  32. lib/SendmachineApi/SendmachineApiClient.php +206 -0
  33. lib/SendmachineApi/composer.json +11 -0
  34. lib/SendmachineApi/library/Account.php +90 -0
  35. lib/SendmachineApi/library/Campaigns.php +222 -0
  36. lib/SendmachineApi/library/Lists.php +276 -0
  37. lib/SendmachineApi/library/Sender.php +68 -0
  38. lib/SendmachineApi/library/Templates.php +91 -0
  39. package.xml +33 -0
  40. skin/adminhtml/default/default/sendmachine/logo.png +0 -0
  41. skin/adminhtml/default/default/sendmachine/logo2.png +0 -0
  42. skin/adminhtml/default/default/sendmachine/logo3.png +0 -0
  43. skin/frontend/base/default/sendmachine/frontend.css +76 -0
  44. skin/frontend/base/default/sendmachine/frontend.js +82 -0
  45. skin/frontend/base/default/sendmachine/loading.gif +0 -0
app/code/community/Sendmachine/Sendmachine/Block/AppContainer/Grid.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Block_AppContainer_Grid extends Mage_Adminhtml_Block_Widget_Grid {
4
+
5
+ public function __construct() {
6
+
7
+ parent::__construct();
8
+ $this->setId('sm_import_export_log');
9
+ $this->setDefaultSort('id');
10
+ $this->setDefaultDir('desc');
11
+ }
12
+
13
+ protected function _getCollectionClass() {
14
+
15
+ return 'sendmachine/sendmachine_collection';
16
+ }
17
+
18
+ protected function _prepareCollection() {
19
+
20
+ $collection = Mage::getResourceModel($this->_getCollectionClass());
21
+ $this->setCollection($collection);
22
+
23
+ return parent::_prepareCollection();
24
+ }
25
+
26
+ protected function _prepareColumns() {
27
+
28
+ $helper = Mage::helper('sendmachine');
29
+
30
+ $this->addColumn('id', array(
31
+ 'header' => $helper->__('Index'),
32
+ 'index' => 'id'
33
+ ));
34
+
35
+ $this->addColumn('action', array(
36
+ 'header' => $helper->__('Action'),
37
+ 'index' => 'action'
38
+ ));
39
+
40
+ $this->addColumn('state', array(
41
+ 'header' => $helper->__('State'),
42
+ 'index' => 'state'
43
+ ));
44
+
45
+ $this->addColumn('number', array(
46
+ 'header' => $helper->__('Customer number'),
47
+ 'index' => 'number'
48
+ ));
49
+
50
+ $this->addColumn('list_name', array(
51
+ 'header' => $helper->__('Contact list'),
52
+ 'index' => 'list_name'
53
+ ));
54
+
55
+ $this->addColumn('sdate', array(
56
+ 'header' => $helper->__('Start date'),
57
+ 'index' => 'sdate'
58
+ ));
59
+
60
+ $this->addColumn('edate', array(
61
+ 'header' => $helper->__('End date'),
62
+ 'index' => 'edate'
63
+ ));
64
+
65
+ return parent::_prepareColumns();
66
+ }
67
+
68
+ }
app/code/community/Sendmachine/Sendmachine/Block/AppContainer/Main.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Block_AppContainer_Main extends Mage_Adminhtml_Block_Widget_Form_Container {
4
+
5
+ private $_tab;
6
+
7
+ public function __construct($data = NULL) {
8
+
9
+ $this->_blockGroup = NULL;
10
+ parent::__construct();
11
+
12
+ $this->_removeButton('delete');
13
+ $this->_removeButton('back');
14
+
15
+ $this->_tab = isset($data['tab']) ? $data['tab'] : NULL;
16
+ }
17
+
18
+ public function getHeaderText() {
19
+
20
+ $apiConnected = Mage::registry('sm_model')->get('api_connected');
21
+ $status = $apiConnected ? Mage::helper('sendmachine')->__('connected') : Mage::helper('sendmachine')->__('disconnected');
22
+ $style = "display:inline-block;color:white;padding:2px 5px;margin-left:-20px;background-color:#eb5e00;border-radius:3px;";
23
+
24
+ return '<span style="' . $style . '" >' . Mage::helper('sendmachine')->__('Api status: ') . $status . '</span>';
25
+ }
26
+
27
+ protected function _prepareLayout() {
28
+
29
+ $this->setChild('form', $this->getLayout()->createBlock('sendmachine/appContainer_tab_' . $this->_tab));
30
+
31
+ return parent::_prepareLayout();
32
+ }
33
+
34
+ }
app/code/community/Sendmachine/Sendmachine/Block/AppContainer/Tab/Email.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Block_AppContainer_Tab_Email extends Mage_Adminhtml_Block_Widget_Form {
4
+
5
+ protected function _prepareForm() {
6
+
7
+ $sm = Mage::registry('sm_model');
8
+ $form = new Varien_Data_Form(array(
9
+ 'id' => 'edit_form',
10
+ 'action' => $this->getUrl('*/*/save'),
11
+ 'method' => 'post'
12
+ )
13
+ );
14
+
15
+ $form->setUseContainer(true);
16
+
17
+
18
+ $fieldset = $form->addFieldset('email_fieldset', ['legend' => Mage::helper('sendmachine')->__('Email Settings')]);
19
+ $testfieldset = $form->addFieldset('emailtest_fieldset', ['legend' => Mage::helper('sendmachine')->__('Test Configuration')]);
20
+
21
+ $fieldset->addField('tab_email', 'hidden', [
22
+ 'name' => 'tab',
23
+ 'value' => 'email'
24
+ ]);
25
+
26
+ $fieldset->addField('email_enabled', 'select', [
27
+ 'name' => 'email_enabled',
28
+ 'label' => Mage::helper('sendmachine')->__('Enable email sending'),
29
+ 'title' => Mage::helper('sendmachine')->__('Enable email sending'),
30
+ 'values' => Mage::getModel('adminhtml/system_config_source_yesno')->toOptionArray()
31
+ ]);
32
+
33
+ $fieldset->addField('smtp_encryption', 'select', [
34
+ 'name' => 'smtp_encryption',
35
+ 'label' => Mage::helper('sendmachine')->__('SMTP Encryption'),
36
+ 'title' => Mage::helper('sendmachine')->__('SMTP Encryption'),
37
+ 'values' => Mage::getModel('sendmachine/source_smtp')->toOptionArray()
38
+ ]);
39
+
40
+ $fieldset->addField('from_email', 'text', [
41
+ 'name' => 'from_email',
42
+ 'label' => Mage::helper('sendmachine')->__('From Email'),
43
+ 'title' => Mage::helper('sendmachine')->__('From Email'),
44
+ 'after_element_html' => '<small>' . Mage::helper('sendmachine')->__("Note! If you set a 'From email' here, all other 'from emails' will be overriden") . '<small>'
45
+ ]
46
+ );
47
+
48
+ $fieldset->addField('from_name', 'text', [
49
+ 'name' => 'from_name',
50
+ 'label' => Mage::helper('sendmachine')->__('From Name'),
51
+ 'title' => Mage::helper('sendmachine')->__('From Name'),
52
+ 'after_element_html' => '<small>' . Mage::helper('sendmachine')->__("Note! If you set a 'From name' here, all other 'from names' will be overriden") . '<small>'
53
+ ]
54
+ );
55
+
56
+ $fieldset->addField('transactional_campaigns_enabled', 'select', [
57
+ 'name' => 'transactional_campaigns_enabled',
58
+ 'label' => Mage::helper('sendmachine')->__('Use transactional emails'),
59
+ 'title' => Mage::helper('sendmachine')->__('Use transactional emails'),
60
+ 'values' => Mage::getModel('adminhtml/system_config_source_yesno')->toOptionArray()
61
+ ]);
62
+
63
+ $fieldset->addField('transactional_campaign_prefix', 'text', [
64
+ 'name' => 'transactional_campaign_prefix',
65
+ 'label' => Mage::helper('sendmachine')->__('Transactional campaigns prefix'),
66
+ 'title' => Mage::helper('sendmachine')->__('Transactional campaigns prefix'),
67
+ 'after_element_html' => '<small>Campaign\'s prefix<small>'
68
+ ]
69
+ );
70
+
71
+ $fieldset->addField('transactional_campaign_areas', 'multiselect', [
72
+ 'name' => 'transactional_campaign_areas',
73
+ 'label' => Mage::helper('sendmachine')->__('Transactional campaigns areas'),
74
+ 'title' => Mage::helper('sendmachine')->__('Transactional campaigns areas'),
75
+ 'values' => Mage::getModel('sendmachine/source_transactionalCampAreas')->toOptionArray(),
76
+ 'after_element_html' => '<small>' . Mage::helper('sendmachine')->__("Note! Hold 'ctrl' and click the area you want to select/deselect for multiple selection") . '</small>'
77
+ ]);
78
+
79
+ $fieldset->addField('transactional_campaign_suffix', 'text', [
80
+ 'name' => 'transactional_campaign_suffix',
81
+ 'label' => Mage::helper('sendmachine')->__('Transactional campaigns suffix'),
82
+ 'title' => Mage::helper('sendmachine')->__('Transactional campaigns suffix'),
83
+ 'after_element_html' => '<small>Campaign\'s suffix<small>'
84
+ ]
85
+ );
86
+
87
+ $testfieldset->addField('smMageTestEmail', 'text', [
88
+ 'label' => Mage::helper('sendmachine')->__('Send a test email'),
89
+ 'title' => Mage::helper('sendmachine')->__('Send a test email'),
90
+ 'style' => 'width:240px',
91
+ 'after_element_html' => '<button onClick=\'smSendTestEmail("' . Mage::helper('adminhtml')->getUrl('adminhtml/sendmachine/sendtestmail') . '");return false;\' >' . Mage::helper('sendmachine')->__('Send') . '</button><small>' . Mage::helper('sendmachine')->__('Send a test email to make sure that settings were applied correctly') . '<small>',
92
+ ]
93
+ );
94
+
95
+ $form->addValues($sm->get());
96
+ $this->setForm($form);
97
+ return parent::_prepareForm();
98
+ }
99
+
100
+ }
app/code/community/Sendmachine/Sendmachine/Block/AppContainer/Tab/General.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Block_AppContainer_Tab_General extends Mage_Adminhtml_Block_Widget_Form {
4
+
5
+ protected function _prepareForm() {
6
+
7
+ $sm = Mage::registry('sm_model');
8
+ $form = new Varien_Data_Form(array(
9
+ 'id' => 'edit_form',
10
+ 'action' => $this->getUrl('*/*/save'),
11
+ 'method' => 'post'
12
+ )
13
+ );
14
+
15
+ $form->setUseContainer(true);
16
+
17
+ $fieldset = $form->addFieldset('general_fieldset', ['legend' => Mage::helper('sendmachine')->__('General Settings')]);
18
+
19
+ $fieldset->addField('tab_general', 'hidden', [
20
+ 'name' => 'tab',
21
+ 'value' => 'index'
22
+ ]);
23
+
24
+ $fieldset->addField('plugin_enabled', 'select', [
25
+ 'name' => 'plugin_enabled',
26
+ 'label' => Mage::helper('sendmachine')->__('Plugin enabled'),
27
+ 'title' => Mage::helper('sendmachine')->__('Plugin enabled'),
28
+ 'values' => Mage::getModel('adminhtml/system_config_source_yesno')->toOptionArray()
29
+ ]);
30
+
31
+ $fieldset->addField('api_username', 'text', [
32
+ 'name' => 'api_username',
33
+ 'label' => Mage::helper('sendmachine')->__('Api username'),
34
+ 'title' => Mage::helper('sendmachine')->__('Api username'),
35
+ 'after_element_html' => '<button id="button_api_username" onClick="smToggleCredentialsVisibility(\'api_username\');return false;" >' . Mage::helper('sendmachine')->__('Show') . '</button>'
36
+ ]
37
+ );
38
+
39
+ $fieldset->addField('api_password', 'text', [
40
+ 'name' => 'api_password',
41
+ 'label' => Mage::helper('adminhtml')->__('API password'),
42
+ 'title' => Mage::helper('adminhtml')->__('API password'),
43
+ 'after_element_html' => '<button id="button_api_password" onClick="smToggleCredentialsVisibility(\'api_password\');return false;" >' . Mage::helper('sendmachine')->__('Show') . '</button><script>smInitCredentialsBlur()</script>'
44
+ ]
45
+ );
46
+
47
+ $form->addValues($sm->get());
48
+ $this->setForm($form);
49
+ return parent::_prepareForm();
50
+ }
51
+
52
+ }
app/code/community/Sendmachine/Sendmachine/Block/AppContainer/Tab/Lists.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Block_AppContainer_Tab_Lists extends Mage_Adminhtml_Block_Widget_Form {
4
+
5
+ protected function _prepareForm() {
6
+
7
+ $sm = Mage::registry('sm_model');
8
+ $form = new Varien_Data_Form(array(
9
+ 'id' => 'edit_form',
10
+ 'action' => $this->getUrl('*/*/save'),
11
+ 'method' => 'post'
12
+ )
13
+ );
14
+
15
+ $form->setUseContainer(true);
16
+
17
+ $fieldset = $form->addFieldset('lists_fieldset', ['legend' => Mage::helper('sendmachine')->__('List Settings')]);
18
+ $popupfieldset = $form->addFieldset('lists_fieldset_popup', ['legend' => Mage::helper('sendmachine')->__('Popup Settings')]);
19
+ $importexport = $form->addFieldset('lists_fieldset_importexport', ['legend' => Mage::helper('sendmachine')->__('Import/Export Users')]);
20
+
21
+ $fieldset->addField('tab_lists', 'hidden', [
22
+ 'name' => 'tab',
23
+ 'value' => 'list'
24
+ ]);
25
+
26
+ $fieldset->addField('selected_contact_list', 'select', [
27
+ 'name' => 'selected_contact_list',
28
+ 'label' => Mage::helper('sendmachine')->__('Contact List'),
29
+ 'title' => Mage::helper('sendmachine')->__('Contact List'),
30
+ 'values' => Mage::getModel('sendmachine/source_contactlist')->toOptionArray(),
31
+ 'after_element_html' => '<button style="margin-top:10px;" onClick="smRefreshCachedLists(\'' . Mage::helper('adminhtml')->getUrl('adminhtml/sendmachine/refreshCachedLists') . '\');return false;" >' . Mage::helper('sendmachine')->__('Refresh contact lists') . '</button><br><small>' . Mage::helper('sendmachine')->__("Contact lists do not update each time you visit this page. Click 'refresh' to update them when needed") . '</small>'
32
+ ]);
33
+
34
+ $fieldset->addField('keep_users_synced', 'select', [
35
+ 'name' => 'keep_users_synced',
36
+ 'label' => Mage::helper('sendmachine')->__('Keep subscribers synced'),
37
+ 'title' => Mage::helper('sendmachine')->__('Keep subscribers synced'),
38
+ 'values' => Mage::getModel('adminhtml/system_config_source_yesno')->toOptionArray()
39
+ ]);
40
+
41
+ $fieldset->addField('import_subscribers_limit', 'select', [
42
+ 'name' => 'import_subscribers_limit',
43
+ 'label' => Mage::helper('sendmachine')->__('Import subscribers limit'),
44
+ 'title' => Mage::helper('sendmachine')->__('Import subscribers limit'),
45
+ 'values' => Mage::getModel('sendmachine/source_importExportLimit')->toOptionArray()
46
+ ]);
47
+
48
+ $fieldset->addField('export_subscribers_limit', 'select', [
49
+ 'name' => 'export_subscribers_limit',
50
+ 'label' => Mage::helper('sendmachine')->__('Export subscribers limit'),
51
+ 'title' => Mage::helper('sendmachine')->__('Export subscribers limit'),
52
+ 'values' => Mage::getModel('sendmachine/source_importExportLimit')->toOptionArray()
53
+ ]);
54
+
55
+ $popupfieldset->addField('enable_subscribe_popup', 'select', [
56
+ 'name' => 'enable_subscribe_popup',
57
+ 'label' => Mage::helper('sendmachine')->__('Subscribe popup'),
58
+ 'title' => Mage::helper('sendmachine')->__('Subscribe popup'),
59
+ 'values' => Mage::getModel('adminhtml/system_config_source_yesno')->toOptionArray()
60
+ ]);
61
+
62
+ $popupfieldset->addField('popup_show_after_page', 'text', [
63
+ 'name' => 'popup_show_after_page',
64
+ 'label' => Mage::helper('sendmachine')->__('Show On Page View'),
65
+ 'title' => Mage::helper('sendmachine')->__('Show On Page View'),
66
+ ]);
67
+
68
+ $popupfieldset->addField('popup_delay', 'text', [
69
+ 'name' => 'popup_delay',
70
+ 'label' => Mage::helper('sendmachine')->__('Popup Delay (ms)'),
71
+ 'title' => Mage::helper('sendmachine')->__('Popup Delay (ms)'),
72
+ ]);
73
+
74
+ $popupfieldset->addField('hide_after_subscribe', 'text', [
75
+ 'name' => 'hide_after_subscribe',
76
+ 'label' => Mage::helper('sendmachine')->__('Dismiss popup (s)'),
77
+ 'title' => Mage::helper('sendmachine')->__('Dismiss popup (s)'),
78
+ 'after_element_html' => '<small>' . Mage::helper('sendmachine')->__('Dismiss popup box after successful subscribe or no activity. 0 means no dismiss') . '</small>'
79
+ ]);
80
+
81
+ $popupfieldset->addField('popup_show_on_store', 'select', array(
82
+ 'name' => 'popup_show_on_store',
83
+ 'label' => Mage::helper('sendmachine')->__('Show in store'),
84
+ 'title' => Mage::helper('sendmachine')->__('Show in store'),
85
+ 'values' => Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm(false, true),
86
+ ));
87
+
88
+ $popupfieldset->addField('popup_text_header', 'text', array(
89
+ 'name' => 'popup_text_header',
90
+ 'label' => Mage::helper('sendmachine')->__("Popup header text"),
91
+ 'title' => Mage::helper('sendmachine')->__("Popup header text"),
92
+ ));
93
+
94
+ $popupfieldset->addField('popup_custom_fields', 'checkbox', array(
95
+ 'style' => 'display:none',
96
+ 'label' => Mage::helper('sendmachine')->__("Popup custom fields"),
97
+ 'title' => Mage::helper('sendmachine')->__("Popup custom fields"),
98
+ 'after_element_html' => Mage::helper('sendmachine')->customfields2checkbox($sm->get('list_custom_fields'))
99
+ ));
100
+
101
+ $importexport->addField('sm_import_export_store', 'select', array(
102
+ 'name' => 'sm_import_export_store',
103
+ 'label' => Mage::helper('sendmachine')->__("Store"),
104
+ 'title' => Mage::helper('sendmachine')->__("Store"),
105
+ 'values' => Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm(false, true),
106
+ ));
107
+
108
+ $importexport->addField('smImportToNewsletter', 'button', [
109
+ 'label' => Mage::helper('sendmachine')->__("Import subscribers"),
110
+ 'value' => 'Import to Newsletter',
111
+ 'class' => 'form-button',
112
+ 'onclick' => "smImport('" . Mage::helper('adminhtml')->getUrl('adminhtml/sendmachine/importToNewsletter') . "')",
113
+ 'after_element_html' => '<br><small>' . Mage::helper('sendmachine')->__("Import your sendmachine subscribers to 'Newsletter Subscribers' page.") . '<br><b>' . Mage::helper('sendmachine')->__('Note!') . '</b> ' . Mage::helper('sendmachine')->__("You must select a contact list first.") . '<br>' . Mage::helper('sendmachine')->__("If 'All store views' option is selected, users will be subscribed to the default store") . '</small>'
114
+ ]);
115
+
116
+ $importexport->addField('smExportToSendmachine', 'button', [
117
+ 'label' => Mage::helper('sendmachine')->__('Export subscribers'),
118
+ 'value' => 'Export to Sendmachine',
119
+ 'class' => 'form-button',
120
+ 'onclick' => "smExport('" . Mage::helper('adminhtml')->getUrl('adminhtml/sendmachine/exportToSendmachine') . "')",
121
+ 'after_element_html' => '<br><small>' . Mage::helper('sendmachine')->__("Export your subscribed customers to a contact list in your sendmachine account.") . '<br><b>' . Mage::helper('sendmachine')->__("Note!") . '</b> ' . Mage::helper('sendmachine')->__("You must select a contact list first") . '</small>'
122
+ ]);
123
+
124
+ $form->addValues($sm->get());
125
+ $this->setForm($form);
126
+ return parent::_prepareForm();
127
+ }
128
+
129
+ protected function _afterToHtml($html) {
130
+
131
+ $extra = $this->getLayout()->createBlock('sendmachine/appContainer_grid')->toHtml();
132
+ return $html . $extra;
133
+ }
134
+
135
+ }
app/code/community/Sendmachine/Sendmachine/Block/AppContainer/Tabs.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Block_AppContainer_Tabs extends Mage_Adminhtml_Block_Widget_Tabs {
4
+
5
+ public function __construct() {
6
+
7
+ parent::__construct();
8
+
9
+ $this->setId('sendmachine_tabs');
10
+ $this->setTitle("<img style='height:44px;' src='" . $this->getSkinUrl('sendmachine/logo.png') . "'>");
11
+ }
12
+
13
+ protected function _beforeToHtml() {
14
+
15
+ $this->addTab('general_section', array(
16
+ 'label' => Mage::helper('sendmachine')->__('General'),
17
+ 'title' => Mage::helper('sendmachine')->__('General'),
18
+ 'url' => $this->getUrl('*/*/index')
19
+ ));
20
+
21
+ $this->addTab('list_section', array(
22
+ 'label' => Mage::helper('sendmachine')->__('List'),
23
+ 'title' => Mage::helper('sendmachine')->__('List'),
24
+ 'url' => $this->getUrl('*/*/list'),
25
+ 'active' => (Mage::app()->getRequest()->getActionName() == 'list' ) ? true : false
26
+ ));
27
+
28
+ $this->addTab('email_section', array(
29
+ 'label' => Mage::helper('sendmachine')->__('Email'),
30
+ 'title' => Mage::helper('sendmachine')->__('Email'),
31
+ 'url' => $this->getUrl('*/*/email'),
32
+ 'active' => (Mage::app()->getRequest()->getActionName() == 'email' ) ? true : false
33
+ ));
34
+
35
+ return parent::_beforeToHtml();
36
+ }
37
+
38
+ }
app/code/community/Sendmachine/Sendmachine/Block/PopupBlock.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ Class Sendmachine_Sendmachine_Block_PopupBlock extends Mage_Core_Block_Template {
4
+
5
+ private $sm = NULL;
6
+
7
+ public function displayPopup() {
8
+
9
+ $smInstance = Mage::registry('sm_model');
10
+ $this->sm = $smInstance ? $smInstance : Mage::getModel('sendmachine/sendmachine');
11
+
12
+ $store = $this->sm->get('popup_show_on_store');
13
+ $currentStore = Mage::app()->getStore()->getStoreId();
14
+
15
+ if ($this->sm->apiConnected() && $this->sm->get('plugin_enabled') && $this->sm->get('enable_subscribe_popup') && (!$store || $store == $currentStore)) {
16
+
17
+ $cookie = Mage::getSingleton('core/cookie');
18
+ if (!$count = $cookie->get('sendmachine_popup_count')) {
19
+ $cookie->set('sendmachine_popup_count', 1, 3600 * 24 * 365, '/');
20
+ $count = 0;
21
+ }
22
+
23
+ $configCount = $this->sm->get('popup_show_after_page');
24
+
25
+ if ($configCount > $count) {
26
+ $count++;
27
+ $cookie->set('sendmachine_popup_count', $count, 3600 * 24 * 365, '/');
28
+
29
+ if ($configCount == $count) {
30
+ return true;
31
+ }
32
+ }
33
+
34
+ return false;
35
+ }
36
+
37
+ return false;
38
+ }
39
+
40
+ public function formData() {
41
+
42
+ $fields = $this->sm->get('list_custom_fields');
43
+ return Mage::helper('sendmachine')->customfields2form($fields);
44
+ }
45
+
46
+ public function popupDescription() {
47
+
48
+ return $this->sm->get('popup_text_header');
49
+ }
50
+
51
+ public function getPopupDelay() {
52
+
53
+ return (int) $this->sm->get('popup_delay');
54
+ }
55
+
56
+ public function getPostUrl() {
57
+
58
+ return Mage::getUrl('sendmachine/subscribe/');
59
+ }
60
+
61
+ public function getSubscribePopupDelay() {
62
+
63
+ return $this->sm->get('hide_after_subscribe');
64
+ }
65
+
66
+ }
app/code/community/Sendmachine/Sendmachine/Helper/Data.php ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Helper_Data extends Mage_Core_Helper_Abstract {
4
+
5
+ public function initEmailConfig($smtp_settings, $smtpEncryptionType) {
6
+
7
+ if ($smtp_settings) {
8
+
9
+ $config = [
10
+ "host" => $smtp_settings['hostname'],
11
+ "username" => $smtp_settings["username"],
12
+ "password" => $smtp_settings['password'],
13
+ ];
14
+
15
+ switch ($smtpEncryptionType) {
16
+ case "SSL":
17
+ $config["port"] = $smtp_settings['ssl_tls_port'];
18
+ $config["ssl"] = "ssl";
19
+ break;
20
+ case "TLS":
21
+ $config["port"] = $smtp_settings['starttls_port'];
22
+ $config["ssl"] = "tls";
23
+ break;
24
+ default:
25
+ $config["port"] = $smtp_settings['port'];
26
+ break;
27
+ }
28
+ return $config;
29
+ } else {
30
+ return false;
31
+ }
32
+ }
33
+
34
+ public function customfields2form($fields = NULL) {
35
+
36
+ if (!$fields) {
37
+ return false;
38
+ }
39
+
40
+ $list_fields = "";
41
+
42
+ foreach ($fields as $k => $v) {
43
+
44
+ if ($v['visible']) {
45
+
46
+ $required = ($v['required']) ? "*" : "";
47
+
48
+ $list_fields .= $v['label'] . " $required<br>";
49
+
50
+ if (in_array($v['type'], ["text", "number", "email", "date", "birthday"])) {
51
+ $placeholder = "";
52
+
53
+ if ($v['type'] == "date")
54
+ $placeholder = "yyyy/mm/dd";
55
+ elseif ($v['type'] == "birthday")
56
+ $placeholder = "mm/dd";
57
+
58
+ $list_fields .= "<input placeholder='$placeholder' type='text' name='" . $k . "'/><br><br>";
59
+ }
60
+ elseif ($v['type'] == "radiobutton") {
61
+
62
+ foreach ($v['options'] as $option) {
63
+
64
+ $list_fields .= "<label><input type='radio' value='" . $option . "' name='" . $k . "' /> " . $option . "</label><br>";
65
+ }
66
+ $list_fields .="<br>";
67
+ } elseif ($v['type'] == "dropdown") {
68
+
69
+ $list_fields .= "<select class='sm_list_dropdown' name='" . $k . "'>";
70
+ $list_fields .= "<option></option>";
71
+
72
+ foreach ($v['options'] as $option) {
73
+
74
+ $list_fields .= "<option value='" . $option . "'>" . $option . "</option>";
75
+ }
76
+
77
+ $list_fields .= "</select><br><br>";
78
+ }
79
+ }
80
+ }
81
+
82
+ return $list_fields;
83
+ }
84
+
85
+ public function prepareCustomFields($fields) {
86
+
87
+ if (!$fields || !count($fields))
88
+ return NULL;
89
+
90
+ $_fields = [];
91
+ foreach ($fields as $v) {
92
+
93
+ if (!isset($v['form_name']))
94
+ $v['form_name'] = uc_words(strtolower($v['name']));
95
+
96
+ $_fields[$v['name']] = ['label' => $v['form_name'], 'visible' => $v['visible'] ? 1 : 0, 'required' => $v['required'] ? 1 : 0, 'type' => $v['cf_type']];
97
+
98
+ if (isset($v['options']))
99
+ $_fields[$v['name']]['options'] = $v['options'];
100
+ }
101
+
102
+ return $_fields;
103
+ }
104
+
105
+ public function customfields2checkbox($fields) {
106
+
107
+ if (!$fields) {
108
+ return false;
109
+ }
110
+
111
+ $data = "<table style='width:100%' cellspacing='0' cellpadding='0'><thead><th>" . $this->__('Label') . "</th><th>" . $this->__('Name') . "</th><th>" . $this->__('Visible') . "</th></thead><tbody>";
112
+
113
+ foreach ($fields as $k => $v) {
114
+
115
+ $checked = $v['visible'] || $v['required'] ? "checked" : "";
116
+ $disabled = $v['required'] ? 'disabled' : "";
117
+ $note = $v['required'] ? '*' : "";
118
+ $value = $v['required'] ? '1' : "0";
119
+ $input = "<input type='hidden' name='list_custom_fields[$k][visible]' value='" . $value . "'/>";
120
+ $input .= "<input $checked $disabled name='list_custom_fields[$k][visible]' value='1' type='checkbox'/> $note";
121
+
122
+ $data .= "<tr><td style='border-top:1px solid grey' >" . $v['label'] . "</td><td style='border-top:1px solid grey;'>$k</td><td style='border-top:1px solid grey;'>$input</td></tr>";
123
+ }
124
+ $data .= "<tr><td style='padding-top:8px;' colspan='3'>".$this->__("* field is required, can't be hidden")."</td></tr>";
125
+ $data .= "</tbody></table>";
126
+
127
+ return $data;
128
+ }
129
+
130
+ }
app/code/community/Sendmachine/Sendmachine/Model/...Observer.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Septi_Sendmachine_Model_Observer {
4
+
5
+ public function __construct() {
6
+
7
+ $this->sm = Mage::getModel('sendmachine/sm4magento');
8
+ }
9
+
10
+ public function sendmachineObserver() {
11
+
12
+ $credentials = $this->sm->getCredentials();
13
+ $this->sm->connectApi($credentials);
14
+
15
+ if (Mage::getStoreConfigFlag('system/smtp/disable')) {
16
+ $this->sm->setData('system/smtp/disable', 0);
17
+ }
18
+ }
19
+
20
+ }
app/code/community/Sendmachine/Sendmachine/Model/Cronjobs.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Model_Cronjobs {
4
+
5
+ const IMPORT_LIMIT = 1000;
6
+
7
+ public function __construct() {
8
+
9
+ $smInstance = Mage::registry('sm_model');
10
+ $this->sm = $smInstance ? $smInstance : Mage::getModel('sendmachine/sendmachine');
11
+
12
+ Mage::register('sm_model', $this->sm);
13
+ }
14
+
15
+ public function importToNewsletter($store, $logId, $listId) {
16
+
17
+ $this->sm->importMode = true;
18
+
19
+ $_limit = $this->sm->get('import_subscribers_limit');
20
+ $limit = ($_limit > self::IMPORT_LIMIT) ? self::IMPORT_LIMIT : $_limit;
21
+
22
+ if (!$listId) {
23
+ $this->sm->addImportExportLog('import', 'failed', 0, $logId);
24
+ return false;
25
+ }
26
+
27
+ $members = $this->sm->fetchListSubscribers($listId, $limit);
28
+
29
+ $sm_subscribers = false;
30
+ if ($members && count($members)) {
31
+
32
+ foreach ($members as $val) {
33
+ $sm_subscribers[] = $val['email'];
34
+ }
35
+ }
36
+
37
+ Mage::app()->setCurrentStore((int) $store);
38
+
39
+ if ($sm_subscribers && count($sm_subscribers)) {
40
+
41
+ $subscribe_model = Mage::getModel('newsletter/subscriber');
42
+
43
+ foreach ($sm_subscribers as $email) {
44
+
45
+ $subscribe_model->setImportMode(true)->subscribe($email);
46
+ $subscriber = $subscribe_model->loadByEmail($email);
47
+ $subscriber->setStatus(Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED);
48
+ $subscriber->save();
49
+ }
50
+ }
51
+
52
+ $this->sm->addImportExportLog('import', 'completed', count($sm_subscribers), $logId);
53
+ $this->sm->importMode = false;
54
+ }
55
+
56
+ }
app/code/community/Sendmachine/Sendmachine/Model/Email/Queue.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Model_Email_Queue extends Mage_Core_Model_Email_Queue {
4
+
5
+ /**
6
+ * Send all messages in a queue
7
+ *
8
+ * @return Mage_Core_Model_Email_Queue
9
+ */
10
+ public function send() {
11
+
12
+ /** @var $collection Mage_Core_Model_Resource_Email_Queue_Collection */
13
+ $collection = Mage::getModel('core/email_queue')->getCollection()
14
+ ->addOnlyForSendingFilter()
15
+ ->setPageSize(self::MESSAGES_LIMIT_PER_CRON_RUN)
16
+ ->setCurPage(1)
17
+ ->load();
18
+
19
+
20
+ $smInstance = Mage::registry('sm_model');
21
+ $sm = $smInstance ? $smInstance : Mage::getModel('sendmachine/sendmachine');
22
+
23
+ ini_set('SMTP', Mage::getStoreConfig('system/smtp/host'));
24
+ ini_set('smtp_port', Mage::getStoreConfig('system/smtp/port'));
25
+
26
+ /** @var $message Mage_Core_Model_Email_Queue */
27
+ foreach ($collection as $message) {
28
+ if ($message->getId()) {
29
+ $parameters = new Varien_Object($message->getMessageParameters());
30
+
31
+ $mailer = new Zend_Mail('utf-8');
32
+
33
+ if (!$sm->configureEmail()) {
34
+
35
+ if ($parameters->getReturnPathEmail() !== null) {
36
+ $mailTransport = new Zend_Mail_Transport_Sendmail("-f" . $parameters->getReturnPathEmail());
37
+ Zend_Mail::setDefaultTransport($mailTransport);
38
+ }
39
+ }
40
+
41
+ foreach ($message->getRecipients() as $recipient) {
42
+ list($email, $name, $type) = $recipient;
43
+ switch ($type) {
44
+ case self::EMAIL_TYPE_BCC:
45
+ $mailer->addBcc($email, '=?utf-8?B?' . base64_encode($name) . '?=');
46
+ break;
47
+ case self::EMAIL_TYPE_TO:
48
+ case self::EMAIL_TYPE_CC:
49
+ default:
50
+ $mailer->addTo($email, '=?utf-8?B?' . base64_encode($name) . '?=');
51
+ break;
52
+ }
53
+ }
54
+
55
+ if ($parameters->getIsPlain()) {
56
+ $mailer->setBodyText($message->getMessageBody());
57
+ } else {
58
+ $mailer->setBodyHTML($message->getMessageBody());
59
+ }
60
+
61
+ $mailer->setSubject('=?utf-8?B?' . base64_encode($parameters->getSubject()) . '?=');
62
+
63
+
64
+ $_fromEmail = $sm->get('from_email');
65
+ $_fromName = $sm->get('from_name');
66
+
67
+ $fromEmail = $_fromEmail ? $_fromEmail : $parameters->getFromEmail();
68
+ $fromName = $_fromName ? $_fromName : $parameters->getFromName();
69
+
70
+ $mailer->setFrom($fromEmail, $fromName);
71
+
72
+ if ($parameters->getReplyTo() !== null) {
73
+ $mailer->setReplyTo($parameters->getReplyTo());
74
+ }
75
+ if ($parameters->getReturnTo() !== null) {
76
+ $mailer->setReturnPath($parameters->getReturnTo());
77
+ }
78
+
79
+ try {
80
+ $mailer->send();
81
+ unset($mailer);
82
+ $message->setProcessedAt(Varien_Date::formatDate(true));
83
+ $message->save();
84
+ } catch (Exception $e) {
85
+ unset($mailer);
86
+ $oldDevMode = Mage::getIsDeveloperMode();
87
+ Mage::setIsDeveloperMode(true);
88
+ Mage::logException($e);
89
+ Mage::setIsDeveloperMode($oldDevMode);
90
+
91
+ return false;
92
+ }
93
+ }
94
+ }
95
+
96
+ return $this;
97
+ }
98
+
99
+ }
app/code/community/Sendmachine/Sendmachine/Model/Email/Template.php ADDED
@@ -0,0 +1,120 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Model_Email_Template extends Mage_Core_Model_Email_Template {
4
+
5
+ /**
6
+ * Send mail to recipient
7
+ *
8
+ * @param array|string $email E-mail(s)
9
+ * @param array|string|null $name receiver name(s)
10
+ * @param array $variables template variables
11
+ * @return boolean
12
+ * */
13
+ public function send($email, $name = null, array $variables = array()) {
14
+
15
+ if (!$this->isValidForSend()) {
16
+ Mage::logException(new Exception('This letter cannot be sent.')); // translation is intentionally omitted
17
+ return false;
18
+ }
19
+
20
+ $emails = array_values((array) $email);
21
+ $names = is_array($name) ? $name : (array) $name;
22
+ $names = array_values($names);
23
+ foreach ($emails as $key => $email) {
24
+ if (!isset($names[$key])) {
25
+ $names[$key] = substr($email, 0, strpos($email, '@'));
26
+ }
27
+ }
28
+
29
+ $variables['email'] = reset($emails);
30
+ $variables['name'] = reset($names);
31
+
32
+ $this->setUseAbsoluteLinks(true);
33
+ $text = $this->getProcessedTemplate($variables, true);
34
+ $subject = $this->getProcessedTemplateSubject($variables);
35
+
36
+ $setReturnPath = Mage::getStoreConfig(self::XML_PATH_SENDING_SET_RETURN_PATH);
37
+ switch ($setReturnPath) {
38
+ case 1:
39
+ $returnPathEmail = $this->getSenderEmail();
40
+ break;
41
+ case 2:
42
+ $returnPathEmail = Mage::getStoreConfig(self::XML_PATH_SENDING_RETURN_PATH_EMAIL);
43
+ break;
44
+ default:
45
+ $returnPathEmail = null;
46
+ break;
47
+ }
48
+
49
+ if ($this->hasQueue() && $this->getQueue() instanceof Mage_Core_Model_Email_Queue) {
50
+ /** @var $emailQueue Mage_Core_Model_Email_Queue */
51
+ $emailQueue = $this->getQueue();
52
+ $emailQueue->setMessageBody($text);
53
+ $emailQueue->setMessageParameters(array(
54
+ 'subject' => $subject,
55
+ 'return_path_email' => $returnPathEmail,
56
+ 'is_plain' => $this->isPlain(),
57
+ 'from_email' => $this->getSenderEmail(),
58
+ 'from_name' => $this->getSenderName(),
59
+ 'reply_to' => $this->getMail()->getReplyTo(),
60
+ 'return_to' => $this->getMail()->getReturnPath(),
61
+ ))
62
+ ->addRecipients($emails, $names, Mage_Core_Model_Email_Queue::EMAIL_TYPE_TO)
63
+ ->addRecipients($this->_bccEmails, array(), Mage_Core_Model_Email_Queue::EMAIL_TYPE_BCC);
64
+ $emailQueue->addMessageToQueue();
65
+
66
+ return true;
67
+ }
68
+
69
+ ini_set('SMTP', Mage::getStoreConfig('system/smtp/host'));
70
+ ini_set('smtp_port', Mage::getStoreConfig('system/smtp/port'));
71
+
72
+ $mail = $this->getMail();
73
+ $smInstance = Mage::registry('sm_model');
74
+ $sm = $smInstance ? $smInstance : Mage::getModel('sendmachine/sendmachine');
75
+
76
+ if (!$sm->configureEmail()) {
77
+
78
+ if ($returnPathEmail !== null) {
79
+ $mailTransport = new Zend_Mail_Transport_Sendmail("-f" . $returnPathEmail);
80
+ Zend_Mail::setDefaultTransport($mailTransport);
81
+ }
82
+ }
83
+
84
+ foreach ($emails as $key => $email) {
85
+ $mail->addTo($email, '=?utf-8?B?' . base64_encode($names[$key]) . '?=');
86
+ }
87
+
88
+ if ($this->isPlain()) {
89
+ $mail->setBodyText($text);
90
+ } else {
91
+ $mail->setBodyHTML($text);
92
+ }
93
+
94
+ $mail->setSubject('=?utf-8?B?' . base64_encode($subject) . '?=');
95
+
96
+ $_fromEmail = $sm->get('from_email');
97
+ $_fromName = $sm->get('from_name');
98
+
99
+ $fromEmail = $_fromEmail ? $_fromEmail : $this->getSenderEmail();
100
+ $fromName = $_fromName ? $_fromName : $this->getSenderName();
101
+
102
+ $mail->setFrom($fromEmail, $fromName);
103
+
104
+ if ($trCmp = $sm->createTransactionalCampaign($this->getId())) {
105
+ $mail->addHeader($trCmp['header_name'], $trCmp['header_value']);
106
+ }
107
+
108
+ try {
109
+ $mail->send();
110
+ $this->_mail = null;
111
+ } catch (Exception $e) {
112
+ $this->_mail = null;
113
+ Mage::logException($e);
114
+ return false;
115
+ }
116
+
117
+ return true;
118
+ }
119
+
120
+ }
app/code/community/Sendmachine/Sendmachine/Model/Mysql4/Sendmachine.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Model_Mysql4_Sendmachine extends Mage_Core_Model_Mysql4_Abstract {
4
+
5
+ public function _construct() {
6
+
7
+ $this->_init('sendmachine/sendmachine', 'id');
8
+ }
9
+
10
+ }
app/code/community/Sendmachine/Sendmachine/Model/Mysql4/Sendmachine/Collection.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Model_Mysql4_Sendmachine_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract {
4
+
5
+ public function _construct() {
6
+
7
+ $this->_init('sendmachine/sendmachine');
8
+ }
9
+
10
+ }
app/code/community/Sendmachine/Sendmachine/Model/Observer.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Model_Observer {
4
+
5
+ public function handleSubscriber(Varien_Event_Observer $observer) {
6
+
7
+ $smInstance = Mage::registry('sm_model');
8
+ $sm = $smInstance ? $smInstance : Mage::getModel('sendmachine/sendmachine');
9
+
10
+ if ($sm->get('api_connected') && $sm->get('keep_users_synced') && !$sm->importMode) {
11
+
12
+ file_put_contents('/home/septi/work/logs/log', PHP_EOL . "Observer hit!!", FILE_APPEND);
13
+
14
+ $event = $observer->getEvent();
15
+ $subscriber = $event->getDataObject();
16
+ $data = $subscriber->getData();
17
+
18
+ if ($data['subscriber_status'] == Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED) {
19
+
20
+ $listId = $sm->get('selected_contact_list');
21
+ $sm->subscribeToList([$data['subscriber_email']], $listId);
22
+ }
23
+ }
24
+
25
+ return $observer;
26
+ }
27
+
28
+ }
app/code/community/Sendmachine/Sendmachine/Model/Sendmachine.php ADDED
@@ -0,0 +1,337 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Model_Sendmachine extends Mage_Core_Model_Abstract {
4
+
5
+ const SM_APP = "sendmachine_application";
6
+
7
+ protected $api = NULL;
8
+ protected $appData = NULL;
9
+
10
+ protected function _construct() {
11
+
12
+ parent::_construct();
13
+ $this->_init('sendmachine/sendmachine');
14
+ }
15
+
16
+ public function get($key = NULL, $forceFetch = false) {
17
+
18
+ if ($this->appData === NULL || $forceFetch) {
19
+
20
+ $tmpData = Mage::getStoreConfig(self::SM_APP, Mage::app()->getStore(0));
21
+ $this->appData = json_decode($tmpData, true);
22
+ }
23
+
24
+ if ($key) {
25
+ if (isset($this->appData[$key])) {
26
+ return $this->appData[$key];
27
+ }
28
+ return false;
29
+ }
30
+
31
+ return $this->appData;
32
+ }
33
+
34
+ public function set($key = "", $value = "", $commit = false, $walk_array = false) {
35
+
36
+ if ($key) {
37
+
38
+ if (is_null($this->appData))
39
+ $this->get();
40
+
41
+ if (is_array($key)) {
42
+
43
+ foreach ($key as $k => $v) {
44
+
45
+ if (is_array($v) && $walk_array)
46
+ $this->_walkArray($this->appData, [$k => $v]);
47
+ else
48
+ $this->appData[$k] = $v;
49
+ }
50
+ } else {
51
+
52
+ if (count($value) && $walk_array)
53
+ $this->_walkArray($this->appData, $value);
54
+ else
55
+ $this->appData[$key] = $value;
56
+ }
57
+
58
+ if ($commit)
59
+ $this->commit();
60
+
61
+ return true;
62
+ }
63
+ return false;
64
+ }
65
+
66
+ private function _walkArray(&$master_array, $merge_values) {
67
+
68
+ if (is_array($merge_values)) {
69
+
70
+ foreach ($merge_values as $k => $v) {
71
+ $this->_walkArray($master_array[$k], $v);
72
+ }
73
+ } else {
74
+ $master_array = $merge_values;
75
+ }
76
+ }
77
+
78
+ public function commit($path = self::SM_APP, $value = NULL) {
79
+
80
+ if (is_null($value)) {
81
+ $value = json_encode($this->appData);
82
+ }
83
+
84
+ Mage::getModel('core/config')->saveConfig($path, $value);
85
+
86
+ Mage::app()->getCacheInstance()->cleanType('config');
87
+ }
88
+
89
+ public function apiConnected() {
90
+
91
+ return $this->get("api_connected");
92
+ }
93
+
94
+ protected function initApiClass() {
95
+
96
+ set_include_path(get_include_path() . PATH_SEPARATOR . Mage::getBaseDir('lib') . '/SendmachineApi');
97
+ require_once(Mage::getBaseDir('lib') . '/SendmachineApi/SendmachineApiClient.php');
98
+
99
+ $credentials = $this->getCredentials();
100
+
101
+ if (!empty($credentials['username']) && !empty($credentials['password'])) {
102
+ $this->api = new SendmachineApiClient($credentials['username'], $credentials['password']);
103
+ }
104
+ }
105
+
106
+ public function connectApi($credentials = NULL) {
107
+
108
+ if ($credentials === NULL) {
109
+ $credentials = $this->getCredentials();
110
+ }
111
+
112
+ if (!empty($credentials['username']) && !empty($credentials['password'])) {
113
+ try {
114
+ $this->initApiClass();
115
+ $this->api = new SendmachineApiClient($credentials['username'], $credentials['password']);
116
+ $res = $this->api->account->details();
117
+ if (isset($res['user']))
118
+ return true;
119
+ else
120
+ return false;
121
+ } catch (Sendmachine_Error $ex) {
122
+ return $ex->getMessage();
123
+ } catch (Http_Error $ex) {
124
+
125
+ }
126
+ }
127
+
128
+ return NULL;
129
+ }
130
+
131
+ public function addCronjob($method = NULL, $args = []) {
132
+
133
+ if ($method) {
134
+
135
+ $savedQueueData = $this->get('sm_cronjob');
136
+ if (!is_array($savedQueueData)) {
137
+ $savedQueueData = [];
138
+ }
139
+
140
+ array_push($savedQueueData, ['method' => $method, 'args' => $args]);
141
+
142
+ $this->set('sm_cronjob', $savedQueueData, true);
143
+ }
144
+ }
145
+
146
+ public function executeCronjob() {
147
+
148
+ $sqd = $this->get('sm_cronjob');
149
+
150
+ $this->set('sm_cronjob', NULL, true);
151
+
152
+ if ($sqd && is_array($sqd) && count($sqd)) {
153
+
154
+ foreach ($sqd as $v) {
155
+ call_user_func_array([Mage::getModel('sendmachine/cronjobs'), $v['method']], $v['args']);
156
+ }
157
+ }
158
+ }
159
+
160
+ public function fetchSmtpSettings() {
161
+
162
+ try {
163
+ $this->initApiClass();
164
+ $resp = $this->api->account->smtp();
165
+ if (isset($resp['smtp'])) {
166
+ return $resp['smtp'];
167
+ } else
168
+ return false;
169
+ } catch (Sendmachine_Error $ex) {
170
+ return NULL;
171
+ } catch (Http_Error $ex) {
172
+ return NULL;
173
+ }
174
+ }
175
+
176
+ public function fetchContactLists() {
177
+
178
+ try {
179
+ $this->initApiClass();
180
+ $resp = $this->api->lists->get();
181
+ if (isset($resp['contactlists'])) {
182
+ return $resp['contactlists'];
183
+ } else {
184
+ return false;
185
+ }
186
+ } catch (Sendmachine_Error $ex) {
187
+ return NULL;
188
+ } catch (Http_Error $ex) {
189
+ return NULL;
190
+ }
191
+ }
192
+
193
+ public function fetchListMembers($listId = NULL, $limit = 25) {
194
+
195
+ try {
196
+ $this->initApiClass();
197
+ $resp = $this->api->lists->recipients($listId, (int) $limit, 0, 'subscribed', 'added');
198
+ if (isset($resp['contacts'])) {
199
+ return $resp['contacts'];
200
+ } else {
201
+ return false;
202
+ }
203
+ } catch (Sendmachine_Error $ex) {
204
+ return NULL;
205
+ } catch (Http_Error $ex) {
206
+ return NULL;
207
+ }
208
+ }
209
+
210
+ public function fetchCustomFields($listId = NULL) {
211
+
212
+ try {
213
+ $this->initApiClass();
214
+ $resp = $this->api->lists->custom_fields($listId);
215
+ if (isset($resp['custom_fields'])) {
216
+ return $resp['custom_fields'];
217
+ } else {
218
+ return false;
219
+ }
220
+ } catch (Sendmachine_Error $ex) {
221
+ return NULL;
222
+ } catch (Http_Error $ex) {
223
+ return NULL;
224
+ }
225
+ }
226
+
227
+ public function fetchListSubscribers($listId = NULL, $limit = 25) {
228
+
229
+ try {
230
+ $this->initApiClass();
231
+ $resp = $this->api->lists->recipients($listId, (int) $limit, 0, 'subscribed', 'added');
232
+ if (isset($resp['contacts'])) {
233
+ return $resp['contacts'];
234
+ } else {
235
+ return false;
236
+ }
237
+ } catch (Sendmachine_Error $ex) {
238
+ return NULL;
239
+ } catch (Http_Error $ex) {
240
+ return NULL;
241
+ }
242
+ }
243
+
244
+ public function subscribeToList($subscribers = [], $listId = NULL) {
245
+
246
+ try {
247
+ $this->initApiClass();
248
+ $resp = $this->api->lists->manage_contacts($listId, $subscribers);
249
+ if (isset($resp['status']) && ($resp['status'] == "saved" || $resp['status'] == "queued")) {
250
+ return true;
251
+ } else {
252
+ return false;
253
+ }
254
+ } catch (Sendmachine_Error $ex) {
255
+ return NULL;
256
+ } catch (Http_Error $ex) {
257
+ return NULL;
258
+ }
259
+ }
260
+
261
+ public function configureEmail() {
262
+
263
+ if ($this->apiConnected() && $this->get('plugin_enabled') && $this->get('email_enabled')) {
264
+
265
+ $config = $this->get('email_config');
266
+ $config['auth'] = "login";
267
+ $host = "";
268
+ if (isset($config['host'])) {
269
+ $host = $config['host'];
270
+ unset($config['host']);
271
+ }
272
+
273
+ $transport = new Zend_Mail_Transport_Smtp($host, $config);
274
+ Zend_Mail::setDefaultTransport($transport);
275
+ return true;
276
+ }
277
+ return false;
278
+ }
279
+
280
+ public function createTransactionalCampaign($template_id = "") {
281
+
282
+ if ($this->get('transactional_campaigns_enabled')) {
283
+
284
+ $trCmpAreas = $this->get('transactional_campaign_areas');
285
+ $trCmpPrexif = $this->get('transactional_campaign_prefix');
286
+ $trCmpSuffix = $this->get('transactional_campaign_suffix');
287
+
288
+ if (in_array($template_id, $trCmpAreas)) {
289
+
290
+ $template_list = Mage::getModel('core/email_template')->getDefaultTemplates();
291
+ $template_name = $template_list[trim($template_id)]['label'];
292
+
293
+ return [
294
+ "header_name" => "X-Sendmachine-Campaign",
295
+ "header_value" => $trCmpPrexif . $template_name . $trCmpSuffix
296
+ ];
297
+ }
298
+ return false;
299
+ }
300
+ return NULL;
301
+ }
302
+
303
+ public function getCredentials() {
304
+
305
+ return [
306
+ "username" => $this->get('api_username'),
307
+ "password" => $this->get('api_password')
308
+ ];
309
+ }
310
+
311
+ public function addImportExportLog($action, $state = 'pending', $number = 0, $logId = NULL) {
312
+
313
+ if (is_null($logId)) {
314
+ $listName = "";
315
+ $listId = $this->get('selected_contact_list');
316
+ $contactlists = $this->get('contact_lists');
317
+ foreach ($contactlists as $v) {
318
+ if ($v['list_id'] == $listId) {
319
+ $listName = $v['name'];
320
+ }
321
+ }
322
+ $data = array('action' => $action, 'state' => $state, 'list_name' => $listName, 'sdate' => date('Y-m-d H:i:s'));
323
+ $this->setData($data);
324
+ return $this->save()->getId();
325
+ } else {
326
+ $data = array('state' => $state, 'number' => $number, 'edate' => date('Y-m-d H:i:s'));
327
+ $this->load($logId)->addData($data);
328
+ try {
329
+ $this->setId($logId)->save();
330
+ return $logId;
331
+ } catch (Exception $e) {
332
+ return false;
333
+ }
334
+ }
335
+ }
336
+
337
+ }
app/code/community/Sendmachine/Sendmachine/Model/Source/Contactlist.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Model_Source_Contactlist {
4
+
5
+ public function __construct() {
6
+
7
+ $this->sm = Mage::registry('sm_model');
8
+ }
9
+
10
+ public function toOptionArray() {
11
+
12
+ $cl = [
13
+ [
14
+ 'value' => '0',
15
+ 'label' => ''
16
+ ]
17
+ ];
18
+ if ($this->sm->apiConnected()) {
19
+
20
+ $data = $this->sm->get('contact_lists');
21
+ if (count($data)) {
22
+ foreach ($data as $value) {
23
+ array_push($cl, [
24
+ 'value' => $value['list_id'],
25
+ 'label' => $value['name']
26
+ ]);
27
+ }
28
+ }
29
+ }
30
+ return $cl;
31
+ }
32
+
33
+ }
app/code/community/Sendmachine/Sendmachine/Model/Source/ImportExportLimit.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Model_Source_ImportExportLimit {
4
+
5
+ public function toOptionArray() {
6
+
7
+ $values = [100, 200, 500, 1000, 5000, 10000];
8
+
9
+ $ret = [];
10
+
11
+ foreach ($values as $val) {
12
+ array_push($ret, ['value' => $val, 'label' => $val]);
13
+ }
14
+
15
+ return $ret;
16
+ }
17
+
18
+ }
app/code/community/Sendmachine/Sendmachine/Model/Source/Smtp.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Model_Source_Smtp {
4
+
5
+ public function toOptionArray() {
6
+
7
+ return [
8
+ [
9
+ 'value' => 'OPEN',
10
+ 'label' => 'No Encryption',
11
+ ],
12
+ [
13
+ 'value' => 'SSL',
14
+ 'label' => 'SSL',
15
+ ],
16
+ [
17
+ 'value' => 'TLS',
18
+ 'label' => 'TLS'
19
+ ]
20
+ ];
21
+ }
22
+
23
+ }
app/code/community/Sendmachine/Sendmachine/Model/Source/TransactionalCampAreas.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_Model_Source_TransactionalCampAreas {
4
+
5
+ public function __construct() {
6
+
7
+ $this->sm = Mage::registry('sm_model');
8
+ }
9
+
10
+ public function toOptionArray() {
11
+
12
+ $cl = [];
13
+ if ($this->sm->get('api_connected')) {
14
+
15
+ $cl = Mage::getModel('core/email_template')->getDefaultTemplatesAsOptionsArray();
16
+ }
17
+ return $cl;
18
+ }
19
+
20
+ }
app/code/community/Sendmachine/Sendmachine/controllers/SendmachineController.php ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_SendmachineController extends Mage_Adminhtml_Controller_Action {
4
+
5
+ private $sm;
6
+
7
+ public function __construct($request, $response, $invokeArgs = []) {
8
+
9
+ parent::__construct($request, $response, $invokeArgs);
10
+
11
+ $smInstance = Mage::registry('sm_model');
12
+ $this->sm = $smInstance ? $smInstance : Mage::getModel('sendmachine/sendmachine');
13
+ }
14
+
15
+ private function _renderApp($tab = '') {
16
+
17
+ Mage::register('sm_model', $this->sm);
18
+
19
+ $this->loadLayout();
20
+ $this->_setActiveMenu('system/sendmachine');
21
+ $this->_addContent($this->getLayout()->createBlock('sendmachine/appContainer_main', 'smMainFormContainer', ['tab' => $tab]));
22
+ $this->_addLeft($this->getLayout()->createBlock('sendmachine/appContainer_tabs'));
23
+ $this->getLayout()->getBlock('head')->addJs("sendmachine/admin.js");
24
+ $this->renderLayout();
25
+ }
26
+
27
+ public function indexAction() {
28
+
29
+ $this->_title($this->__('System'))->_title($this->__('Sendmachine - General settings'));
30
+ $this->_renderApp('general');
31
+ }
32
+
33
+ public function listAction() {
34
+
35
+ $this->_title($this->__('System'))->_title($this->__('Sendmachine - List settings'));
36
+ $this->_renderApp('lists');
37
+ }
38
+
39
+ public function emailAction() {
40
+
41
+ $this->_title($this->__('System'))->_title($this->__('Sendmachine - Email settings'));
42
+ $this->_renderApp('email');
43
+ }
44
+
45
+ public function saveAction() {
46
+
47
+ $params = $this->getRequest()->getParams();
48
+ $tab = isset($params['tab']) ? $params['tab'] : "index";
49
+
50
+ unset($params['tab']);
51
+ unset($params['limit']);
52
+ unset($params['page']);
53
+ unset($params['key']);
54
+ unset($params['form_key']);
55
+
56
+ $initial_credentials = $this->sm->getCredentials();
57
+ $initial_listid = $this->sm->get('selected_contact_list');
58
+ $initial_smtp_encryption = $this->sm->get('smtp_encryption');
59
+ $this->sm->set($params, NULL, false, true);
60
+ $credentials = $this->sm->getCredentials();
61
+ $listid = $this->sm->get('selected_contact_list');
62
+ $this->smtp_encryption = $this->sm->get('smtp_encryption');
63
+ $errorHandled = false;
64
+
65
+ if ($initial_credentials != $credentials) {
66
+
67
+ if (($connectApi = $this->sm->connectApi()) === true)
68
+ $this->_initApp();
69
+
70
+ else {
71
+
72
+ if (!$connectApi)
73
+ $connectApi = "Unexpected error occurred!";
74
+
75
+ $errorHandled = true;
76
+ Mage::getSingleton('adminhtml/session')->addError($this->__($connectApi));
77
+ $this->_resetApp();
78
+ }
79
+ }
80
+
81
+ if ($initial_listid != $listid) {
82
+
83
+ $fields = $this->sm->fetchCustomFields($listid);
84
+ $this->sm->set('list_custom_fields', Mage::helper('sendmachine')->prepareCustomFields($fields));
85
+ }
86
+
87
+ if ($initial_smtp_encryption != $this->smtp_encryption) {
88
+
89
+ $smtp_settings = $this->sm->get("provider_smtp_settings");
90
+ $email_settings = Mage::helper('sendmachine')->initEmailConfig($smtp_settings, $this->smtp_encryption);
91
+ $this->sm->set('email_config', $email_settings);
92
+ }
93
+
94
+ $this->sm->commit();
95
+
96
+ if (!$errorHandled)
97
+ Mage::getSingleton('adminhtml/session')->addSuccess($this->__('Successfully saved'));
98
+ $this->getResponse()->setRedirect($this->getUrl("*/*/" . $tab));
99
+ }
100
+
101
+ public function sendtestmailAction() {
102
+
103
+ if (!$this->sm->apiConnected()) {
104
+
105
+ Mage::getSingleton('adminhtml/session')->addError($this->__('Api not connected'));
106
+ return false;
107
+ }
108
+ if (!$this->sm->get('email_enabled')) {
109
+
110
+ Mage::getSingleton('adminhtml/session')->addError($this->__("'email sending' not enabled"));
111
+ return false;
112
+ }
113
+
114
+ $mailer = Mage::getModel('core/email_template');
115
+
116
+ $recipientEmail = $this->getRequest()->getParam('emailAddress');
117
+
118
+ $sender['name'] = Mage::getStoreConfig('trans_email/ident_general/name');
119
+ $sender['email'] = Mage::getStoreConfig('trans_email/ident_general/email');
120
+
121
+ $result = $mailer->sendTransactional("smSendTestEmail", $sender, $recipientEmail);
122
+
123
+ if ($result->sent_success)
124
+ Mage::getSingleton('adminhtml/session')->addSuccess(sprintf($this->__("Test message to '%s' sent successfully"), $recipientEmail));
125
+ else
126
+ Mage::getSingleton('adminhtml/session')->addError($this->__('Something went wrong, message not sent'));
127
+ }
128
+
129
+ public function importToNewsletterAction() {
130
+
131
+ if ($this->sm->apiConnected()) {
132
+
133
+ $store = $this->getRequest()->getParam('store');
134
+ if (!$store) {
135
+ $store = Mage::app()->getWebsite(true)->getDefaultGroup()->getDefaultStoreId();
136
+ }
137
+ $logId = $this->sm->addImportExportLog('import');
138
+ $listId = $this->sm->get('selected_contact_list');
139
+
140
+ $this->sm->addCronjob('importToNewsletter', [$store, $logId, $listId]);
141
+
142
+ Mage::getSingleton('adminhtml/session')->addSuccess($this->__('Import queued'));
143
+ } else {
144
+
145
+ Mage::getSingleton('adminhtml/session')->addError($this->__('Api not connected'));
146
+ }
147
+ }
148
+
149
+ public function exportToSendmachineAction() {
150
+
151
+ if ($this->sm->apiConnected()) {
152
+
153
+ $subscribe_status = [Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED];
154
+
155
+ $logId = $this->sm->addImportExportLog('export');
156
+
157
+ $store = $this->getRequest()->getParam('sm_import_export_store');
158
+ $limit = $this->sm->get('export_subscribers_limit');
159
+ $subscribers = Mage::getModel('newsletter/subscriber')->getCollection()->setPageSize((int) $limit);
160
+ $_subscribers = [];
161
+
162
+ if ($subscribers && count($subscribers)) {
163
+
164
+ foreach ($subscribers as $v) {
165
+
166
+ $data = $v->get();
167
+ if (($store && $store != $data['store_id']) || !in_array($data['subscriber_status'], $subscribe_status)) {
168
+ continue;
169
+ }
170
+ $_subscribers[] = $data['subscriber_email'];
171
+ }
172
+ }
173
+
174
+ $listId = $this->sm->get('selected_contact_list');
175
+ $subscribeStatus = $this->sm->subscribeToList($_subscribers, $listId);
176
+
177
+ $state = $subscribeStatus ? "completed" : "failed";
178
+ $count = $subscribeStatus ? count($_subscribers) : 0;
179
+
180
+ $this->sm->addImportExportLog('export', $state, $count, $logId);
181
+
182
+ if ($subscribeStatus) {
183
+ Mage::getSingleton('adminhtml/session')->addSuccess($this->__('Export successful'));
184
+ } else {
185
+ Mage::getSingleton('adminhtml/session')->addError($this->__('Something went wrong, export not completed'));
186
+ }
187
+ } else {
188
+
189
+ Mage::getSingleton('adminhtml/session')->addError($this->__('Api not connected'));
190
+ }
191
+ }
192
+
193
+ public function refreshCachedListsAction() {
194
+
195
+ if ($this->sm->apiConnected()) {
196
+
197
+ if ($resp = $this->sm->fetchContactLists()) {
198
+
199
+ $this->sm->set("contact_lists", $resp);
200
+
201
+ $listid = $this->sm->get('selected_contact_list');
202
+ $fields = $this->sm->fetchCustomFields($listid);
203
+ $this->sm->set('list_custom_fields', Mage::helper('sendmachine')->prepareCustomFields($fields), true);
204
+
205
+ Mage::getSingleton('adminhtml/session')->addSuccess($this->__('Lists refreshed'));
206
+ } else {
207
+ Mage::getSingleton('adminhtml/session')->addError($this->__('Something went wrong, lists not refreshed'));
208
+ }
209
+ } else {
210
+
211
+ Mage::getSingleton('adminhtml/session')->addError($this->__('Api not connected'));
212
+ }
213
+ }
214
+
215
+ private function _initApp() {
216
+
217
+ $this->sm->set('api_connected', true);
218
+ $this->sm->set('plugin_enabled', true);
219
+ $this->sm->set('email_enabled', true);
220
+ $this->sm->set('hide_after_subscribe', 15);
221
+ $this->sm->set('sm_cronjob', NULL);
222
+ $this->sm->set('import_subscribers_limit', 100);
223
+ $this->sm->set('export_subscribers_limit', 1000);
224
+ $this->sm->set('popup_show_after_page', 2);
225
+ $this->sm->set('popup_delay', 300);
226
+ $this->sm->set('selected_contact_list', NULL);
227
+ $this->sm->set('list_custom_fields', NULL);
228
+ $this->sm->set('keep_users_synced', true);
229
+
230
+ $smtpSettings = $this->sm->fetchSmtpSettings();
231
+ $this->sm->set("provider_smtp_settings", $smtpSettings ? $smtpSettings : "");
232
+
233
+ $contactLists = $this->sm->fetchContactLists();
234
+ $this->sm->set("contact_lists", $contactLists ? $contactLists : "");
235
+
236
+ $smtp_settings = $this->sm->get("provider_smtp_settings");
237
+ $email_settings = Mage::helper('sendmachine')->initEmailConfig($smtp_settings, 'OPEN');
238
+ $this->sm->set('email_config', $email_settings);
239
+
240
+ $this->sm->commit('system/smtp/disable', 0);
241
+ }
242
+
243
+ private function _resetApp() {
244
+
245
+ $this->sm->set('api_connected', false);
246
+ $this->sm->set('email_config', NULL);
247
+ $this->sm->set('sm_cronjob', NULL);
248
+ $this->sm->set('contact_lists', NULL);
249
+ $this->sm->set('smtp', NULL);
250
+ $this->sm->set('listId', NULL);
251
+ $this->sm->set('provider_smtp_settings', NULL);
252
+ }
253
+
254
+ }
app/code/community/Sendmachine/Sendmachine/controllers/SubscribeController.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sendmachine_Sendmachine_SubscribeController extends Mage_Core_Controller_Front_Action {
4
+
5
+ public function indexAction() {
6
+
7
+ $smInstance = Mage::registry('sm_model');
8
+ $sm = $smInstance ? $smInstance : Mage::getModel('sendmachine/sendmachine');
9
+
10
+ $params = $this->getRequest()->getParams();
11
+
12
+ $fields = $sm->get('list_custom_fields');
13
+ $response = NULL;
14
+ if (!$fields || !count($fields)) {
15
+ $response = ['code' => 0, 'message' => $this->__('Something went wrong.You were not subscribed')];
16
+ } else {
17
+
18
+ $arr = [];
19
+ foreach ($fields as $k => $v) {
20
+
21
+ if ($v['required'] && empty($params[$k])) {
22
+ $response = ['code' => 0, 'message' => $this->__('Required data was not filled')];
23
+ break;
24
+ }
25
+
26
+ if (!empty($params[$k])) {
27
+ $arr[strtolower($k)] = $params[$k];
28
+ }
29
+ }
30
+ if (!$response) {
31
+
32
+ $listId = $sm->get('selected_contact_list');
33
+ if ($sm->subscribeToList([$arr], $listId))
34
+ $response = ['code' => 1, 'message' => $this->__('You have been successfully subscribed')];
35
+ else
36
+ $response = ['code' => 0, 'message' => $this->__('Something went wrong.You were not subscribed')];
37
+ }
38
+ }
39
+
40
+ $this->getResponse()->clearHeaders()->setHeader('Content-type', 'application/json', true);
41
+ $this->getResponse()->setBody(json_encode($response));
42
+ }
43
+
44
+ }
app/code/community/Sendmachine/Sendmachine/etc/adminhtml.xml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <menu>
4
+ <system>
5
+ <children>
6
+ <sendmachine translate="title" module="sendmachine">
7
+ <title>Sendmachine</title>
8
+ <sort_order>110</sort_order>
9
+ <action>adminhtml/sendmachine</action>
10
+ </sendmachine>
11
+ </children>
12
+ </system>
13
+ </menu>
14
+ </config>
app/code/community/Sendmachine/Sendmachine/etc/config.xml ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Sendmachine_Sendmachine>
5
+ <version>1.0.0</version>
6
+ </Sendmachine_Sendmachine>
7
+ </modules>
8
+ <global>
9
+ <helpers>
10
+ <sendmachine>
11
+ <class>Sendmachine_Sendmachine_Helper</class>
12
+ </sendmachine>
13
+ </helpers>
14
+ <blocks>
15
+ <sendmachine>
16
+ <class>Sendmachine_Sendmachine_Block</class>
17
+ </sendmachine>
18
+ </blocks>
19
+ <events>
20
+ <newsletter_subscriber_save_commit_after>
21
+ <observers>
22
+ <sendmachine>
23
+ <class>Sendmachine_Sendmachine_Model_Observer</class>
24
+ <method>handleSubscriber</method>
25
+ </sendmachine>
26
+ </observers>
27
+ </newsletter_subscriber_save_commit_after>
28
+ </events>
29
+ <models>
30
+ <core>
31
+ <rewrite>
32
+ <email_template>Sendmachine_Sendmachine_Model_Email_Template</email_template>
33
+ </rewrite>
34
+ <rewrite>
35
+ <email_queue>Sendmachine_Sendmachine_Model_Email_Queue</email_queue>
36
+ </rewrite>
37
+ </core>
38
+ <sendmachine>
39
+ <class>Sendmachine_Sendmachine_Model</class>
40
+ <resourceModel>sendmachine_mysql4</resourceModel>
41
+ </sendmachine>
42
+ <sendmachine_mysql4>
43
+ <class>Sendmachine_Sendmachine_Model_Mysql4</class>
44
+ <entities>
45
+ <sendmachine>
46
+ <table>sm_import_export_log</table>
47
+ </sendmachine>
48
+ </entities>
49
+ </sendmachine_mysql4>
50
+ </models>
51
+ <resources>
52
+ <sendmachine_setup>
53
+ <setup>
54
+ <module>Sendmachine_Sendmachine</module>
55
+ </setup>
56
+ <connection>
57
+ <use>core_setup</use>
58
+ </connection>
59
+ </sendmachine_setup>
60
+ <sendmachine_write>
61
+ <connection>
62
+ <use>core_write</use>
63
+ </connection>
64
+ </sendmachine_write>
65
+ <sendmachine_read>
66
+ <connection>
67
+ <use>core_read</use>
68
+ </connection>
69
+ </sendmachine_read>
70
+ </resources>
71
+ <template>
72
+ <email>
73
+ <smSendTestEmail translate="label" module="sendmachine">
74
+ <label>Sendmachine Test Email</label>
75
+ <file>sendmachine/smSendTestEmail.html</file>
76
+ <type>html</type>
77
+ </smSendTestEmail>
78
+ </email>
79
+ </template>
80
+ </global>
81
+ <crontab>
82
+ <jobs>
83
+ <sendmachine>
84
+ <schedule>
85
+ <cron_expr>*/1 * * * *</cron_expr>
86
+ </schedule>
87
+ <run>
88
+ <model>sendmachine/sendmachine::executeCronjob</model>
89
+ </run>
90
+ </sendmachine>
91
+ </jobs>
92
+ </crontab>
93
+ <admin>
94
+ <routers>
95
+ <adminhtml>
96
+ <args>
97
+ <modules>
98
+ <sendmachine before="Mage_Adminhtml">Sendmachine_Sendmachine</sendmachine>
99
+ </modules>
100
+ </args>
101
+ </adminhtml>
102
+ </routers>
103
+ </admin>
104
+ <frontend>
105
+ <layout>
106
+ <updates>
107
+ <sendmachine>
108
+ <file>sendmachine.xml</file>
109
+ </sendmachine>
110
+ </updates>
111
+ </layout>
112
+ <routers>
113
+ <sendmachine>
114
+ <use>standard</use>
115
+ <args>
116
+ <module>Sendmachine_Sendmachine</module>
117
+ <frontName>sendmachine</frontName>
118
+ </args>
119
+ </sendmachine>
120
+ </routers>
121
+ </frontend>
122
+ <adminhtml>
123
+ <translate>
124
+ <modules>
125
+ <sendmachine>
126
+ <files>
127
+ <default>Sendmachine_Sendmachine.csv</default>
128
+ </files>
129
+ </sendmachine>
130
+ </modules>
131
+ </translate>
132
+ </adminhtml>
133
+ </config>
app/code/community/Sendmachine/Sendmachine/sql/sendmachine_setup/mysql4-install-1.0.0.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ $installer->run("
8
+ -- DROP TABLE IF EXISTS {$this->getTable('sm_import_export_log')};
9
+ CREATE TABLE {$this->getTable('sm_import_export_log')} (
10
+ `id` int(11) unsigned NOT NULL auto_increment,
11
+ `action` ENUM('import','export') NOT NULL,
12
+ `state` ENUM('pending','completed','failed') NOT NULL,
13
+ `number` int(100) NULL DEFAULT '0',
14
+ `list_name` varchar(100) NOT NULL,
15
+ `sdate` DATETIME NOT NULL,
16
+ `edate` DATETIME NULL DEFAULT NULL,
17
+ PRIMARY KEY (`id`)
18
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
19
+
20
+ ");
21
+
22
+ $installer->endSetup();
app/design/frontend/base/default/layout/sendmachine.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout version="0.1.0">
3
+ <default translate="label" module="sendmachine">
4
+ <reference name="before_body_end">
5
+ <block type="sendmachine/popupBlock" name="sendmachine.popupBlock" template="sendmachine/popup.phtml" />
6
+ </reference>
7
+ <reference name="head">
8
+ <action method="addItem">
9
+ <type>skin_js</type>
10
+ <name>sendmachine/frontend.js</name>
11
+ </action>
12
+ <action method="addItem">
13
+ <type>skin_css</type>
14
+ <name>sendmachine/frontend.css</name>
15
+ </action>
16
+ </reference>
17
+ </default>
18
+ </layout>
app/design/frontend/base/default/template/sendmachine/popup.phtml ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <?php
3
+ if (!$this->displayPopup()) {
4
+ return;
5
+ }
6
+ ?>
7
+ <div onClick="smDismissPopup();" id="sm_popup_box_wrapper">
8
+ <table id="sm_popup_box_table">
9
+ <tr>
10
+ <td style="vertical-align:middle">
11
+ <div id="sm_popup_box_inner" onclick="smStopEventPropagation();smSubscribeHasActivity=true">
12
+ <div id="sm_popup_box_loader" ></div>
13
+ <div id="sm_popup_box_header">
14
+ <button id="sm_popup_box_close_button" onClick="smDismissPopup();" style="" >CLOSE</button>
15
+ <div style="clear:both" ></div>
16
+ </div>
17
+ <div id="sm_popup_box_main">
18
+ <div id="sm_popup_box_notification_area"></div>
19
+ <div id="sm_popup_box_description">
20
+ <?php echo $this->popupDescription(); ?>
21
+ </div>
22
+ <div id="sm_popup_box_content_form" >
23
+ <form onsubmit="smSubscribeCustomer(this, <?php echo $this->getSubscribePopupDelay(); ?>);return false;" action="<?php echo $this->getPostUrl() ?>">
24
+ <?php
25
+ echo $this->formData();
26
+ ?>
27
+ <input type="submit" value="SUBSCRIBE" id="sm_popup_box_submit_button" />
28
+ </form>
29
+ </div>
30
+ </div>
31
+ </div>
32
+ </td>
33
+ </tr>
34
+ </table>
35
+ </div>
36
+ <script>
37
+ smDisplayPopup(<?php echo $this->getPopupDelay() ?>);
38
+ smDismissNoActivity(<?php echo $this->getSubscribePopupDelay() ?>);
39
+ </script>
app/etc/modules/Sendmachine_Sendmachine.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Sendmachine_Sendmachine>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Sendmachine_Sendmachine>
8
+ </modules>
9
+ </config>
app/locale/en_US/Sendmachine_Sendmachine.csv ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Label","Label"
2
+ "Name","Name"
3
+ "Visible","Visible"
4
+ "* field is required, can't be hidden","* field is required, can't be hidden"
5
+ "Something went wrong.You were not subscribed","Something went wrong.You were not subscribed"
6
+ "Required data was not filled","Required data was not filled"
7
+ "You have been successfully subscribed","You have been successfully subscribed"
8
+ "System","System"
9
+ "Sendmachine - General settings","Sendmachine - General settings"
10
+ "Sendmachine - List settings","Sendmachine - List settings"
11
+ "Sendmachine - Email settings","Sendmachine - Email settings"
12
+ "Successfully saved","Successfully saved"
13
+ "Api not connected","Api not connected"
14
+ "'email sending' not enabled","'email sending' not enabled"
15
+ "Test message to '%s' sent successfully","Test message to '%s' sent successfully"
16
+ "Something went wrong, message not sent","Something went wrong, message not sent"
17
+ "Import queued","Import queued"
18
+ "Export successful","Export successful"
19
+ "Something went wrong, export not completed","Something went wrong, export not completed"
20
+ "Lists refreshed","Lists refreshed"
21
+ "Something went wrong, lists not refreshed","Something went wrong, lists not refreshed"
22
+ "connected","connected"
23
+ "disconnected","disconnected"
24
+ "Api status: ","Api status: "
25
+ "Index","Index"
26
+ "Action","Action"
27
+ "State","State"
28
+ "Customer number","Customer number"
29
+ "Contact list","Contact list"
30
+ "Start date","Start date"
31
+ "End date","End date"
32
+ "General","General"
33
+ "List","List"
34
+ "Email","Email"
35
+ "General Settings","General Settings"
36
+ "Plugin enabled","Plugin enabled"
37
+ "Api username","Api username"
38
+ "Show","Show"
39
+ "API password","API password"
40
+ "List Settings","List Settings"
41
+ "Popup Settings","Popup Settings"
42
+ "Import/Export Users","Import/Export Users"
43
+ "Contact List","Contact List"
44
+ "Refresh contact lists","Refresh contact lists"
45
+ "Contact lists do not update each time you visit this page. Click 'refresh' to update them when needed","Contact lists do not update each time you visit this page. Click 'refresh' to update them when needed"
46
+ "Keep subscribers synced","Keep subscribers synced"
47
+ "Import subscribers limit","Import subscribers limit"
48
+ "Export subscribers limit","Export subscribers limit"
49
+ "Subscribe popup","Subscribe popup"
50
+ "Show On Page View","Show On Page View"
51
+ "Popup Delay (ms)","Popup Delay (ms)"
52
+ "Dismiss popup (ms)","Dismiss popup (ms)"
53
+ "Dismiss popup box after successfull subscribe. 0 means no dismiss","Dismiss popup box after successfull subscribe. 0 means no dismiss"
54
+ "Show in store","Show in store"
55
+ "Popup header text","Popup header text"
56
+ "Popup custom fields","Popup custom fields"
57
+ "Store","Store"
58
+ "Import subscribers","Import subscribers"
59
+ "Import your sendmachine subscribers to 'Newsletter Subscribers' page.","Import your sendmachine subscribers to 'Newsletter Subscribers' page."
60
+ "Note!","Note!"
61
+ "You must select a contact list first.","You must select a contact list first."
62
+ "If 'All store views' option is selected, users will be subscribed to the default store","If 'All store views' option is selected, users will be subscribed to the default store"
63
+ "Export subscribers","Export subscribers"
64
+ "Export your subscribed customers to a contact list in your sendmachine account.","Export your subscribed customers to a contact list in your sendmachine account."
65
+ "You must select a contact list first","You must select a contact list first"
66
+ "Email Settings","Email Settings"
67
+ "Test Configuration","Test Configuration"
68
+ "Enable email sending","Enable email sending"
69
+ "SMTP Encryption","SMTP Encryption"
70
+ "From Email","From Email"
71
+ "Note! If you set a 'From email' here, all other 'from emails' will be ","Note! If you set a 'From email' here, all other 'from emails' will be "
72
+ "overriden","overriden"
73
+ "From Name","From Name"
74
+ "Note! If you set a 'From name' here, all other 'from names' will be overriden","Note! If you set a 'From name' here, all other 'from names' will be overriden"
75
+ "Use transactional emails","Use transactional emails"
76
+ "Transactional campaigns prefix","Transactional campaigns prefix"
77
+ "Transactional campaigns areas","Transactional campaigns areas"
78
+ "Note! Hold 'ctrl' and click the area you want to select/deselect for multiple selection","Note! Hold 'ctrl' and click the area you want to select/deselect for multiple selection"
79
+ "Transactional campaigns suffix","Transactional campaigns suffix"
80
+ "Send a test email","Send a test email"
81
+ "Send","Send"
82
+ "Send a test email to make sure that settings were applied correctly","Send a test email to make sure that settings were applied correctly"
83
+ msgstr ","msgstr ","
js/sendmachine/admin.js ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ function smInitCredentialsBlur() {
2
+
3
+ smToggleCredentialsVisibility('api_username', 'hide');
4
+ smToggleCredentialsVisibility('api_password', 'hide');
5
+
6
+ document.getElementById('api_username').onfocus = function () {
7
+ smToggleCredentialsVisibility('api_username', 'show');
8
+ };
9
+ document.getElementById('api_password').onfocus = function () {
10
+ smToggleCredentialsVisibility('api_password', 'show');
11
+ };
12
+ }
13
+
14
+ function smToggleCredentialsVisibility(id, state) {
15
+
16
+ if (id !== 'api_username' && id !== 'api_password') {
17
+ return;
18
+ }
19
+
20
+ var style = '';
21
+ var text = '';
22
+
23
+ var button = document.getElementById('button_' + id);
24
+
25
+ if (!state) {
26
+ state = button.getAttribute('class');
27
+ }
28
+
29
+ if (state === 'hide') {
30
+ style = 'color:transparent;text-shadow:0 0 5px rgba(0,0,0,0.5)';
31
+ text = 'show';
32
+ }
33
+ else if (state === 'show') {
34
+ style = '';
35
+ text = 'hide';
36
+ }
37
+
38
+ button.setAttribute('class', text);
39
+ button.innerHTML = text;
40
+ document.getElementById(id).setAttribute('style', style + ';width:222px;');
41
+ }
42
+
43
+ function smSendTestEmail(url) {
44
+
45
+ var emailAddress = document.getElementById('smMageTestEmail');
46
+ new Ajax.Request(url, {
47
+ method: 'post',
48
+ parameters: {emailAddress: emailAddress.value},
49
+ onSuccess: function () {
50
+ location.reload();
51
+ }
52
+ });
53
+ }
54
+
55
+ function smImport(url) {
56
+
57
+ var store = document.getElementById('sm_import_export_store').value;
58
+ new Ajax.Request(url, {
59
+ method: 'post',
60
+ parameters: {
61
+ store: store
62
+ },
63
+ onSuccess: function () {
64
+ location.reload();
65
+ }
66
+ });
67
+ }
68
+
69
+ function smExport(url) {
70
+
71
+ var store = document.getElementById('sm_import_export_store').value;
72
+ new Ajax.Request(url, {
73
+ method: 'post',
74
+ parameters: {sm_import_export_store: store},
75
+ onSuccess: function () {
76
+ location.reload();
77
+ }
78
+ });
79
+ }
80
+
81
+ function smRefreshCachedLists(url) {
82
+
83
+ new Ajax.Request(url, {
84
+ method: 'post',
85
+ onSuccess: function () {
86
+ location.reload();
87
+ }
88
+ });
89
+ }
lib/SendmachineApi/README.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ SendmachineApiClient
2
+ ====================
3
+
4
+ PHP implementation of the Sendmachine API.
5
+ [Developer documentation](http://developers.sendmachine.com/)
lib/SendmachineApi/SendmachineApiClient.php ADDED
@@ -0,0 +1,206 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once __dir__ . '/library/Account.php';
4
+ require_once __dir__ . '/library/Sender.php';
5
+ require_once __dir__ . '/library/Campaigns.php';
6
+ require_once __dir__ . '/library/Lists.php';
7
+ require_once __dir__ . '/library/Templates.php';
8
+
9
+ class SendmachineApiClient {
10
+
11
+ /**
12
+ * api host
13
+ * @var string
14
+ */
15
+ private $api_host = 'https://api.sendmachine.com';
16
+
17
+ /**
18
+ * api username
19
+ * @var string
20
+ */
21
+ private $username;
22
+
23
+ /**
24
+ * api password
25
+ * @var string
26
+ */
27
+ private $password;
28
+
29
+ /**
30
+ * Curl resource
31
+ * @var resource
32
+ */
33
+ private $curl;
34
+
35
+ /*
36
+ * for debugging
37
+ */
38
+ private $debug = false;
39
+
40
+ /**
41
+ * connect to api
42
+ * @param string $username
43
+ * @param string $password
44
+ */
45
+ public function __construct($username = null, $password = null) {
46
+
47
+ if (!$username || !$password) {
48
+
49
+ list($username, $password) = $this->check_config();
50
+ }
51
+
52
+ if (!$username || !$password) {
53
+
54
+ throw new Sendmachine_Error("You must provide a username and password", "no_username_password");
55
+ }
56
+
57
+ $this->username = $username;
58
+ $this->password = $password;
59
+
60
+ $this->curl = curl_init();
61
+
62
+ $this->campaigns = new Campaigns($this);
63
+ $this->sender = new Sender($this);
64
+ $this->lists = new Lists($this);
65
+ $this->account = new Account($this);
66
+ $this->templates = new Templates($this);
67
+ }
68
+
69
+ public function request($url, $method, $params = array()) {
70
+
71
+ $ch = $this->curl;
72
+
73
+ switch (strtoupper($method)) {
74
+ case 'GET':
75
+ if (count($params)) {
76
+ $url .= "?" . http_build_query($params);
77
+ }
78
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "GET");
79
+ break;
80
+ case 'PUT':
81
+ case 'POST':
82
+ $params = json_encode($params);
83
+
84
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
85
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
86
+ curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Content-Length: ' . strlen($params)]);
87
+ break;
88
+ case 'DELETE':
89
+ curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
90
+ curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
91
+ break;
92
+ }
93
+
94
+ $final_url = $this->api_host . $url;
95
+
96
+ curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_DEFAULT);
97
+ curl_setopt($ch, CURLOPT_USERPWD, $this->username . ":" . $this->password);
98
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
99
+ curl_setopt($ch, CURLOPT_URL, $final_url);
100
+ curl_setopt($ch, CURLOPT_VERBOSE, $this->debug);
101
+
102
+ if ($this->debug) {
103
+ $start = microtime(true);
104
+ $this->log('URL: ' . $this->api_host . $url . (is_string($params) ? ", params: " . $params : ""));
105
+ }
106
+
107
+ $response = curl_exec($ch);
108
+ $info = curl_getinfo($ch);
109
+
110
+ if ($this->debug) {
111
+ $time = microtime(true) - $start;
112
+ $this->log('Completed in ' . number_format($time * 1000, 2) . 'ms');
113
+ $this->log('Response: ' . $response);
114
+ }
115
+
116
+ if (curl_error($ch)) {
117
+
118
+ throw new Http_Error("API call to $this->api_host$url failed.Reason: " . curl_error($ch));
119
+ }
120
+
121
+ $result = json_decode($response, true);
122
+ if ($response && !$result)
123
+ $result = $response;
124
+
125
+ if ($info['http_code'] >= 400) {
126
+
127
+ $this->set_error($result);
128
+ }
129
+
130
+ return $result;
131
+ }
132
+
133
+ public function __destruct() {
134
+
135
+ if (is_resource($this->curl)) {
136
+
137
+ curl_close($this->curl);
138
+ }
139
+ }
140
+
141
+ public function log($msg) {
142
+ error_log($msg);
143
+ }
144
+
145
+ public function check_config() {
146
+
147
+ $config_paths = [".sendmachine.conf", "/etc/.sendmachine.conf"];
148
+ $username = null;
149
+ $password = null;
150
+
151
+ foreach ($config_paths as $path) {
152
+
153
+ if (file_exists($path)) {
154
+
155
+ if (!is_readable($path)) {
156
+
157
+ throw new Sendmachine_Error("Configuration file ($path) does not have read access.", "config_not_readable");
158
+ }
159
+
160
+ $config = parse_ini_file($path);
161
+
162
+ $username = empty($config['username']) ? null : $config['username'];
163
+ $password = empty($config['password']) ? null : $config['password'];
164
+ break;
165
+ }
166
+ }
167
+
168
+ return [$username, $password];
169
+ }
170
+
171
+ public function set_error($result) {
172
+
173
+ if (is_array($result)) {
174
+
175
+ if (empty($result['error_reason'])) {
176
+
177
+ if (!empty($result['status']))
178
+ $result['error_reason'] = $result['status'];
179
+ else
180
+ $result['error_reason'] = "Unexpected error";
181
+ }
182
+
183
+ throw new Sendmachine_Error($result['error_reason'], $result['status']);
184
+ }
185
+ }
186
+
187
+ }
188
+
189
+ class Sendmachine_Error extends Exception {
190
+
191
+ private $err_status;
192
+
193
+ public function __construct($error_reason = "", $error_status = "") {
194
+
195
+ parent::__construct($error_reason);
196
+
197
+ $this->err_status = $error_status;
198
+ }
199
+
200
+ public function getSendmachineStatus() {
201
+ return $this->err_status;
202
+ }
203
+
204
+ }
205
+
206
+ class Http_Error extends Sendmachine_Error {}
lib/SendmachineApi/composer.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "sendmachine/sendmachine-api-client",
3
+ "description": "Sendmachine API Client",
4
+ "keywords": ["sendmachine","api","email"],
5
+ "homepage": "https://github.com/Sendmachine/SendmachineApiClient",
6
+ "license": "MIT",
7
+ "require": {
8
+ "php": ">=5.3.0",
9
+ "ext-curl": "*"
10
+ }
11
+ }
lib/SendmachineApi/library/Account.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Account {
4
+
5
+ public function __construct(SendmachineApiClient $master) {
6
+ $this->master = $master;
7
+ }
8
+
9
+ /**
10
+ * Get details about the current active package of the user
11
+ * @return array
12
+ * {
13
+ * "package": {
14
+ * "name",
15
+ * "state",
16
+ * "credits",
17
+ * "interval",
18
+ * "price",
19
+ * "currency",
20
+ * "custom_fields",
21
+ * "period_min",
22
+ * "period_max",
23
+ * "contract_type",
24
+ * "max_credit",
25
+ * "mcountsent",
26
+ * "prod_id",
27
+ * "info_type"
28
+ * }
29
+ * }
30
+ */
31
+ public function package() {
32
+
33
+ return $this->master->request('/account/package', 'GET');
34
+ }
35
+
36
+ /**
37
+ * Get details about the current rating
38
+ * @return array
39
+ * {
40
+ * "score"
41
+ * }
42
+ */
43
+ public function rating() {
44
+
45
+ return $this->master->request('/account/rating', 'GET');
46
+ }
47
+
48
+ /**
49
+ * The SMTP user and password are also used for API Auth.
50
+ * @return array
51
+ * {
52
+ * "smtp": {
53
+ * "hostname",
54
+ * "port",
55
+ * "ssl_tls_port",
56
+ * "starttls_port",
57
+ * "username",
58
+ * "password",
59
+ * "state"
60
+ * }
61
+ * }
62
+ */
63
+ public function smtp() {
64
+
65
+ return $this->master->request('/account/smtp', 'GET');
66
+ }
67
+
68
+ /**
69
+ * get user details
70
+ * @return array
71
+ * {
72
+ * "user": {
73
+ * "email",
74
+ * "sex",
75
+ * "first_name",
76
+ * "last_name",
77
+ * "country",
78
+ * "phone_number",
79
+ * "mobile_number",
80
+ * "state",
81
+ * "language"
82
+ * }
83
+ * }
84
+ */
85
+ public function details() {
86
+
87
+ return $this->master->request('/account/user', 'GET');
88
+ }
89
+
90
+ }
lib/SendmachineApi/library/Campaigns.php ADDED
@@ -0,0 +1,222 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Campaigns {
4
+
5
+ public function __construct(SendmachineApiClient $master) {
6
+ $this->master = $master;
7
+ }
8
+
9
+ /**
10
+ *get campaigns
11
+ * @param type $filter (campaign, transactional, archived, new, finalized, scheduled, sending, sent, cancelled)
12
+ * @param type $orderby (name, cdate, total, opened, openedratio, clicked, clickedratio)
13
+ * @param type $offset
14
+ * @param type $limit
15
+ * @param type $search
16
+ * @return array
17
+ * {
18
+ * "campaign": [
19
+ * {
20
+ * "campaign_id",
21
+ * "name",
22
+ * "cdate",
23
+ * "mdate",
24
+ * "autocreated",
25
+ * "state",
26
+ * "body_html",
27
+ * "schedule",
28
+ * "archived"
29
+ * },
30
+ * ...
31
+ * ],
32
+ * "total"
33
+ * }
34
+ */
35
+ public function get($filter = 'all', $orderby = 'cdate', $offset = 0, $limit = 25, $search = null) {
36
+
37
+ $params = ['filter' => $filter, 'orderby' => $orderby, 'offset' => $offset, 'limit' => $limit, 'search' => $search];
38
+ return $this->master->request('/campaigns', 'GET', $params);
39
+ }
40
+
41
+ /**
42
+ *
43
+ * @param array $options
44
+ * @return array
45
+ *
46
+ */
47
+ public function create($options = array()) {
48
+
49
+ return $this->master->request('/campaigns', 'POST', $options);
50
+ }
51
+
52
+ /**
53
+ * Get campaign details (body is not sent here)
54
+ * @param int $campaign_id
55
+ * @return array
56
+ * {
57
+ * "campaign": {
58
+ * "campaign_id",
59
+ * "name",
60
+ * "cdate",
61
+ * "mdate",
62
+ * "autocreated",
63
+ * "subject",
64
+ * "sender_name",
65
+ * "replyto",
66
+ * "schedule",
67
+ * "state",
68
+ * "archived",
69
+ * "contactlist_id",
70
+ * "segment_id",
71
+ * "ga_tracking",
72
+ * "personalize_to",
73
+ * "contactlist_name",
74
+ * "sender_email"
75
+ * }
76
+ * }
77
+ */
78
+ public function details($campaign_id) {
79
+
80
+ return $this->master->request('/campaigns/' . $campaign_id, 'GET');
81
+ }
82
+
83
+ /**
84
+ * Update campaign
85
+ * @param int $campaign_id
86
+ * @param array $data
87
+ * @return array
88
+ * {
89
+ * "status"
90
+ * }
91
+ */
92
+ public function update($campaign_id, $data = array()) {
93
+
94
+ return $this->master->request('/campaigns/' . $campaign_id, 'POST', $data);
95
+ }
96
+
97
+ /**
98
+ * schedule campaign
99
+ * @param int $campaign_id
100
+ * @param date $date
101
+ * @return array
102
+ * {
103
+ * "status"
104
+ * }
105
+ */
106
+ public function schedule($campaign_id, $date = "") {
107
+
108
+ $params = ['date' => $date];
109
+ return $this->master->request('/campaigns/schedule/' . $campaign_id, 'POST', $params);
110
+ }
111
+
112
+ /**
113
+ * unschedule campaign
114
+ * @param int $campaign_id
115
+ * @return array
116
+ * {
117
+ * "status"
118
+ * }
119
+ */
120
+ public function unschedule($campaign_id) {
121
+
122
+ return $this->master->request('/campaigns/schedule/' . $campaign_id, 'DELETE');
123
+ }
124
+
125
+ /**
126
+ * send test email
127
+ * @param int $campaign_id
128
+ * @param string $addresses
129
+ * @return array
130
+ * {
131
+ * "status"
132
+ * }
133
+ */
134
+ public function test($campaign_id, $addresses = "") {
135
+
136
+ $params = ['addresses' => $addresses];
137
+ return $this->master->request('/campaigns/test/' . $campaign_id, 'POST', $params);
138
+ }
139
+
140
+ /**
141
+ * send campaign
142
+ * @param int $campaign_id
143
+ * @return array
144
+ * {
145
+ * "status"
146
+ * }
147
+ */
148
+ public function send($campaign_id) {
149
+
150
+ return $this->master->request('/campaigns/send/' . $campaign_id, 'POST');
151
+ }
152
+
153
+ /**
154
+ * archive campaign
155
+ * @param int $campaign_id
156
+ * @return array
157
+ * {
158
+ * "status"
159
+ * }
160
+ */
161
+ public function archive($campaign_id) {
162
+
163
+ return $this->master->request('/campaigns/archive/' . $campaign_id, 'POST');
164
+ }
165
+
166
+ /**
167
+ * unarchive campaign
168
+ * @param int $campaign_id
169
+ * @return array
170
+ * {
171
+ * "status"
172
+ * }
173
+ */
174
+ public function unarchive($campaign_id) {
175
+
176
+ return $this->master->request('/campaigns/archive/' . $campaign_id, 'DELETE');
177
+ }
178
+
179
+ /**
180
+ * check if campaign is ready for sending
181
+ * @param int $campaign_id
182
+ * @return array
183
+ * {
184
+ * "status"
185
+ * }
186
+ */
187
+ public function ready($campaign_id) {
188
+
189
+ return $this->master->request('/campaigns/ready/' . $campaign_id, 'GET');
190
+ }
191
+
192
+ /**
193
+ * duplicate campaign
194
+ * @param int $campaign_id
195
+ * @return array
196
+ * {
197
+ * "status",
198
+ * "new_id"
199
+ * }
200
+ */
201
+ public function duplicate($campaign_id) {
202
+
203
+ return $this->master->request('/campaigns/duplicate/' . $campaign_id, 'POST');
204
+ }
205
+
206
+ /**
207
+ * get campaign html and text content
208
+ * @param int $campaign_id
209
+ * @return array
210
+ * {
211
+ * "source": {
212
+ * "body_text",
213
+ * "body_html"
214
+ * }
215
+ * }
216
+ */
217
+ public function content($campaign_id) {
218
+
219
+ return $this->master->request('/campaigns/content/' . $campaign_id, 'GET');
220
+ }
221
+
222
+ }
lib/SendmachineApi/library/Lists.php ADDED
@@ -0,0 +1,276 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Lists {
4
+
5
+ public function __construct(SendmachineApiClient $master) {
6
+ $this->master = $master;
7
+ }
8
+
9
+ /**
10
+ * get all contact lists
11
+ * @param string $limit
12
+ * @param string $offset
13
+ * @return array
14
+ * {
15
+ * "contactlists": [
16
+ * {
17
+ * "list_id",
18
+ * "name",
19
+ * "lastsenttolist",
20
+ * "state",
21
+ * "subscribed",
22
+ * "unsubscribed",
23
+ * "cleaned",
24
+ * "total"
25
+ * },
26
+ * ...
27
+ * ],
28
+ * "total"
29
+ * }
30
+ */
31
+ public function get($limit = 25, $offset = 0) {
32
+
33
+ $params = ['limit' => $limit, 'offset' => $offset];
34
+ return $this->master->request('/list', 'GET', $params);
35
+ }
36
+
37
+ /**
38
+ * Get list recpipients
39
+ * @param string $list_id
40
+ * @param int $limit
41
+ * @param int $offset
42
+ * @param string $filter (all, subscribed, unsubscribed, cleaned)
43
+ * @param string $order_by (email, added, lastmod)
44
+ * @param int $segment_id
45
+ * @return array
46
+ * {
47
+ * "contacts": [
48
+ * {
49
+ * "email",
50
+ * "status",
51
+ * "added",
52
+ * "lastmod"",
53
+ * "rating",
54
+ * "macros"
55
+ * },
56
+ * ...
57
+ * ],
58
+ * "total"
59
+ * "twostep"
60
+ * }
61
+ */
62
+ public function recipients($list_id, $limit = 25, $offset = 0, $filter = 'all', $order_by = 'email', $segment_id = 0) {
63
+
64
+ $params = ['limit' => $limit, 'offset' => $offset, 'filter' => $filter, 'orderby' => $order_by, 'sid' => $segment_id];
65
+ return $this->master->request('/list/' . $list_id, 'GET', $params);
66
+ }
67
+
68
+ /**
69
+ * get list details
70
+ * @param string $list_id
71
+ * @return array
72
+ * {
73
+ * "list_id",
74
+ * "list_hash",
75
+ * "name",
76
+ * "cdate",
77
+ * "mdate",
78
+ * "lastsenttolist",
79
+ * "state",
80
+ * "subscribed",
81
+ * "unsubscribed",
82
+ * "cleaned",
83
+ * "send_goodbye",
84
+ * "alias"",
85
+ * "default_from_name",
86
+ * "default_from_email",
87
+ * "company",
88
+ * "address": {
89
+ * "address",
90
+ * "city",
91
+ * "country",
92
+ * "zip_code"
93
+ * },
94
+ * "phone",
95
+ * "subscription_reminder",
96
+ * "default_subject",
97
+ * "website",
98
+ * "twostep"
99
+ * }
100
+ */
101
+ public function details($list_id){
102
+
103
+ return $this->master->request('/list/'.$list_id.'/details', 'GET');
104
+ }
105
+
106
+ /**
107
+ * Create a new contact list
108
+ * @param array $data
109
+ * {
110
+ * "website",
111
+ * "default_from_name",
112
+ * "default_from_email",
113
+ * "address" => {
114
+ * "zip_code",
115
+ * "country",
116
+ * "city",
117
+ * "address"
118
+ * },
119
+ * "phone",
120
+ * "name",
121
+ * "subscription_reminder",
122
+ * "company" ,
123
+ * "send_goodbye",
124
+ * "default_subject"
125
+ * }
126
+ * @return array
127
+ * {
128
+ * "status",
129
+ * "id"
130
+ * }
131
+ */
132
+ public function create($data) {
133
+
134
+ $params = ['list_details' => $data];
135
+ return $this->master->request('/list', 'POST', $params);
136
+ }
137
+
138
+ /**
139
+ * manage contacts from list
140
+ * @param string $list_id
141
+ * @param string $emails
142
+ * @param string $action (subscribe, unsubscribe)
143
+ * @param string $list_name
144
+ * @return array
145
+ * {
146
+ * "status",
147
+ * "columns"
148
+ * }
149
+ */
150
+ public function manage_contacts($list_id, $emails = "", $action = 'subscribe', $list_name = null) {
151
+
152
+ $params = ['contacts' => $emails, 'action' => $action, 'name' => $list_name];
153
+ return $this->master->request('/list/' . $list_id, 'POST', $params);
154
+ }
155
+
156
+ /**
157
+ *
158
+ * @param string $list_id
159
+ * @param string $email
160
+ * @param array $data
161
+ * @return array
162
+ * {
163
+ * "status",
164
+ * "columns"
165
+ * }
166
+ */
167
+ public function manage_contact($list_id, $email, $data){
168
+
169
+ return $this->master->request('/list/' . $list_id.'/rcpt/'.$email, 'POST', $data);
170
+ }
171
+
172
+ /**
173
+ *
174
+ * @param string $list_id
175
+ * @param string $email
176
+ * @return array
177
+ * {
178
+ * "contacts": [
179
+ * {
180
+ * "email",
181
+ * "status",
182
+ * "added",
183
+ * "rating",
184
+ * "macros"
185
+ * }
186
+ * ]
187
+ * }
188
+ */
189
+ public function contact_details($list_id, $email){
190
+
191
+ return $this->master->request('/list/' . $list_id.'/rcpt/'.$email, 'GET');
192
+ }
193
+
194
+ /**
195
+ * edit contactlist details
196
+ * @param string $list_id
197
+ * @param array $data
198
+ * @return array
199
+ * {
200
+ * "status"
201
+ * }
202
+ */
203
+ public function edit($list_id, $data){
204
+
205
+ $params = ['list_details' => $data];
206
+ return $this->master->request('/list/'.$list_id.'/details', 'POST', $params);
207
+ }
208
+
209
+ /**
210
+ * Delete a contact list
211
+ * @param string $list_id
212
+ * @return array
213
+ * {
214
+ * "status"
215
+ * }
216
+ */
217
+ public function delete($list_id) {
218
+
219
+ return $this->master->request('/list/' . $list_id, 'DELETE');
220
+ }
221
+
222
+ /**
223
+ * List segments from any given contact list
224
+ * @param string $list_id
225
+ * @param int $limit
226
+ * @param int $offset
227
+ * @param string $orderby (adate, name)
228
+ * @param string $sort (desc, asc)
229
+ * @return array
230
+ * {
231
+ * "segment_list": [
232
+ * {
233
+ * "segment_id",
234
+ * "contactlist_id",
235
+ * "name",
236
+ * "state",
237
+ * "type",
238
+ * "adate",
239
+ * "mdate",
240
+ * "lastsenttosegment"
241
+ * },
242
+ * ...
243
+ * ],
244
+ * "total"
245
+ * }
246
+ */
247
+ public function list_segments($list_id, $limit = 25, $offset = 0, $orderby = "adate", $sort = "desc") {
248
+
249
+ $params = ['limit' => $limit, 'offset' => $offset, 'orderby' => $orderby, 'sort' => $sort];
250
+ return $this->master->request('/list/'.$list_id.'/segment', 'GET', $params);
251
+ }
252
+
253
+ /**
254
+ * Get contact list's fields
255
+ * @param int $list_id
256
+ * @return array
257
+ * {
258
+ * "custom_fields": [
259
+ * {
260
+ * "name",
261
+ * "form_name",
262
+ * "visible",
263
+ * "required",
264
+ * "cf_type",
265
+ * "options"
266
+ * }
267
+ * ]
268
+ * }
269
+ */
270
+ public function custom_fields($list_id){
271
+ return $this->master->request('/list/'.$list_id.'/custom_fields', 'GET');
272
+ }
273
+
274
+ }
275
+
276
+ class Sendmachine_Lists_Exception extends Sendmachine_Error{}
lib/SendmachineApi/library/Sender.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Sender {
4
+
5
+ public function __construct(SendmachineApiClient $master) {
6
+ $this->master = $master;
7
+ }
8
+
9
+ /**
10
+ * get sender list
11
+ * @param string $status (active, pending, active+pending, all)
12
+ * @param string $type (email, domain, all)
13
+ * @param string $group (none, domain, flat)
14
+ * @param int $limit
15
+ * @param int $offset
16
+ * @return array
17
+ * {
18
+ * "senderlist": [
19
+ * {
20
+ * "email",
21
+ * "type",
22
+ * "emailtype",
23
+ * "status",
24
+ * "label"
25
+ * },
26
+ * ...
27
+ * ],
28
+ * "total"
29
+ * }
30
+ */
31
+ public function get($status = 'active', $type = 'email', $group = null, $limit = null, $offset = null) {
32
+
33
+ $params = ['status' => $status, 'type' => $type, 'group' => $group, 'limit' => $limit, 'offset' => $offset];
34
+ return $this->master->request('/sender', 'GET', $params);
35
+ }
36
+
37
+ /**
38
+ * add a new sender
39
+ * @param string $email
40
+ * @return array
41
+ * {
42
+ * "sender": {
43
+ * "address",
44
+ * "type"
45
+ * },
46
+ * "status"
47
+ * }
48
+ */
49
+ public function add($email) {
50
+
51
+ $params = ['type' => 'email', 'address' => $email];
52
+ return $this->master->request('/sender', 'POST', $params);
53
+ }
54
+
55
+ /**
56
+ * delete sender by email address
57
+ * @param type $sender_email
58
+ * @return array
59
+ * {
60
+ * "status"
61
+ * }
62
+ */
63
+ public function delete($sender_email){
64
+
65
+ return $this->master->request('/sender/'.$sender_email, 'DELETE');
66
+ }
67
+
68
+ }
lib/SendmachineApi/library/Templates.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Templates {
4
+
5
+ public function __construct(SendmachineApiClient $master) {
6
+ $this->master = $master;
7
+ }
8
+
9
+ /**
10
+ * get templates
11
+ * @param int $limit
12
+ * @param int $offset
13
+ * @return array
14
+ * {
15
+ * "list": [
16
+ * {
17
+ * "tpl_id",
18
+ * "name",
19
+ * "date",
20
+ * "mdate"
21
+ * },
22
+ * ...
23
+ * ],
24
+ * "total"
25
+ * }
26
+ */
27
+ public function get($limit = 25, $offset = 0) {
28
+
29
+ $params = ['limit' => $limit, 'offset' => $offset];
30
+ return $this->master->request('/templates', 'GET', $params);
31
+ }
32
+
33
+ /**
34
+ * Get a single template
35
+ * @param int $template_id
36
+ * @return array
37
+ * {
38
+ * "body",
39
+ * "id",
40
+ * "name"
41
+ * }
42
+ */
43
+ public function details($template_id) {
44
+
45
+ return $this->master->request('/templates/' . $template_id, 'GET');
46
+ }
47
+
48
+ /**
49
+ * Create a new template
50
+ * @param string $name
51
+ * @param string $body
52
+ * @return array
53
+ * {
54
+ * "status"
55
+ * }
56
+ */
57
+ public function create($name, $body = "") {
58
+
59
+ $params = ['name' => $name, 'body' => $body];
60
+ return $this->master->request('/templates', 'POST', $params);
61
+ }
62
+
63
+ /**
64
+ * edit template body
65
+ * @param int $template_id
66
+ * @param string $body
67
+ * @return array
68
+ * {
69
+ * "status"
70
+ * }
71
+ */
72
+ public function update($template_id, $body = "") {
73
+
74
+ $params = ['body' => $body];
75
+ return $this->master->request('/templates/' . $template_id, 'POST', $params);
76
+ }
77
+
78
+ /**
79
+ * Delete a template
80
+ * @param int $template_id
81
+ * @return array
82
+ * {
83
+ * "status"
84
+ * }
85
+ */
86
+ public function delete($template_id) {
87
+
88
+ return $this->master->request('/templates/' . $template_id, 'DELETE');
89
+ }
90
+
91
+ }
package.xml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>sendmachine</name>
4
+ <version>1.0.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://www.opensource.org/licenses/osl-3.0.php">OSL</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Official Sendmachine plugin featuring subscribe popup, users sync, email sending and transactional campaigns.</summary>
10
+ <description>Sendmachine's official plugin will enable you to:&#xD;
11
+ &#xD;
12
+ Subscribe Popup&#xD;
13
+ After you've successfully connected to the extension (using your sendmachine API credentials) you can configure a subscribe popup modal to allow your customers to easily subscribe to one of your contact lists.&#xD;
14
+ &#xD;
15
+ Import/Export subscribers&#xD;
16
+ You want to send emails to all your users but don't know how? Well, don't worry, we can help you with that. After you've successfully selected a contact list, you can use the "Export to sendmachine" button, to export all your subscribers to your sendmachine account in the selected contact list. If you want to send a campaign from your magento store, there's an "Import to newsletter" button that imports all your sendmachine subscribers (from the selected list) to your magento newsletter subscribers tab. &#xD;
17
+ If you have multiple stores you can import/export subscribers to a specific store instead of all.&#xD;
18
+ &#xD;
19
+ Send emails through our services&#xD;
20
+ No need for nasty, geeky configurations. Just insert your API credentials and you are good to go. Also, make sure that "enable email sending" is set to on.&#xD;
21
+ If you set a from email that doesn't already exist in your sendmachine account as a sender address, a confirmation email will be generated and sent to that address.&#xD;
22
+ Not quite sure if you've done everything right? You can test if everything is ok by sending a test email. If you got the mail, you can sit back and relax: you've done it, otherwise something went wrong.&#xD;
23
+ &#xD;
24
+ Send transactional emails&#xD;
25
+ Using our services you can now monitor an email's activity (opens, clicks, geolocations, user agents). In order to enable this option, after you install our plugin, go to "email" tab, set "Use transactional emails" to "yes" and mark the email areas that you want you want to be transactional and that's it.</description>
26
+ <notes>Fist stable release.</notes>
27
+ <authors><author><name>Sendmachine Team</name><user>sendmachine</user><email>support@sendmachine.com</email></author></authors>
28
+ <date>2015-09-08</date>
29
+ <time>07:50:07</time>
30
+ <contents><target name="magecommunity"><dir name="Sendmachine"><dir name="Sendmachine"><dir name="Block"><dir name="AppContainer"><file name="Grid.php" hash="7a5feeb317e4859197140ee06d218039"/><file name="Main.php" hash="72bfae321e391f0f6c9534b2c2cf5bdb"/><dir name="Tab"><file name="Email.php" hash="97760a4c62225f6a8a977b5c2a1c60ea"/><file name="General.php" hash="10465b7692811b4ae467e827bfd27183"/><file name="Lists.php" hash="c65b5bb6ee523f65513d5316fd66518e"/></dir><file name="Tabs.php" hash="13507bb6578e80fec5084726b96acf07"/></dir><file name="PopupBlock.php" hash="7e42dab9ba8bef6bffdf8e496a64b3e4"/></dir><dir name="Helper"><file name="Data.php" hash="3e54639ada6047e12827df7be1b02746"/></dir><dir name="Model"><file name="Cronjobs.php" hash="fd431a87859a56f562937e8487e655ba"/><dir name="Email"><file name="Queue.php" hash="565cf2bee7c364027bd853ccac13a0c8"/><file name="Template.php" hash="15cbff0acaff99e9daa13cf9df4239e0"/></dir><dir name="Mysql4"><dir name="Sendmachine"><file name="Collection.php" hash="9308e4f5e4cc12f76028b3401ed76c58"/></dir><file name="Sendmachine.php" hash="70d59dd115baa6d9e6d7f398508eeb95"/></dir><file name="Observer.php" hash="fd7177c751474337a56cbdd9c731beda"/><file name="Sendmachine.php" hash="50f3f9b43e654eb4354f584aef15839b"/><dir name="Source"><file name="Contactlist.php" hash="7cb8e66b769da607a311dffba12304b3"/><file name="ImportExportLimit.php" hash="701b16f0f58ad1865b09efde615e3cf0"/><file name="Smtp.php" hash="041e6f75734ff963531f8ab979f3f0f4"/><file name="TransactionalCampAreas.php" hash="ddacac0ea340ce06ccf1b02b282d69b2"/></dir><file name="...Observer.php" hash="760b42e52cdf87ef65f109128f95a24e"/></dir><dir name="controllers"><file name="SendmachineController.php" hash="cae0cfaad4e26a6bb3b38e5cdd72e8e0"/><file name="SubscribeController.php" hash="7d56a808e79c2b6cf7bf45d7a8178f78"/></dir><dir name="etc"><file name="adminhtml.xml" hash="2b9bc07f400202cbf4a92e4256319d28"/><file name="config.xml" hash="f4b1d6844da04e5f8eec790b5e02fc4d"/></dir><dir name="sql"><dir name="sendmachine_setup"><file name="mysql4-install-1.0.0.php" hash="5e5132b88f61df798c61284e98938230"/></dir></dir></dir></dir></target><target name="magelib"><dir name="SendmachineApi"><file name="README.md" hash="4f3be41975112c7b0e2d1b420362ca88"/><file name="SendmachineApiClient.php" hash="9990716a4159b2f57c91637126a0993e"/><file name="composer.json" hash="14472d29d81169ec0865135d75ceda44"/><dir name="library"><file name="Account.php" hash="d385b9bf2c6ab2cfe59224376b6e5ddd"/><file name="Campaigns.php" hash="675639e847d88e22d5ecfc23d9b931ed"/><file name="Lists.php" hash="be9f6d9dbb9be2948cc1c562063c2b28"/><file name="Sender.php" hash="c776b61c527ceadb1779c95c66e5cdb9"/><file name="Templates.php" hash="44b181d899bdf444a9ea66b95f648557"/></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="sendmachine"><file name="logo.png" hash="3ded087eb9efd7c6bdcaade0fec6f9e5"/><file name="logo2.png" hash="d0cdd8f8688b086dbba5dd7ce774e912"/><file name="logo3.png" hash="5c367ffbe7a6422668b3c0fa503a60fb"/></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="sendmachine"><file name="frontend.css" hash="d02fbf9fe0d145c7a9e8d59a91b7055d"/><file name="frontend.js" hash="ca7ca5de929041908f263f68ade035bf"/><file name="loading.gif" hash="3fce1e41ae8b01675553928349770faa"/></dir></dir></dir></dir></target><target name="mageweb"><dir name="js"><dir name="sendmachine"><file name="admin.js" hash="a6c7e0e797f4a996c469c4f32ee26988"/></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Sendmachine_Sendmachine.xml" hash="8378d3fff65502b2677cb5439af9a091"/></dir></target><target name="magelocale"><dir name="en_US"><file name="Sendmachine_Sendmachine.csv" hash="bdfdd5fda92cf52a1e9c07801f7b2a64"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="sendmachine.xml" hash="111176ded682edb4732351af44f2fa66"/></dir><dir name="template"><dir name="sendmachine"><file name="popup.phtml" hash="456a82301ee6d038a4964ab857645d6b"/></dir></dir></dir></dir></dir></target></contents>
31
+ <compatible/>
32
+ <dependencies><required><php><min>5.0.0</min><max>5.6.13</max></php><extension><name>curl</name><min/><max/></extension></required></dependencies>
33
+ </package>
skin/adminhtml/default/default/sendmachine/logo.png ADDED
Binary file
skin/adminhtml/default/default/sendmachine/logo2.png ADDED
Binary file
skin/adminhtml/default/default/sendmachine/logo3.png ADDED
Binary file
skin/frontend/base/default/sendmachine/frontend.css ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #sm_popup_box_wrapper{
2
+ font-size: 14px;
3
+ position:fixed;
4
+ top:0;
5
+ left:0;
6
+ width:100%;
7
+ height:100%;
8
+ background:rgba(0, 0, 0, .5);
9
+ visibility:hidden;
10
+ filter: alpha(opacity=0);
11
+ opacity: 0;
12
+ -webkit-transition: opacity .30s ease-in-out;
13
+ -moz-transition: opacity .30s ease-in-out;
14
+ -ms-transition: opacity .30s ease-in-out;
15
+ -o-transition: opacity .30s ease-in-out;
16
+ transition: opacity .30s ease-in-out;
17
+ }
18
+ #sm_popup_box_wrapper #sm_popup_box_table{
19
+ width:100%;
20
+ height:100%;
21
+ }
22
+ #sm_popup_box_wrapper #sm_popup_box_inner{
23
+ background-color:white;
24
+ padding:10px;
25
+ width:40%;
26
+ margin:auto;
27
+ min-width:300px;
28
+ margin-bottom:100px;
29
+ position:relative;
30
+ }
31
+ #sm_popup_box_wrapper #sm_popup_box_main{
32
+ margin-bottom:20px;
33
+ }
34
+ #sm_popup_box_wrapper #sm_popup_box_description{
35
+ margin:10px 0;
36
+ }
37
+ #sm_popup_box_wrapper #sm_popup_box_close_button{
38
+ float:right;
39
+ background-color:black;
40
+ border:none;
41
+ padding:5px;
42
+ color:white;
43
+ }
44
+ #sm_popup_box_wrapper #sm_popup_box_submit_button{
45
+ padding:5px 8px;
46
+ background-color: #E6E6E6;
47
+ border: 1px solid grey;
48
+ }
49
+ #sm_popup_box_wrapper #sm_popup_box_loader{
50
+ display:none;
51
+ position:absolute;
52
+ top:0;
53
+ left:0;
54
+ width:100%;
55
+ height:100%;
56
+ background:rgba(255,255,255,0.7);
57
+ background-image:url('./loading.gif');
58
+ background-repeat:no-repeat;
59
+ background-position:center;
60
+ background-size:100px;
61
+ }
62
+ #sm_popup_box_wrapper #sm_popup_box_notification_area{
63
+ margin:10px 0;
64
+ }
65
+ #sm_popup_box_wrapper #sm_popup_box_notification_area #sm_popup_box_notification_success{
66
+ background-color: #dff0d8;
67
+ color: #484848;
68
+ padding: 8px;
69
+ border-radius: 3px;
70
+ }
71
+ #sm_popup_box_wrapper #sm_popup_box_notification_area #sm_popup_box_notification_error{
72
+ background-color: #f8d0c8;
73
+ color: #484848;
74
+ padding: 8px;
75
+ border-radius: 3px;
76
+ }
skin/frontend/base/default/sendmachine/frontend.js ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var smSubscribeHasActivity = false;
2
+
3
+ function smDisplayPopup(popupDelay) {
4
+
5
+ setTimeout(function () {
6
+ document.getElementById('sm_popup_box_wrapper').style.visibility = 'visible';
7
+ document.getElementById('sm_popup_box_wrapper').style.opacity = 1;
8
+ }, popupDelay);
9
+ }
10
+
11
+ function smDismissNoActivity(di) {
12
+
13
+ if (di) {
14
+ setTimeout(function () {
15
+ if (!smSubscribeHasActivity)
16
+ smDismissPopup();
17
+ }, di*1000);
18
+ }
19
+ }
20
+
21
+ function smDismissPopup() {
22
+
23
+ document.getElementById('sm_popup_box_wrapper').style.opacity = 0;
24
+
25
+ setTimeout(function () {
26
+ document.getElementById('sm_popup_box_wrapper').style.display = 'none';
27
+ document.getElementById('sm_popup_box_wrapper').style.visibility = 'hidden';
28
+ }, 300);
29
+ }
30
+
31
+ function smStopEventPropagation() {
32
+
33
+ if (event.stopPropagation) {
34
+ event.stopPropagation();
35
+ }
36
+ event.cancelBubble = true;
37
+ }
38
+
39
+ function smSubscribeCustomer(el, dismissSuccess) {
40
+
41
+ var request_params = {};
42
+
43
+ for (var i = 0; i < el.elements.length; i++) {
44
+
45
+ if (el.elements[i].name) {
46
+ request_params[el.elements[i].name] = [el.elements[i].value];
47
+ }
48
+ }
49
+
50
+ document.getElementById('sm_popup_box_loader').style.display = 'block';
51
+
52
+ new Ajax.Request(el.action, {
53
+ requestHeaders: {Accept: 'application/json'},
54
+ method: 'post',
55
+ parameters: request_params,
56
+ onSuccess: function (response) {
57
+
58
+ document.getElementById('sm_popup_box_loader').style.display = 'none';
59
+ var resp = response.responseText.evalJSON(true);
60
+
61
+ if (resp.code === 1) {
62
+ el.reset();
63
+ document.getElementById('sm_popup_box_notification_area').innerHTML = "<div id='sm_popup_box_notification_success' >" + resp.message + "</div>";
64
+ if (dismissSuccess) {
65
+ setTimeout(function () {
66
+ smDismissPopup();
67
+ }, dismissSuccess*1000);
68
+ }
69
+ }
70
+ else {
71
+ document.getElementById('sm_popup_box_notification_area').innerHTML = "<div id='sm_popup_box_notification_error' >" + resp.message + "</div>";
72
+ }
73
+ },
74
+ onError: function () {
75
+
76
+ document.getElementById('sm_popup_box_loader').style.display = 'none';
77
+ document.getElementById('sm_popup_box_notification_area').innerHTML = "<div id='sm_popup_box_notification_error' >Something went wrong.You were not subscribed</div>";
78
+ }
79
+ });
80
+
81
+ return false;
82
+ }
skin/frontend/base/default/sendmachine/loading.gif ADDED
Binary file