ActiveCampaign_Subscriptions - Version 1.5.0

Version Notes

Added Forms selector, so you can control how subscribers receive Opt-in messages.

Also removed the "Reset" and "Delete Connection" buttons, as they are not necessary (you can use "Enabled" or "Disabled" instead).

Download this release

Release Info

Developer ActiveCampaign, Inc.
Extension ActiveCampaign_Subscriptions
Version 1.5.0
Comparing to
See all releases


Code changes from version 1.0.2 to 1.5.0

app/code/community/ActiveCampaign/Subscriptions/Block/Adminhtml/Subscriptions.php CHANGED
@@ -1,4 +1,5 @@
1
  <?php
 
2
  class ActiveCampaign_Subscriptions_Block_Adminhtml_Subscriptions extends Mage_Adminhtml_Block_Widget_Grid_Container
3
  {
4
  public function __construct()
1
  <?php
2
+
3
  class ActiveCampaign_Subscriptions_Block_Adminhtml_Subscriptions extends Mage_Adminhtml_Block_Widget_Grid_Container
4
  {
5
  public function __construct()
app/code/community/ActiveCampaign/Subscriptions/Block/Adminhtml/Subscriptions/Edit.php CHANGED
@@ -11,8 +11,13 @@ class ActiveCampaign_Subscriptions_Block_Adminhtml_Subscriptions_Edit extends Ma
11
  $this->_controller = 'adminhtml_subscriptions';
12
 
13
  $this->_updateButton('save', 'label', Mage::helper('subscriptions')->__('Save Connection'));
 
14
  $this->_updateButton('delete', 'label', Mage::helper('subscriptions')->__('Delete Connection'));
15
 
 
 
 
 
16
  $this->_addButton('saveandcontinue', array(
17
  'label' => Mage::helper('adminhtml')->__('Save And Continue Edit'),
18
  'onclick' => 'saveAndContinueEdit()',
11
  $this->_controller = 'adminhtml_subscriptions';
12
 
13
  $this->_updateButton('save', 'label', Mage::helper('subscriptions')->__('Save Connection'));
14
+
15
  $this->_updateButton('delete', 'label', Mage::helper('subscriptions')->__('Delete Connection'));
16
 
17
+ // hide these buttons
18
+ $this->_updateButton('delete', 'style', 'display: none;');
19
+ $this->_updateButton('reset', 'style', 'display: none;');
20
+
21
  $this->_addButton('saveandcontinue', array(
22
  'label' => Mage::helper('adminhtml')->__('Save And Continue Edit'),
23
  'onclick' => 'saveAndContinueEdit()',
app/code/community/ActiveCampaign/Subscriptions/Block/Adminhtml/Subscriptions/Edit/Tab/Form.php ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class ActiveCampaign_Subscriptions_Block_Adminhtml_Subscriptions_Edit_Tab_Form extends Mage_Adminhtml_Block_Widget_Form
4
+ {
5
+ protected function dbg($var, $continue = 0, $element = "pre")
6
+ {
7
+ echo "<" . $element . ">";
8
+ echo "Vartype: " . gettype($var) . "\n";
9
+ if ( is_array($var) )
10
+ {
11
+ echo "Elements: " . count($var) . "\n\n";
12
+ }
13
+ elseif ( is_string($var) )
14
+ {
15
+ echo "Length: " . strlen($var) . "\n\n";
16
+ }
17
+ print_r($var);
18
+ echo "</" . $element . ">";
19
+ if (!$continue) exit();
20
+ }
21
+
22
+ protected function connection_data($connection_data) {
23
+
24
+ $api_url = $api_key = $list_value = "";
25
+ $list_ids = array();
26
+ $form_id = 0;
27
+
28
+ //$this->dbg($connection_data);
29
+
30
+ foreach ($connection_data as $connection) {
31
+ // find first one that is enabled
32
+ $api_url = $connection["api_url"];
33
+ $api_key = $connection["api_key"];
34
+
35
+ $list_value = $connection["list_value"];
36
+ if ($list_value) {
37
+ // example for single list saved: ["mthommes6.activehosted.com-13"]
38
+ // example for multiple lists saved: ["mthommes6.activehosted.com-5","mthommes6.activehosted.com-13"]
39
+ $list_values = json_decode($list_value);
40
+ foreach ($list_values as $acct_listid) {
41
+ // IE: mthommes6.activehosted.com-13
42
+ $acct_listid = explode("-", $acct_listid);
43
+ $list_ids[] = (int)$acct_listid[1];
44
+ }
45
+ }
46
+
47
+ $form_value = trim($connection["form_value"], "\"");
48
+ if ($form_value) {
49
+ // example form saved: "mthommes6.activehosted.com-1269"
50
+ $acct_formid = explode("-", $form_value);
51
+ $form_id = (int)$acct_formid[1];
52
+ }
53
+
54
+ break;
55
+ }
56
+
57
+ return array(
58
+ "data" => $connection_data,
59
+ "api_url" => $api_url,
60
+ "api_key" => $api_key,
61
+ "list_ids" => $list_ids,
62
+ "form_id" => $form_id,
63
+ );
64
+ }
65
+
66
+ protected function _prepareForm()
67
+ {
68
+ $magento_form = new Varien_Data_Form();
69
+ $this->setForm($magento_form);
70
+
71
+ $fieldset = $magento_form->addFieldset('subscriptions_form', array('legend'=>Mage::helper('subscriptions')->__('Choose Form (To use Opt-in settings)')));
72
+
73
+ $connection_ = Mage::registry('subscriptions_data')->getData();
74
+ //$this->dbg($connection_,1);
75
+
76
+ $connection = $this->connection_data(array($connection_));
77
+ //$this->dbg($connection);
78
+
79
+ $forms_ = array();
80
+
81
+ $forms_[] = array(
82
+ "value" => $connection_["account_url"] . "-" . "0",
83
+ "label" => Mage::helper('subscriptions')->__("(Optional) Select a form..."),
84
+ );
85
+
86
+ if ($connection) {
87
+
88
+ $api_url = $connection["api_url"];
89
+ $api_key = $connection["api_key"];
90
+
91
+ $ac = new ActiveCampaign($api_url, $api_key);
92
+
93
+ $forms = $ac->api("form/getforms");
94
+ $forms = get_object_vars($forms);
95
+
96
+ foreach ($forms as $k => $form) {
97
+ if (is_int($k)) {
98
+ // avoid "result_code", "result_message", etc items
99
+ $form = get_object_vars($form);
100
+
101
+ $form__ = array(
102
+ "value" => $connection_["account_url"] . "-" . $form["id"],
103
+ "label" => $form["name"],
104
+ );
105
+
106
+ foreach ($form["lists"] as $listid) {
107
+ if (in_array($listid, $connection["list_ids"])) {
108
+ // only add to main array if this form is associated with the list(s) they chose
109
+ $forms_[] = $form__;
110
+ continue(2);
111
+ }
112
+ }
113
+ }
114
+ }
115
+ //$this->dbg($forms_,1);
116
+
117
+ }
118
+
119
+ // hidden field that stores all of the forms from the install (so we can reference data from them later, based on what they choose).
120
+ $fieldset->addField('forms', 'hidden', array(
121
+ 'label' => Mage::helper('subscriptions')->__('Forms'),
122
+ 'name' => 'forms',
123
+ ));
124
+
125
+ $fieldset->addField('form_value', 'select', array(
126
+ 'label' => Mage::helper('subscriptions')->__('Forms'),
127
+ 'name' => 'form_value',
128
+ 'values' => $forms_,
129
+ ));
130
+
131
+ if ( Mage::getSingleton('adminhtml/session')->getSubscriptionsData() ) {
132
+ $data = Mage::getSingleton('adminhtml/session')->getSubscriptionsData();
133
+ Mage::getSingleton('adminhtml/session')->setSubscriptionsData(null);
134
+ }
135
+ elseif ( Mage::registry('subscriptions_data') ) {
136
+ $data = Mage::registry('subscriptions_data')->getData();
137
+ }
138
+
139
+ $data["forms"] = json_encode($forms_);
140
+ $data["form_value"] = json_decode($data["form_value"]);
141
+ $magento_form->setValues($data);
142
+
143
+ return parent::_prepareForm();
144
+
145
+ }
146
+
147
+ }
app/code/community/ActiveCampaign/Subscriptions/Block/Adminhtml/Subscriptions/Edit/Tab/List.php CHANGED
@@ -23,7 +23,7 @@ class ActiveCampaign_Subscriptions_Block_Adminhtml_Subscriptions_Edit_Tab_List e
23
  {
24
  $form = new Varien_Data_Form();
25
  $this->setForm($form);
26
- $fieldset = $form->addFieldset('subscriptions_form', array('legend'=>Mage::helper('subscriptions')->__('Choose Lists')));
27
 
28
  $connection = Mage::registry('subscriptions_data')->getData();
29
  //$this->dbg($connection,1);
23
  {
24
  $form = new Varien_Data_Form();
25
  $this->setForm($form);
26
+ $fieldset = $form->addFieldset('subscriptions_form', array('legend'=>Mage::helper('subscriptions')->__('Choose Lists (To add new customers to)')));
27
 
28
  $connection = Mage::registry('subscriptions_data')->getData();
29
  //$this->dbg($connection,1);
app/code/community/ActiveCampaign/Subscriptions/Block/Adminhtml/Subscriptions/Edit/Tabs.php CHANGED
@@ -25,6 +25,12 @@ class ActiveCampaign_Subscriptions_Block_Adminhtml_Subscriptions_Edit_Tabs exten
25
  'content' => $this->getLayout()->createBlock('subscriptions/adminhtml_subscriptions_edit_tab_list')->toHtml(),
26
  ));
27
 
 
 
 
 
 
 
28
  $this->addTab('form_section_export', array(
29
  'label' => Mage::helper('subscriptions')->__('Export Magento Subscribers'),
30
  'title' => Mage::helper('subscriptions')->__('Export Magento Subscribers'),
25
  'content' => $this->getLayout()->createBlock('subscriptions/adminhtml_subscriptions_edit_tab_list')->toHtml(),
26
  ));
27
 
28
+ $this->addTab('form_section_forms', array(
29
+ 'label' => Mage::helper('subscriptions')->__('Forms'),
30
+ 'title' => Mage::helper('subscriptions')->__('Forms'),
31
+ 'content' => $this->getLayout()->createBlock('subscriptions/adminhtml_subscriptions_edit_tab_form')->toHtml(),
32
+ ));
33
+
34
  $this->addTab('form_section_export', array(
35
  'label' => Mage::helper('subscriptions')->__('Export Magento Subscribers'),
36
  'title' => Mage::helper('subscriptions')->__('Export Magento Subscribers'),
app/code/community/ActiveCampaign/Subscriptions/Block/Subscriptions.php CHANGED
@@ -7,16 +7,15 @@ require_once(Mage::getBaseDir() . "/app/code/community/ActiveCampaign/Subscripti
7
  class ActiveCampaign_Subscriptions_Block_Subscriptions extends Mage_Core_Block_Template
8
  {
9
  public function _prepareLayout()
10
- {
11
  return parent::_prepareLayout();
12
- }
13
 
14
- public function getSubscriptions()
15
- {
16
- if (!$this->hasData('subscriptions')) {
17
- $this->setData('subscriptions', Mage::registry('subscriptions'));
18
- }
19
- return $this->getData('subscriptions');
20
-
21
- }
22
  }
7
  class ActiveCampaign_Subscriptions_Block_Subscriptions extends Mage_Core_Block_Template
8
  {
9
  public function _prepareLayout()
10
+ {
11
  return parent::_prepareLayout();
12
+ }
13
 
14
+ public function getSubscriptions()
15
+ {
16
+ if (!$this->hasData('subscriptions')) {
17
+ $this->setData('subscriptions', Mage::registry('subscriptions'));
18
+ }
19
+ return $this->getData('subscriptions');
20
+ }
 
21
  }
app/code/community/ActiveCampaign/Subscriptions/Model/Observer.php CHANGED
@@ -8,6 +8,13 @@ require_once(Mage::getBaseDir() . "/app/code/community/ActiveCampaign/Subscripti
8
 
9
  class ActiveCampaign_Subscriptions_Model_Observer {
10
 
 
 
 
 
 
 
 
11
  protected function dbg($var, $continue = 0, $element = "pre")
12
  {
13
  echo "<" . $element . ">";
@@ -33,12 +40,14 @@ class ActiveCampaign_Subscriptions_Model_Observer {
33
 
34
  $api_url = $api_key = $list_value = "";
35
  $list_ids = array();
 
36
 
37
  foreach ($connection_data as $connection) {
38
  if ((int)$connection["status"] == 1) {
39
  // find first one that is enabled
40
  $api_url = $connection["api_url"];
41
  $api_key = $connection["api_key"];
 
42
  $list_value = $connection["list_value"];
43
  if ($list_value) {
44
  // example for single list saved: ["mthommes6.activehosted.com-13"]
@@ -50,6 +59,14 @@ class ActiveCampaign_Subscriptions_Model_Observer {
50
  $list_ids[] = (int)$acct_listid[1];
51
  }
52
  }
 
 
 
 
 
 
 
 
53
  break;
54
  }
55
  }
@@ -59,6 +76,7 @@ class ActiveCampaign_Subscriptions_Model_Observer {
59
  "api_url" => $api_url,
60
  "api_key" => $api_key,
61
  "list_ids" => $list_ids,
 
62
  );
63
  }
64
 
@@ -99,6 +117,8 @@ class ActiveCampaign_Subscriptions_Model_Observer {
99
  $subscriber["status[{$list_id}]"] = 1;
100
  }
101
 
 
 
102
  $subscriber_request = $ac->api("subscriber/sync?service=magento", $subscriber);
103
 
104
  if ((int)$subscriber_request->success) {
@@ -115,6 +135,8 @@ class ActiveCampaign_Subscriptions_Model_Observer {
115
 
116
  }
117
 
 
 
118
  }
119
 
120
  public function edit_subscribe(Varien_Event_Observer $observer) {
@@ -152,9 +174,11 @@ class ActiveCampaign_Subscriptions_Model_Observer {
152
  // add lists
153
  foreach ($connection["list_ids"] as $list_id) {
154
  $subscriber["p[{$list_id}]"] = $list_id;
155
- $subscriber["status[{$list_id}]"] = $list_status;
156
  }
157
 
 
 
158
  $subscriber_request = $ac->api("subscriber/sync?service=magento", $subscriber);
159
 
160
  if ((int)$subscriber_request->success) {
@@ -171,6 +195,8 @@ class ActiveCampaign_Subscriptions_Model_Observer {
171
 
172
  }
173
 
 
 
174
  }
175
 
176
  }
8
 
9
  class ActiveCampaign_Subscriptions_Model_Observer {
10
 
11
+ protected function file_append($content) {
12
+ $handle = fopen("/var/www/html/magento/matt.log", "a");
13
+ if ( is_array($content) || is_object($content) ) $content = print_r($content, 1);
14
+ fwrite($handle, "\n" . date("m/d/Y, h:i", strtotime("now")) . ": " . $content);
15
+ fclose($handle);
16
+ }
17
+
18
  protected function dbg($var, $continue = 0, $element = "pre")
19
  {
20
  echo "<" . $element . ">";
40
 
41
  $api_url = $api_key = $list_value = "";
42
  $list_ids = array();
43
+ $form_id = 0;
44
 
45
  foreach ($connection_data as $connection) {
46
  if ((int)$connection["status"] == 1) {
47
  // find first one that is enabled
48
  $api_url = $connection["api_url"];
49
  $api_key = $connection["api_key"];
50
+
51
  $list_value = $connection["list_value"];
52
  if ($list_value) {
53
  // example for single list saved: ["mthommes6.activehosted.com-13"]
59
  $list_ids[] = (int)$acct_listid[1];
60
  }
61
  }
62
+
63
+ $form_value = trim($connection["form_value"], "\"");
64
+ if ($form_value) {
65
+ // example form saved: "mthommes6.activehosted.com-1269"
66
+ $acct_formid = explode("-", $form_value);
67
+ $form_id = (int)$acct_formid[1];
68
+ }
69
+
70
  break;
71
  }
72
  }
76
  "api_url" => $api_url,
77
  "api_key" => $api_key,
78
  "list_ids" => $list_ids,
79
+ "form_id" => $form_id,
80
  );
81
  }
82
 
117
  $subscriber["status[{$list_id}]"] = 1;
118
  }
119
 
120
+ $subscriber["form"] = $connection["form_id"];
121
+
122
  $subscriber_request = $ac->api("subscriber/sync?service=magento", $subscriber);
123
 
124
  if ((int)$subscriber_request->success) {
135
 
136
  }
137
 
138
+ return;
139
+
140
  }
141
 
142
  public function edit_subscribe(Varien_Event_Observer $observer) {
174
  // add lists
175
  foreach ($connection["list_ids"] as $list_id) {
176
  $subscriber["p[{$list_id}]"] = $list_id;
177
+ $subscriber["status[{$list_id}]"] = 1;
178
  }
179
 
180
+ $subscriber["form"] = $connection["form_id"];
181
+
182
  $subscriber_request = $ac->api("subscriber/sync?service=magento", $subscriber);
183
 
184
  if ((int)$subscriber_request->success) {
195
 
196
  }
197
 
198
+ return;
199
+
200
  }
201
 
202
  }
app/code/community/ActiveCampaign/Subscriptions/activecampaign-api-php/ActiveCampaign.class.php CHANGED
@@ -1,6 +1,6 @@
1
  <?php
2
 
3
- if ( !defined("ACTIVECAMPAIGN_URL") || !defined("ACTIVECAMPAIGN_API_KEY") ) {
4
  include "config.php";
5
  }
6
 
@@ -85,5 +85,6 @@ require_once("List.class.php");
85
  require_once("Message.class.php");
86
  require_once("Subscriber.class.php");
87
  require_once("User.class.php");
 
88
 
89
  ?>
1
  <?php
2
 
3
+ if ( !defined("ACTIVECAMPAIGN_URL") || (!defined("ACTIVECAMPAIGN_API_KEY") && !defined("ACTIVECAMPAIGN_API_USER") && !defined("ACTIVECAMPAIGN_API_PASS")) ) {
4
  include "config.php";
5
  }
6
 
85
  require_once("Message.class.php");
86
  require_once("Subscriber.class.php");
87
  require_once("User.class.php");
88
+ require_once("Webhook.class.php");
89
 
90
  ?>
app/code/community/ActiveCampaign/Subscriptions/activecampaign-api-php/Connector.class.php CHANGED
@@ -1,134 +1,146 @@
1
- <?php
2
-
3
- class AC_Connector {
4
-
5
- public $url;
6
- public $api_key;
7
- public $output = "json";
8
-
9
- function __construct($url, $api_key, $api_user = "", $api_pass = "") {
10
- // $api_pass should be md5() already
11
- $base = "";
12
- if (!preg_match("/https:\/\/www.activecampaign.com/", $url)) {
13
- // not a reseller
14
- $base = "/admin";
15
- }
16
- if (preg_match("/\/$/", $url)) {
17
- // remove trailing slash
18
- $url = substr($url, 0, strlen($url) - 1);
19
- }
20
- if ($api_key) {
21
- $this->url = "{$url}{$base}/api.php?api_key={$api_key}";
22
- }
23
- elseif ($api_user && $api_pass) {
24
- $this->url = "{$url}{$base}/api.php?api_user={$api_user}&api_pass={$api_pass}";
25
- }
26
- $this->api_key = $api_key;
27
- }
28
-
29
- public function credentials_test() {
30
- $test_url = "{$this->url}&api_action=group_view&api_output={$this->output}&id=3";
31
- $r = $this->curl($test_url);
32
- if (is_object($r) && (int)$r->result_code) {
33
- // successful
34
- $r = true;
35
- }
36
- else {
37
- // failed
38
- $r = false;
39
- }
40
- return $r;
41
- }
42
-
43
- public function curl($url, $post_data = array()) {
44
- // find the method from the URL
45
- $method = preg_match("/api_action=[^&]*/i", $url, $matches);
46
- $method = preg_match("/[^=]*$/i", $matches[0], $matches2);
47
- $method = $matches2[0];
48
- $request = curl_init();
49
- curl_setopt($request, CURLOPT_URL, $url);
50
- curl_setopt($request, CURLOPT_HEADER, 0);
51
- curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
52
- if ($post_data) {
53
- curl_setopt($request, CURLOPT_POST, 1);
54
- $data = "";
55
-
56
- if (is_array($post_data)) {
57
- foreach($post_data as $key => $value) {
58
- if (is_array($value)) {
59
-
60
- if (is_int($key)) {
61
- // array two levels deep
62
- foreach ($value as $key_ => $value_) {
63
- if (is_array($value_)) {
64
- foreach ($value_ as $k => $v) {
65
- $k = urlencode($k);
66
- $data .= "{$key_}[{$key}][{$k}]=" . urlencode($v) . "&";
67
- }
68
- }
69
- else {
70
- $data .= "{$key_}[{$key}]=" . urlencode($value_) . "&";
71
- }
72
- }
73
- }
74
- else {
75
- // IE: [group] => array(2 => 2, 3 => 3)
76
- // normally we just want the key to be a string, IE: ["group[2]"] => 2
77
- // but we want to allow passing both formats
78
- foreach ($value as $k => $v) {
79
- $k = urlencode($k);
80
- $data .= "{$key}[{$k}]=" . urlencode($v) . "&";
81
- }
82
- }
83
-
84
- }
85
- else {
86
- $data .= "{$key}=" . urlencode($value) . "&";
87
- }
88
- }
89
- }
90
- else {
91
- // not an array - perhaps serialized or JSON string?
92
- // just pass it as data
93
- $data = "data={$post_data}";
94
- }
95
-
96
- $data = rtrim($data, "& ");
97
- curl_setopt($request, CURLOPT_POSTFIELDS, $data);
98
- }
99
- curl_setopt($request, CURLOPT_SSL_VERIFYPEER, false);
100
- curl_setopt($request, CURLOPT_SSL_VERIFYHOST, 0);
101
- curl_setopt($request, CURLOPT_FOLLOWLOCATION, true);
102
- $response = curl_exec($request);
103
- //dbg($response);
104
- $http_code = curl_getinfo($request, CURLINFO_HTTP_CODE);
105
- curl_close($request);
106
- $object = json_decode($response);
107
- if ( !is_object($object) || (!isset($object->result_code) && !isset($object->succeeded)) ) {
108
- // add methods that only return a string
109
- $string_responses = array("form_html");
110
- if (in_array($method, $string_responses)) {
111
- return $response;
112
- }
113
- // something went wrong
114
- return "There was an error with the API request (code {$http_code}).";
115
- }
116
- if (isset($object->result_code)) {
117
- $object->success = $object->result_code;
118
- if (!(int)$object->result_code) {
119
- $object->error = $object->result_message;
120
- }
121
- }
122
- elseif (isset($object->succeeded)) {
123
- // some calls return "succeeded" only
124
- $object->success = $object->succeeded;
125
- if (!(int)$object->succeeded) {
126
- $object->error = $object->message;
127
- }
128
- }
129
- return $object;
130
- }
131
-
132
- }
133
-
 
 
 
 
 
 
 
 
 
 
 
 
134
  ?>
1
+ <?php
2
+
3
+ class AC_Connector {
4
+
5
+ public $url;
6
+ public $api_key;
7
+ public $output = "json";
8
+
9
+ function __construct($url, $api_key, $api_user = "", $api_pass = "") {
10
+ // $api_pass should be md5() already
11
+ $base = "";
12
+ if (!preg_match("/https:\/\/www.activecampaign.com/", $url)) {
13
+ // not a reseller
14
+ $base = "/admin";
15
+ }
16
+ if (preg_match("/\/$/", $url)) {
17
+ // remove trailing slash
18
+ $url = substr($url, 0, strlen($url) - 1);
19
+ }
20
+ if ($api_key) {
21
+ $this->url = "{$url}{$base}/api.php?api_key={$api_key}";
22
+ }
23
+ elseif ($api_user && $api_pass) {
24
+ $this->url = "{$url}{$base}/api.php?api_user={$api_user}&api_pass={$api_pass}";
25
+ }
26
+ $this->api_key = $api_key;
27
+ }
28
+
29
+ public function credentials_test() {
30
+ $test_url = "{$this->url}&api_action=group_view&api_output={$this->output}&id=3";
31
+ $r = $this->curl($test_url);
32
+ if (is_object($r) && (int)$r->result_code) {
33
+ // successful
34
+ $r = true;
35
+ }
36
+ else {
37
+ // failed
38
+ $r = false;
39
+ }
40
+ return $r;
41
+ }
42
+
43
+ // debug function (nicely outputs variables)
44
+ public function dbg($var, $continue = 0, $element = "pre") {
45
+ echo "<" . $element . ">";
46
+ echo "Vartype: " . gettype($var) . "\n";
47
+ if ( is_array($var) ) echo "Elements: " . count($var) . "\n\n";
48
+ elseif ( is_string($var) ) echo "Length: " . strlen($var) . "\n\n";
49
+ print_r($var);
50
+ echo "</" . $element . ">";
51
+ if (!$continue) exit();
52
+ }
53
+
54
+ public function curl($url, $post_data = array()) {
55
+ // find the method from the URL
56
+ $method = preg_match("/api_action=[^&]*/i", $url, $matches);
57
+ $method = preg_match("/[^=]*$/i", $matches[0], $matches2);
58
+ $method = $matches2[0];
59
+ $request = curl_init();
60
+ curl_setopt($request, CURLOPT_URL, $url);
61
+ curl_setopt($request, CURLOPT_HEADER, 0);
62
+ curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
63
+ if ($post_data) {
64
+ curl_setopt($request, CURLOPT_POST, 1);
65
+ $data = "";
66
+
67
+ if (is_array($post_data)) {
68
+ foreach($post_data as $key => $value) {
69
+ if (is_array($value)) {
70
+
71
+ if (is_int($key)) {
72
+ // array two levels deep
73
+ foreach ($value as $key_ => $value_) {
74
+ if (is_array($value_)) {
75
+ foreach ($value_ as $k => $v) {
76
+ $k = urlencode($k);
77
+ $data .= "{$key_}[{$key}][{$k}]=" . urlencode($v) . "&";
78
+ }
79
+ }
80
+ else {
81
+ $data .= "{$key_}[{$key}]=" . urlencode($value_) . "&";
82
+ }
83
+ }
84
+ }
85
+ else {
86
+ // IE: [group] => array(2 => 2, 3 => 3)
87
+ // normally we just want the key to be a string, IE: ["group[2]"] => 2
88
+ // but we want to allow passing both formats
89
+ foreach ($value as $k => $v) {
90
+ $k = urlencode($k);
91
+ $data .= "{$key}[{$k}]=" . urlencode($v) . "&";
92
+ }
93
+ }
94
+
95
+ }
96
+ else {
97
+ $data .= "{$key}=" . urlencode($value) . "&";
98
+ }
99
+ }
100
+ }
101
+ else {
102
+ // not an array - perhaps serialized or JSON string?
103
+ // just pass it as data
104
+ $data = "data={$post_data}";
105
+ }
106
+
107
+ $data = rtrim($data, "& ");
108
+ curl_setopt($request, CURLOPT_HTTPHEADER, array("Expect:"));
109
+ curl_setopt($request, CURLOPT_POSTFIELDS, $data);
110
+ }
111
+ curl_setopt($request, CURLOPT_SSL_VERIFYPEER, false);
112
+ curl_setopt($request, CURLOPT_SSL_VERIFYHOST, 0);
113
+ curl_setopt($request, CURLOPT_FOLLOWLOCATION, true);
114
+ $response = curl_exec($request);
115
+ //$this->dbg($response);
116
+ $http_code = curl_getinfo($request, CURLINFO_HTTP_CODE);
117
+ curl_close($request);
118
+ $object = json_decode($response);
119
+ if ( !is_object($object) || (!isset($object->result_code) && !isset($object->succeeded)) ) {
120
+ // add methods that only return a string
121
+ $string_responses = array("form_html");
122
+ if (in_array($method, $string_responses)) {
123
+ return $response;
124
+ }
125
+ // something went wrong
126
+ return "An unexpected problem occurred with the API request. Some causes include: invalid JSON or XML returned. Here is the actual response from the server: ---- " . $response;
127
+ }
128
+ if (isset($object->result_code)) {
129
+ $object->success = $object->result_code;
130
+ if (!(int)$object->result_code) {
131
+ $object->error = $object->result_message;
132
+ }
133
+ }
134
+ elseif (isset($object->succeeded)) {
135
+ // some calls return "succeeded" only
136
+ $object->success = $object->succeeded;
137
+ if (!(int)$object->succeeded) {
138
+ $object->error = $object->message;
139
+ }
140
+ }
141
+ return $object;
142
+ }
143
+
144
+ }
145
+
146
  ?>
app/code/community/ActiveCampaign/Subscriptions/activecampaign-api-php/Form.class.php CHANGED
@@ -22,6 +22,232 @@ class AC_Form extends ActiveCampaign {
22
  return $response;
23
  }
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  }
26
 
27
  ?>
22
  return $response;
23
  }
24
 
25
+ function embed($params) {
26
+
27
+ $params_array = explode("&", $params);
28
+ $params_ = array();
29
+ foreach ($params_array as $expression) {
30
+ // IE: css=1
31
+ list($var, $val) = explode("=", $expression);
32
+ $params_[$var] = $val;
33
+ }
34
+
35
+ $id = (isset($params_["id"])) ? (int)$params_["id"] : 0;
36
+ $css = (isset($params_["css"])) ? (int)$params_["css"] : 1;
37
+ $ajax = (isset($params_["ajax"])) ? (int)$params_["ajax"] : 0;
38
+ // to set the current page as the action, pass "action=", or "action=[THIS URL]"
39
+ $action = (isset($params_["action"])) ? ($params_["action"] ? $params_["action"] : "this") : "";
40
+
41
+ $html = $this->html("id={$id}");
42
+
43
+ if (is_object($html) && !(int)$html->success) {
44
+ return $html->error;
45
+ }
46
+
47
+ if ($html) {
48
+
49
+ if ($action) {
50
+ if ($action != "this") {
51
+ // replace the action attribute with the one provided
52
+ $action_val = urldecode($action);
53
+ $html = preg_replace("/action=['\"][^'\"]+['\"]/", "action='{$action_val}'", $html);
54
+ }
55
+ else {
56
+ $action_val = "";
57
+ }
58
+ }
59
+ else {
60
+ // find the action attribute value (URL)
61
+ // should be the proc.php URL (at this point in the script)
62
+ $action_val = preg_match("/action=['\"][^'\"]+['\"]/", $html, $m);
63
+ $action_val = $m[0];
64
+ $action_val = substr($action_val, 8, strlen($action_val) - 9);
65
+ }
66
+
67
+ if (!$css) {
68
+ // remove all CSS
69
+ $html = preg_replace("/<style[^>]*>(.*)<\/style>/s", "", $html);
70
+ }
71
+
72
+ if (!$ajax) {
73
+ // replace the Submit button to be an actual submit type
74
+ $html = preg_replace("/input type='button'/", "input type='submit'", $html);
75
+
76
+ // if action = "this", remove the action attribute completely
77
+ if (!$action_val) {
78
+ $html = preg_replace("/action=['\"][^'\"]+['\"]/", "", $html);
79
+ }
80
+ }
81
+ else {
82
+
83
+ // if using Ajax, remove the <form> action attribute completely
84
+ $html = preg_replace("/action=['\"][^'\"]+['\"]/", "", $html);
85
+
86
+ $action_val = urldecode($action_val);
87
+
88
+ // add jQuery stuff
89
+ $extra = "<script type='text/javascript'>
90
+
91
+ $(document).ready(function() {
92
+
93
+ $('input[type*=\"button\"]').click(function() {
94
+
95
+ var form_data = {};
96
+ $('form').each(function() {
97
+ form_data = $(this).serialize();
98
+ });
99
+
100
+ var geturl;
101
+ geturl = $.ajax({
102
+ url: '{$action_val}',
103
+ type: 'POST',
104
+ dataType: 'json',
105
+ data: form_data,
106
+ error: function(jqXHR, textStatus, errorThrown) {
107
+ alert('Error: ' + textStatus);
108
+ },
109
+ success: function(data) {
110
+ $('#form_result_message').html(data.message);
111
+ }
112
+ });
113
+
114
+ });
115
+
116
+ });
117
+
118
+ </script>";
119
+
120
+ $html = $html . $extra;
121
+ }
122
+
123
+ }
124
+
125
+ return $html;
126
+ }
127
+
128
+ function process($params) {
129
+
130
+ $r = array();
131
+ if ($_SERVER["REQUEST_METHOD"] != "POST") return $r;
132
+
133
+ $sync = 0;
134
+ if ($params) {
135
+ $params_array = explode("&", $params);
136
+ $params_ = array();
137
+ foreach ($params_array as $expression) {
138
+ // IE: css=1
139
+ list($var, $val) = explode("=", $expression);
140
+ $params_[$var] = $val;
141
+ }
142
+
143
+ $sync = (isset($params_["sync"])) ? (int)$params_["sync"] : 0;
144
+ }
145
+
146
+ $formid = $_POST["f"];
147
+ $email = $_POST["email"];
148
+
149
+ if (isset($_POST["fullname"])) {
150
+ $fullname = explode(" ", $_POST["fullname"]);
151
+ $firstname = array_shift($fullname);
152
+ $lastname = implode(" ", $fullname);
153
+ }
154
+ else {
155
+ $firstname = trim($_POST["firstname"]);
156
+ $lastname = trim($_POST["lastname"]);
157
+ if ($firstname == "") $firstname = trim($_POST["first_name"]);
158
+ if ($lastname == "") $lastname = trim($_POST["last_name"]);
159
+ }
160
+
161
+ $fields = (isset($_POST["field"])) ? $_POST["field"] : array();
162
+
163
+ $subscriber = array(
164
+ "form" => $formid,
165
+ "email" => $email,
166
+ "first_name" => $firstname,
167
+ "last_name" => $lastname,
168
+ );
169
+
170
+ foreach ($fields as $ac_field_id => $field_value) {
171
+ $subscriber["field"][$ac_field_id . ",0"] = $field_value;
172
+ }
173
+
174
+ // add lists
175
+ foreach ($_POST["nlbox"] as $listid) {
176
+ $subscriber["p[{$listid}]"] = $listid;
177
+ $subscriber["status[{$listid}]"] = 1;
178
+ }
179
+
180
+ if (!$sync) {
181
+
182
+ // do add/edit
183
+
184
+ $subscriber_exists = $this->api("subscriber/view?email={$email}", $subscriber);
185
+
186
+ if ( !isset($subscriber_exists->id) ) {
187
+
188
+ // subscriber does not exist - add them
189
+
190
+ $subscriber_request = $this->api("subscriber/add", $subscriber);
191
+
192
+ if ((int)$subscriber_request->success) {
193
+ // successful request
194
+ $subscriber_id = (int)$subscriber_request->subscriber_id;
195
+ $r = array(
196
+ "success" => 1,
197
+ "message" => $subscriber_request->result_message,
198
+ "subscriber_id" => $subscriber_id,
199
+ );
200
+ }
201
+ else {
202
+ // request failed
203
+ $r = array(
204
+ "success" => 0,
205
+ "message" => $subscriber_request->error,
206
+ );
207
+ }
208
+
209
+ }
210
+ else {
211
+
212
+ // subscriber already exists - edit them
213
+
214
+ $subscriber_id = $subscriber_exists->id;
215
+
216
+ $subscriber["id"] = $subscriber_id;
217
+
218
+ $subscriber_request = $this->api("subscriber/edit?overwrite=0", $subscriber);
219
+
220
+ }
221
+
222
+ }
223
+ else {
224
+
225
+ // perform sync (add or edit)
226
+
227
+ $subscriber_request = $this->api("subscriber/sync", $subscriber);
228
+
229
+ }
230
+
231
+ if ((int)$subscriber_request->success) {
232
+ // successful request
233
+ //$subscriber_id = (int)$subscriber_request->subscriber_id;
234
+ $r = array(
235
+ "success" => 1,
236
+ "message" => $subscriber_request->result_message,
237
+ //"subscriber_id" => $subscriber_id,
238
+ );
239
+ }
240
+ else {
241
+ // request failed
242
+ $r = array(
243
+ "success" => 0,
244
+ "message" => $subscriber_request->error,
245
+ );
246
+ }
247
+
248
+ return json_encode($r);
249
+ }
250
+
251
  }
252
 
253
  ?>
app/code/community/ActiveCampaign/Subscriptions/activecampaign-api-php/Webhook.class.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class AC_Webhook extends ActiveCampaign {
4
+
5
+ public $url;
6
+ public $api_key;
7
+
8
+ function __construct($url, $api_key) {
9
+ $this->url = $url;
10
+ $this->api_key = $api_key;
11
+ }
12
+
13
+ function add($params, $post_data) {
14
+ $request_url = "{$this->url}&api_action=webhook_add&api_output={$this->output}";
15
+ $response = $this->curl($request_url, $post_data);
16
+ return $response;
17
+ }
18
+
19
+ function delete($params) {
20
+ $request_url = "{$this->url}&api_action=webhook_delete&api_output={$this->output}&{$params}";
21
+ $response = $this->curl($request_url);
22
+ return $response;
23
+ }
24
+
25
+ function delete_list($params) {
26
+ $request_url = "{$this->url}&api_action=webhook_delete_list&api_output={$this->output}&{$params}";
27
+ $response = $this->curl($request_url);
28
+ return $response;
29
+ }
30
+
31
+ function edit($params, $post_data) {
32
+ $request_url = "{$this->url}&api_action=webhook_edit&api_output={$this->output}";
33
+ $response = $this->curl($request_url, $post_data);
34
+ return $response;
35
+ }
36
+
37
+ function list_($params) {
38
+ $request_url = "{$this->url}&api_action=webhook_list&api_output={$this->output}&{$params}";
39
+ $response = $this->curl($request_url);
40
+ return $response;
41
+ }
42
+
43
+ function view($params) {
44
+ $request_url = "{$this->url}&api_action=webhook_view&api_output={$this->output}&{$params}";
45
+ $response = $this->curl($request_url);
46
+ return $response;
47
+ }
48
+
49
+ }
50
+
51
+ ?>
app/code/community/ActiveCampaign/Subscriptions/controllers/Adminhtml/SubscriptionsController.php CHANGED
@@ -134,6 +134,7 @@ class ActiveCampaign_Subscriptions_Adminhtml_SubscriptionsController extends Mag
134
 
135
  // example (converts to): ["mthommes6.activehosted.com-5","mthommes6.activehosted.com-13"]
136
  $data["list_value"] = json_encode($data["list_value"]);
 
137
 
138
  //$this->dbg($data);
139
 
134
 
135
  // example (converts to): ["mthommes6.activehosted.com-5","mthommes6.activehosted.com-13"]
136
  $data["list_value"] = json_encode($data["list_value"]);
137
+ $data["form_value"] = json_encode($data["form_value"]);
138
 
139
  //$this->dbg($data);
140
 
app/code/community/ActiveCampaign/Subscriptions/sql/subscriptions_setup/mysql4-install-0.1.0.php CHANGED
@@ -23,8 +23,10 @@ CREATE TABLE {$this->getTable('subscriptions')} (
23
  `api_url` varchar(50) NOT NULL default '',
24
  `api_key` varchar(75) NOT NULL default '',
25
  `account_url` varchar(50) NOT NULL default '',
26
- `list_value` varchar(100) NULL,
27
  `lists` text NULL,
 
 
28
  `status` smallint(6) NOT NULL default '0',
29
  `cdate` datetime NULL,
30
  PRIMARY KEY (`subscriptions_id`)
23
  `api_url` varchar(50) NOT NULL default '',
24
  `api_key` varchar(75) NOT NULL default '',
25
  `account_url` varchar(50) NOT NULL default '',
26
+ `list_value` text NULL,
27
  `lists` text NULL,
28
+ `form_value` text NULL,
29
+ `forms` text NULL,
30
  `status` smallint(6) NOT NULL default '0',
31
  `cdate` datetime NULL,
32
  PRIMARY KEY (`subscriptions_id`)
app/design/adminhtml/default/default/template/subscriptions/grid.phtml CHANGED
@@ -3,3 +3,5 @@
3
  echo $this->getGridHtml();
4
  ?>
5
  </div>
 
 
3
  echo $this->getGridHtml();
4
  ?>
5
  </div>
6
+
7
+ <p style="color: gray; font-size: 0.9em; margin-top: 25px;">ActiveCampaign extension version 1.5.0. <a href="http://www.activecampaign.com/help/magento-integration/" target="_blank">Get Help</a></p>
app/design/adminhtml/default/default/template/subscriptions/list.phtml CHANGED
@@ -46,6 +46,6 @@
46
  <script type="text/javascript">
47
  $ac(document).ready(function() {
48
  hide_stuff();
49
- $ac("#subscriptionsGrid_table").attr("style", "width: 600px;");
50
  });
51
  </script>
46
  <script type="text/javascript">
47
  $ac(document).ready(function() {
48
  hide_stuff();
49
+ $ac("#subscriptionsGrid_table").attr("style", "border: 0; width: 600px;");
50
  });
51
  </script>
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>ActiveCampaign_Subscriptions</name>
4
- <version>1.0.2</version>
5
  <stability>stable</stability>
6
  <license uri="https://www.activecampaign.com/hosted/terms.php">Commercial/Free</license>
7
  <channel>community</channel>
@@ -14,11 +14,13 @@
14
  3. Have existing customer account newsletter modifications updated in ActiveCampaign.&#xD;
15
  &#xD;
16
  4. Bulk export/sync all current newsletter subscribers to ActiveCampaign in just two clicks!</description>
17
- <notes>First release</notes>
18
- <authors><author><name>ActiveCampaign, Inc.</name><user>activecampaign</user><email>matt@activecampaign.com</email></author></authors>
19
- <date>2012-11-13</date>
20
- <time>15:04:11</time>
21
- <contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="subscriptions.xml" hash="18bfe6676477fc84b488277025d42568"/></dir><dir name="template"><dir name="subscriptions"><file name="grid.phtml" hash="5479475e2a96a006da97e35b31efeb02"/><file name="list.phtml" hash="d90e444079a30e2337df2cbcf10aa35f"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="default"><dir name="default"><dir name="layout"><file name="subscriptions.xml" hash="d0a96f68db976ce1919a664228184e9c"/></dir><dir name="template"><dir name="subscriptions"><file name="subscriptions.phtml" hash="2025758bce03d7b9cfe99029050c7be4"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="ActiveCampaign_Subscriptions.xml" hash="14eb3a0c9c06bc847b4e8c6ff691c07d"/></dir></target><target name="magecommunity"><dir name="ActiveCampaign"><dir name="Subscriptions"><dir name="activecampaign-api-php"><file name="Account.class.php" hash="eb5d6e647e0c5d6db2e4291bd2e4c24a"/><file name="ActiveCampaign.class.php" hash="142e5af0a49a81e0d7650278419c14a2"/><file name="Auth.class.php" hash="6cf45573aaa8aa4b158f88d80bb9ac7d"/><file name="Campaign.class.php" hash="3db78bd78995f6d4c42d80d26300ebe3"/><file name="Connector.class.php" hash="4d7077303c4c72bf3356270247dfef8d"/><file name="Design.class.php" hash="113a72a83d979fbe80b5ef3acd085a86"/><file name="Form.class.php" hash="d487177b0d108106ad9c35d8583266d2"/><file name="Group.class.php" hash="ce0792f8032ec09b8ca6636ffd14cdc3"/><file name="List.class.php" hash="ad045005e67f7724421b98d44b3464bd"/><file name="Message.class.php" hash="da8e027327b10dcbbd18a94a1a9730b0"/><file name="Subscriber.class.php" hash="132a8edd2d571f5064855e467e916d48"/><file name="User.class.php" hash="4732c709aedb1cc0448acafd4c956c29"/></dir><dir name="Block"><file name="Subscriptions.php" hash="ca3ca3be2fc80d23528010f2b6a5b2c9"/><dir name="Adminhtml"><file name="Subscriptions.php" hash="c26f6255fa14a3a5b81828425041ec2c"/><dir name="Subscriptions"><file name="Edit.php" hash="3dba9bad67c86cea8d6bb9e40898d5fb"/><file name="Grid.php" hash="b51fc9698c21224488c41826489a8177"/><dir name="Edit"><file name="Form.php" hash="b1eda088b2adf03d69bc1aa3cfb2a00a"/><file name="Tabs.php" hash="19d7771dca320416c7c27e0d8f6c9f36"/><dir name="Tab"><file name="Connection.php" hash="230d5a8f70b5de930864b25821290efb"/><file name="Export.php" hash="f65aa906629d6a1b4a17f16014488017"/><file name="List.php" hash="bcde9bfb9254caa3774e9b5d4aa85e14"/></dir></dir></dir></dir></dir><dir name="controllers"><file name="IndexController.php" hash="f6e27a764745bdb55f17fdca49a7fa81"/><dir name="Adminhtml"><file name="SubscriptionsController.php" hash="9546c0b5f3ada863717e9eae7574d92c"/></dir></dir><dir name="etc"><file name="config.xml" hash="a3bacb007c725735eee61c9a2bae5475"/></dir><dir name="Helper"><file name="Data.php" hash="4b35d91431328ee595132df575a60a2a"/></dir><dir name="Model"><file name="Observer.php" hash="f25021043f1dc281560da51e426f2522"/><file name="Status.php" hash="c35feda8164009341d289074be5612c0"/><file name="Subscriptions.php" hash="76818326ecfd635e574f704003184300"/><dir name="Mysql4"><file name="Subscriptions.php" hash="d112b3f1194a8bb7f329dacb34161941"/><dir name="Subscriptions"><file name="Collection.php" hash="457890390bd29e72dda81d3088ef5a50"/></dir></dir></dir><dir name="sql"><dir name="subscriptions_setup"><file name="mysql4-install-0.1.0.php" hash="11028fce8cd9cbf9cff09dd7575453dd"/></dir></dir></dir></dir></target></contents>
 
 
22
  <compatible/>
23
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php><extension><name>curl</name><min>7.19.7</min><max>7.28.0</max></extension></required></dependencies>
24
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>ActiveCampaign_Subscriptions</name>
4
+ <version>1.5.0</version>
5
  <stability>stable</stability>
6
  <license uri="https://www.activecampaign.com/hosted/terms.php">Commercial/Free</license>
7
  <channel>community</channel>
14
  3. Have existing customer account newsletter modifications updated in ActiveCampaign.&#xD;
15
  &#xD;
16
  4. Bulk export/sync all current newsletter subscribers to ActiveCampaign in just two clicks!</description>
17
+ <notes>Added Forms selector, so you can control how subscribers receive Opt-in messages.&#xD;
18
+ &#xD;
19
+ Also removed the "Reset" and "Delete Connection" buttons, as they are not necessary (you can use "Enabled" or "Disabled" instead).</notes>
20
+ <authors><author><name>ActiveCampaign, Inc.</name><user>activecampaign</user><email>help@activecampaign.com</email></author></authors>
21
+ <date>2013-02-12</date>
22
+ <time>15:18:28</time>
23
+ <contents><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="subscriptions.xml" hash="18bfe6676477fc84b488277025d42568"/></dir><dir name="template"><dir name="subscriptions"><file name="grid.phtml" hash="79ae0a6dc36363b20f779027eb02dbfc"/><file name="list.phtml" hash="70c40a80ee43596da6ae899f14191e91"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="default"><dir name="default"><dir name="layout"><file name="subscriptions.xml" hash="d0a96f68db976ce1919a664228184e9c"/></dir><dir name="template"><dir name="subscriptions"><file name="subscriptions.phtml" hash="2025758bce03d7b9cfe99029050c7be4"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="ActiveCampaign_Subscriptions.xml" hash="14eb3a0c9c06bc847b4e8c6ff691c07d"/></dir></target><target name="magecommunity"><dir name="ActiveCampaign"><dir name="Subscriptions"><dir name="activecampaign-api-php"><file name="Account.class.php" hash="eb5d6e647e0c5d6db2e4291bd2e4c24a"/><file name="ActiveCampaign.class.php" hash="a088e4fb59ae3c5353d43a3d39a2d62f"/><file name="Auth.class.php" hash="6cf45573aaa8aa4b158f88d80bb9ac7d"/><file name="Campaign.class.php" hash="3db78bd78995f6d4c42d80d26300ebe3"/><file name="Connector.class.php" hash="73d01f8f2c29248c79913083b6d58963"/><file name="Design.class.php" hash="113a72a83d979fbe80b5ef3acd085a86"/><file name="Form.class.php" hash="c62e2fc1399d0dfac4532c7e450ff31d"/><file name="Group.class.php" hash="ce0792f8032ec09b8ca6636ffd14cdc3"/><file name="List.class.php" hash="ad045005e67f7724421b98d44b3464bd"/><file name="Message.class.php" hash="da8e027327b10dcbbd18a94a1a9730b0"/><file name="Subscriber.class.php" hash="132a8edd2d571f5064855e467e916d48"/><file name="User.class.php" hash="4732c709aedb1cc0448acafd4c956c29"/><file name="Webhook.class.php" hash="1b9fc3e1524c146f42c81f6d2521a7f9"/></dir><dir name="Block"><file name="Subscriptions.php" hash="79b032b024a0593188258d4fef3fa733"/><dir name="Adminhtml"><file name="Subscriptions.php" hash="7f9fdec5858ef7a30c1fcd129f13fe67"/><dir name="Subscriptions"><file name="Edit.php" hash="3c464d71d1ad78ae035f810a1248f918"/><file name="Grid.php" hash="b51fc9698c21224488c41826489a8177"/><dir name="Edit"><file name="Form.php" hash="b1eda088b2adf03d69bc1aa3cfb2a00a"/><file name="Tabs.php" hash="4c94ebd27bb6bb0a572131d441afa945"/><dir name="Tab"><file name="Connection.php" hash="230d5a8f70b5de930864b25821290efb"/><file name="Export.php" hash="f65aa906629d6a1b4a17f16014488017"/><file name="List.php" hash="4f2cd4ca088cca5bb2ad1b598c9bc486"/><file name="Form.php" hash="200931011a1eb4b053a01a9d69909d55"/></dir></dir></dir></dir></dir><dir name="controllers"><file name="IndexController.php" hash="f6e27a764745bdb55f17fdca49a7fa81"/><dir name="Adminhtml"><file name="SubscriptionsController.php" hash="edd787979ac83ea735f8c4cd61340c89"/></dir></dir><dir name="etc"><file name="config.xml" hash="a3bacb007c725735eee61c9a2bae5475"/></dir><dir name="Helper"><file name="Data.php" hash="4b35d91431328ee595132df575a60a2a"/></dir><dir name="Model"><file name="Observer.php" hash="1f4a7a5cdb46c106cc804539dbe045a8"/><file name="Status.php" hash="c35feda8164009341d289074be5612c0"/><file name="Subscriptions.php" hash="76818326ecfd635e574f704003184300"/><dir name="Mysql4"><file name="Subscriptions.php" hash="d112b3f1194a8bb7f329dacb34161941"/><dir name="Subscriptions"><file name="Collection.php" hash="457890390bd29e72dda81d3088ef5a50"/></dir></dir></dir><dir name="sql"><dir name="subscriptions_setup"><file name="mysql4-install-0.1.0.php" hash="9f756eb38486cc878134f07f22f661c0"/></dir></dir></dir></dir></target></contents>
24
  <compatible/>
25
  <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php><extension><name>curl</name><min>7.19.7</min><max>7.28.0</max></extension></required></dependencies>
26
  </package>