Campaign_Commander_Transactional_Email_1_5 - Version 3.0.1

Version Notes

* New SmartFocus menus

* New API implementation

* New features enhance email sending, abandoned cart reminders, and data synchronization

Download this release

Release Info

Developer SmartFocus
Extension Campaign_Commander_Transactional_Email_1_5
Version 3.0.1
Comparing to
See all releases


Code changes from version 2.0.3 to 3.0.1

Files changed (196) hide show
  1. app/code/community/Emv/CartAlert/Block/Cart/Items.php +8 -11
  2. app/code/community/Emv/CartAlert/Block/Customer/Abandonment.php +18 -1
  3. app/code/community/Emv/CartAlert/Constants.php +31 -15
  4. app/code/community/Emv/CartAlert/Helper/Data.php +463 -42
  5. app/code/community/Emv/CartAlert/Model/Abandonedcart.php +0 -68
  6. app/code/community/Emv/CartAlert/Model/Abandonedcartitem.php +0 -43
  7. app/code/community/Emv/CartAlert/Model/Abandonment.php +20 -4
  8. app/code/community/Emv/CartAlert/Model/Mysql4/Abandonment.php +20 -8
  9. app/code/community/Emv/CartAlert/Model/Mysql4/Abandonment/Collection.php +37 -2
  10. app/code/community/Emv/CartAlert/Model/Mysql4/Orderflag.php +193 -0
  11. app/code/community/Emv/CartAlert/Model/Mysql4/Orderflag/Collection.php +71 -0
  12. app/code/community/Emv/CartAlert/Model/Mysql4/Stats.php +93 -0
  13. app/code/community/Emv/CartAlert/Model/Mysql4/Stats/Collection.php +19 -0
  14. app/code/community/Emv/CartAlert/Model/Observer.php +237 -208
  15. app/code/community/Emv/CartAlert/Model/Orderflag.php +30 -0
  16. app/code/community/Emv/CartAlert/Model/Resource/Setup.php +34 -25
  17. app/code/community/Emv/CartAlert/Model/Stats.php +19 -0
  18. app/code/community/Emv/CartAlert/controllers/CustomerController.php +101 -26
  19. app/code/community/Emv/CartAlert/controllers/GuestController.php +96 -25
  20. app/code/community/Emv/CartAlert/etc/adminhtml.xml +1 -5
  21. app/code/community/Emv/CartAlert/etc/config.xml +47 -14
  22. app/code/community/Emv/CartAlert/etc/system.xml +114 -57
  23. app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-install-0.1.0.php +3 -5
  24. app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.1.0-0.2.0.php +16 -17
  25. app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.2.0-0.3.0.php +26 -0
  26. app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.3.0-0.4.0.php +20 -0
  27. app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.4.0-0.5.0.php +16 -0
  28. app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.5.0-0.5.1.php +10 -0
  29. app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.5.1-0.5.2.php +8 -0
  30. app/code/community/Emv/Core/Block/Adminhtml/Account/Edit.php +10 -17
  31. app/code/community/Emv/Core/Block/Adminhtml/Account/Edit/AssociatedUrls.php +66 -0
  32. app/code/community/Emv/Core/Block/Adminhtml/Account/Edit/Form.php +105 -58
  33. app/code/community/Emv/Core/Block/Adminhtml/Account/Grid.php +37 -9
  34. app/code/community/Emv/Core/Block/Adminhtml/Accounts.php +8 -15
  35. app/code/community/Emv/Core/Exception.php +0 -4
  36. app/code/community/Emv/Core/Helper/Config.php +0 -5
  37. app/code/community/Emv/Core/Helper/Data.php +149 -5
  38. app/code/community/Emv/Core/Model/Account.php +283 -27
  39. app/code/community/Emv/Core/Model/Adminhtml/System/Config/Backend/Account/Abstract.php +107 -0
  40. app/code/community/Emv/Core/Model/Adminhtml/System/Config/Backend/Enabled.php +35 -0
  41. app/code/community/Emv/Core/Model/Mysql4/Account.php +19 -6
  42. app/code/community/Emv/Core/Model/Mysql4/Account/Collection.php +30 -9
  43. app/code/community/Emv/Core/Model/Resource/Setup.php +5 -4
  44. app/code/community/Emv/Core/Model/Service/Abstract.php +174 -0
  45. app/code/community/Emv/Core/Model/Service/BatchMember.php +34 -0
  46. app/code/community/Emv/Core/Model/Service/Member.php +61 -0
  47. app/code/community/Emv/Core/Model/Service/Notification.php +100 -0
  48. app/code/community/Emv/Core/Model/Service/Soap/Api.php +0 -367
  49. app/code/community/Emv/Core/Model/Service/Soap/Config.php +0 -59
  50. app/code/community/Emv/Core/Model/Service/Soap/SoapClient.php +0 -47
  51. app/code/community/Emv/Core/Model/Service/Transactional.php +158 -0
  52. app/code/community/Emv/Core/Model/System/Config/Source/Account.php +8 -0
  53. app/code/community/Emv/Core/controllers/Adminhtml/AccountController.php +81 -40
  54. app/code/community/Emv/Core/etc/adminhtml.xml +16 -16
  55. app/code/community/Emv/Core/etc/config.xml +3 -4
  56. app/code/community/Emv/Core/etc/system.xml +1 -61
  57. app/code/community/Emv/Core/sql/emvcore_setup/mysql4-install-0.1.0.php +1 -1
  58. app/code/community/Emv/Core/sql/emvcore_setup/mysql4-upgrade-0.1.0-0.2.0.php +17 -0
  59. app/code/community/Emv/DataSync/Block/Adminhtml/Form/Field/CustomerAttributes.php +79 -0
  60. app/code/community/Emv/DataSync/Block/Adminhtml/Form/Field/EmailVisionFields.php +68 -0
  61. app/code/community/Emv/DataSync/Block/Adminhtml/System/Config/CustomerAttributes.php +101 -0
  62. app/code/community/Emv/DataSync/Block/Adminhtml/System/Config/Date.php +32 -0
  63. app/code/community/Emv/DataSync/Block/Adminhtml/System/Config/GetFields.php +36 -0
  64. app/code/community/Emv/DataSync/Helper/Data.php +193 -0
  65. app/code/community/Emv/DataSync/Helper/Service.php +318 -0
  66. app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/ApiMember/Account.php +25 -0
  67. app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/ApiMember/Cron.php +59 -0
  68. app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/ApiMember/Enabled.php +16 -0
  69. app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/BatchMember/Account.php +25 -0
  70. app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/BatchMember/Cron.php +62 -0
  71. app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/BatchMember/Enabled.php +16 -0
  72. app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/Clean/Cron.php +15 -0
  73. app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Source/Fields.php +30 -0
  74. app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Source/MemberCronTime.php +28 -0
  75. app/code/community/Emv/DataSync/Model/Cron.php +254 -0
  76. app/code/community/Emv/DataSync/Model/Observer.php +256 -0
  77. app/code/community/Emv/DataSync/Model/Service/BatchMember.php +443 -0
  78. app/code/community/Emv/DataSync/Model/Service/Member.php +337 -0
  79. app/code/community/Emv/DataSync/controllers/Adminhtml/DataSyncController.php +81 -0
  80. app/code/community/Emv/DataSync/etc/adminhtml.xml +22 -0
  81. app/code/community/Emv/DataSync/etc/config.xml +162 -0
  82. app/code/community/Emv/DataSync/etc/system.xml +210 -0
  83. app/code/community/Emv/DataSync/sql/emvdatasync_setup/mysql4-install-0.0.1.php +12 -0
  84. app/code/community/Emv/Emt/Block/Adminhtml/Emt/Edit.php +0 -38
  85. app/code/community/Emv/Emt/Block/Adminhtml/Emt/Edit/Attributes.php +0 -83
  86. app/code/community/Emv/Emt/Block/Adminhtml/Emt/Edit/Form.php +0 -240
  87. app/code/community/Emv/Emt/Block/Adminhtml/Emt/Grid.php +0 -97
  88. app/code/community/Emv/Emt/Block/Adminhtml/Emt/Grid/Renderer/Emvname.php +0 -18
  89. app/code/community/Emv/Emt/Block/Adminhtml/Emt/New.php +0 -29
  90. app/code/community/Emv/Emt/Block/Adminhtml/Emt/New/Form.php +0 -94
  91. app/code/community/Emv/Emt/Block/Adminhtml/Emts.php +0 -32
  92. app/code/community/Emv/Emt/Block/Adminhtml/Log.php +21 -0
  93. app/code/community/Emv/Emt/Block/Adminhtml/Log/Grid.php +180 -0
  94. app/code/community/Emv/Emt/Block/Adminhtml/Log/Grid/Renderer/GetError.php +28 -0
  95. app/code/community/Emv/Emt/Block/Adminhtml/Resending.php +21 -0
  96. app/code/community/Emv/Emt/Block/Adminhtml/Resending/Grid.php +152 -0
  97. app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit.php +234 -0
  98. app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit/Tab/EmvContent.php +23 -0
  99. app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit/Tab/EmvDyn.php +231 -0
  100. app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit/Tab/General.php +317 -0
  101. app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit/Tabs.php +57 -0
  102. app/code/community/Emv/Emt/Block/Adminhtml/Template/Grid.php +162 -0
  103. app/code/community/Emv/Emt/Block/Adminhtml/Template/Grid/Renderer/Emvname.php +27 -0
  104. app/code/community/Emv/Emt/Block/Adminhtml/Template/Grid/Renderer/MageTemplate.php +30 -0
  105. app/code/community/Emv/Emt/Block/Adminhtml/Templates.php +21 -0
  106. app/code/community/Emv/Emt/Constants.php +0 -11
  107. app/code/community/Emv/Emt/Helper/Data.php +12 -23
  108. app/code/community/Emv/Emt/Helper/Emvtemplate.php +461 -36
  109. app/code/community/Emv/Emt/Model/Adminhtml/System/Config/Backend/Account.php +59 -0
  110. app/code/community/Emv/Emt/Model/Attribute.php +38 -13
  111. app/code/community/Emv/Emt/Model/Cron.php +39 -0
  112. app/code/community/Emv/Emt/Model/Emt.php +291 -91
  113. app/code/community/Emv/Emt/Model/Log.php +151 -0
  114. app/code/community/Emv/Emt/Model/Mage/Core/Email/Template.php +333 -100
  115. app/code/community/Emv/Emt/Model/MageTemplate.php +20 -3
  116. app/code/community/Emv/Emt/Model/Mailmode.php +49 -22
  117. app/code/community/Emv/Emt/Model/Mysql4/Attribute.php +23 -4
  118. app/code/community/Emv/Emt/Model/Mysql4/Attribute/Collection.php +37 -4
  119. app/code/community/Emv/Emt/Model/Mysql4/Emt.php +25 -6
  120. app/code/community/Emv/Emt/Model/Mysql4/Emt/Collection.php +47 -12
  121. app/code/community/Emv/Emt/Model/Mysql4/Log.php +16 -0
  122. app/code/community/Emv/Emt/Model/Mysql4/Log/Collection.php +35 -0
  123. app/code/community/Emv/Emt/Model/Mysql4/Mailmode.php +0 -19
  124. app/code/community/Emv/Emt/Model/Mysql4/Mailmode/Collection.php +0 -31
  125. app/code/community/Emv/Emt/Model/Mysql4/Resending/Queue/Message.php +20 -0
  126. app/code/community/Emv/Emt/Model/Mysql4/Resending/Queue/Message/Collection.php +37 -0
  127. app/code/community/Emv/Emt/Model/Resending/Queue.php +214 -0
  128. app/code/community/Emv/Emt/Model/Resending/Queue/Message.php +85 -0
  129. app/code/community/Emv/Emt/Model/Resending/Rule.php +263 -0
  130. app/code/community/Emv/Emt/Model/Resource/Setup.php +6 -5
  131. app/code/community/Emv/Emt/controllers/Adminhtml/EmtController.php +0 -484
  132. app/code/community/Emv/Emt/controllers/Adminhtml/LogController.php +83 -0
  133. app/code/community/Emv/Emt/controllers/Adminhtml/RescheduleController.php +68 -0
  134. app/code/community/Emv/Emt/controllers/Adminhtml/TemplateController.php +716 -0
  135. app/code/community/Emv/Emt/etc/adminhtml.xml +46 -11
  136. app/code/community/Emv/Emt/etc/config.xml +31 -2
  137. app/code/community/Emv/Emt/etc/system.xml +96 -0
  138. app/code/community/Emv/Emt/sql/emvemt_setup/mysql4-upgrade-0.1.0-0.2.0.php +3 -0
  139. app/code/community/Emv/Emt/sql/emvemt_setup/mysql4-upgrade-0.2.0-0.3.0.php +12 -0
  140. app/code/community/Emv/Emt/sql/emvemt_setup/mysql4-upgrade-0.3.0-0.4.0.php +25 -0
  141. app/code/community/Emv/Emt/sql/emvemt_setup/mysql4-upgrade-0.4.0-0.4.1.php +79 -0
  142. app/code/community/Emv/Report/Block/Adminhtml/Conversion.php +525 -0
  143. app/code/community/Emv/Report/Block/Adminhtml/Conversion/Form.php +56 -0
  144. app/code/community/Emv/Report/Block/Adminhtml/Details.php +68 -0
  145. app/code/community/Emv/Report/Block/Adminhtml/Details/Grid.php +143 -0
  146. app/code/community/Emv/Report/Helper/Data.php +12 -0
  147. app/code/community/Emv/Report/controllers/Adminhtml/ConversionController.php +205 -0
  148. app/code/community/Emv/Report/controllers/Adminhtml/DetailsController.php +65 -0
  149. app/code/community/Emv/Report/etc/adminhtml.xml +28 -0
  150. app/code/community/Emv/Report/etc/config.xml +48 -0
  151. app/code/community/Mage/SalesRule/Helper/Coupon.php +147 -0
  152. app/code/community/Mage/SalesRule/Model/Coupon/Massgenerator.php +194 -0
  153. app/code/community/Mage/SalesRule/Model/System/Config/Source/Coupon/Format.php +54 -0
  154. app/design/adminhtml/default/default/layout/emailvision/abandonment_report.xml +11 -0
  155. app/design/adminhtml/default/default/template/emailvision/abandonment/grid/container.phtml +195 -0
  156. app/design/adminhtml/default/default/template/emailvision/account/associated_urls.phtml +171 -0
  157. app/design/adminhtml/default/default/template/emailvision/datasync/system/config/form/field/array.phtml +269 -0
  158. app/design/adminhtml/default/default/template/emailvision/datasync/system/config/getfields.phtml +15 -0
  159. app/design/adminhtml/default/default/template/emailvision/emt/template/common_js.phtml +260 -0
  160. app/design/adminhtml/default/default/template/emailvision/emt/template/edit.phtml +49 -0
  161. app/design/adminhtml/default/default/template/emailvision/emt/template/mapped_attributes.phtml +138 -0
  162. app/design/adminhtml/default/default/template/emt/attributes.phtml +0 -142
  163. app/design/frontend/{default/default/layout → base/default/layout/emailvision}/abandonment.xml +1 -1
  164. app/design/frontend/{default/default/template → base/default/template/emailvision}/abandonment/customer.phtml +0 -0
  165. app/design/frontend/{emv/template → base/default/template/emailvision}/abandonment/reminder/items.phtml +17 -14
  166. app/design/frontend/enterprise/default/layout/abandonment.xml +0 -23
  167. app/design/frontend/enterprise/default/template/abandonment/customer.phtml +0 -23
  168. app/etc/modules/Emv_DataSync.xml +12 -0
  169. app/etc/modules/Emv_Report.xml +12 -0
  170. app/locale/en_US/Emv_CartAlert.csv +16 -9
  171. app/locale/en_US/Emv_Core.csv +42 -25
  172. app/locale/en_US/Emv_DataSync.csv +44 -0
  173. app/locale/en_US/Emv_Emt.csv +107 -51
  174. app/locale/en_US/Emv_Report.csv +27 -0
  175. app/locale/en_US/template/email/abandonment/template1.html +0 -41
  176. app/locale/en_US/template/email/abandonment/template2.html +0 -41
  177. app/locale/en_US/template/email/abandonment/template3.html +0 -41
  178. app/locale/en_US/template/email/emailvision/abandonment/template1.html +60 -0
  179. app/locale/en_US/template/email/emailvision/abandonment/template2.html +60 -0
  180. app/locale/en_US/template/email/emailvision/abandonment/template3.html +60 -0
  181. app/locale/en_US/template/email/emailvision/datasync/cron_errors.html +5 -0
  182. app/locale/fr_FR/Emv_CartAlert.csv +27 -19
  183. app/locale/fr_FR/Emv_Core.csv +45 -27
  184. app/locale/fr_FR/Emv_DataSync.csv +45 -0
  185. app/locale/fr_FR/Emv_Emt.csv +107 -51
  186. app/locale/fr_FR/Emv_Report.csv +27 -0
  187. lib/EmailVision/Api/BatchMemberService.php +410 -0
  188. lib/EmailVision/Api/Common.php +609 -0
  189. lib/EmailVision/Api/Exception.php +291 -0
  190. lib/EmailVision/Api/MemberService.php +346 -0
  191. lib/EmailVision/Api/NotificationService.php +345 -0
  192. lib/EmailVision/Api/TransactionalService.php +433 -0
  193. lib/EmailVision/SoapClient.php +36 -0
  194. lib/EmailVision/Tools/File/Csv.php +157 -0
  195. package.xml +24 -9
  196. skin/adminhtml/default/default/campaign-commander.css +14 -0
app/code/community/Emv/CartAlert/Block/Cart/Items.php CHANGED
@@ -1,22 +1,19 @@
1
  <?php
2
  /**
3
  * Block included in abandoned carts reminder e-mails
 
 
 
 
4
  */
5
  class Emv_CartAlert_Block_Cart_Items extends Mage_Sales_Block_Items_Abstract
6
  {
 
 
 
7
  public function __construct()
8
  {
9
  parent::__construct();
10
- /*
11
- * The template path is hard-coded because while sending a mail by cron,
12
- * Magento does not take active themes into account, and searches for
13
- * the template in /app/design/frontend/base/default.
14
- *
15
- * We want to avoid placing this new template in
16
- * /app/design/frontend/base/default, which is not supposed to contain
17
- * other templates that those which come with Magento by default.
18
- */
19
- $this->setTemplate('..'.DS.'..'.DS.'..'.DS.'emv'.DS.
20
- 'template'.DS.'abandonment'.DS.'reminder'.DS.'items.phtml');
21
  }
22
  }
1
  <?php
2
  /**
3
  * Block included in abandoned carts reminder e-mails
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
  */
9
  class Emv_CartAlert_Block_Cart_Items extends Mage_Sales_Block_Items_Abstract
10
  {
11
+ /**
12
+ * Constructor - set template file
13
+ */
14
  public function __construct()
15
  {
16
  parent::__construct();
17
+ $this->setTemplate('emailvision' . DS . 'abandonment' . DS . 'reminder' . DS . 'items.phtml');
 
 
 
 
 
 
 
 
 
 
18
  }
19
  }
app/code/community/Emv/CartAlert/Block/Customer/Abandonment.php CHANGED
@@ -1,14 +1,27 @@
1
  <?php
2
-
 
 
 
 
 
 
3
  class Emv_CartAlert_Block_Customer_Abandonment extends Mage_Customer_Block_Account_Dashboard // Mage_Core_Block_Template
4
  {
5
 
 
 
 
6
  public function __construct()
7
  {
8
  parent::__construct();
9
  $this->setTemplate('customer/form/newsletter.phtml');
10
  }
11
 
 
 
 
 
12
  public function getIsSubscribed()
13
  {
14
  $isSubscribed = Mage::getSingleton('customer/session')->getCustomer()
@@ -17,6 +30,10 @@ class Emv_CartAlert_Block_Customer_Abandonment extends Mage_Customer_Block_Accou
17
  return $isSubscribed;
18
  }
19
 
 
 
 
 
20
  public function getAction()
21
  {
22
  return $this->getUrl('*/*/save');
1
  <?php
2
+ /**
3
+ * Abandonment Cart Reminder Subscription Block for customer
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
  class Emv_CartAlert_Block_Customer_Abandonment extends Mage_Customer_Block_Account_Dashboard // Mage_Core_Block_Template
10
  {
11
 
12
+ /**
13
+ * Constructor - set template file
14
+ */
15
  public function __construct()
16
  {
17
  parent::__construct();
18
  $this->setTemplate('customer/form/newsletter.phtml');
19
  }
20
 
21
+ /**
22
+ * Check if user is subscribed to abandonment cart reminder
23
+ * @return unknown
24
+ */
25
  public function getIsSubscribed()
26
  {
27
  $isSubscribed = Mage::getSingleton('customer/session')->getCustomer()
30
  return $isSubscribed;
31
  }
32
 
33
+ /**
34
+ * (non-PHPdoc)
35
+ * @see Mage_Core_Block_Abstract::getAction()
36
+ */
37
  public function getAction()
38
  {
39
  return $this->getUrl('*/*/save');
app/code/community/Emv/CartAlert/Constants.php CHANGED
@@ -1,26 +1,42 @@
1
  <?php
 
 
 
 
 
 
 
2
  interface Emv_CartAlert_Constants
3
  {
4
- const XML_PATH_FIRST_ALERT_ENABLED = 'abandonment/first_alert_config/enabled';
5
- const XML_PATH_FIRST_ALERT_TEMPLATE = 'abandonment/first_alert_config/template';
6
- const XML_PATH_FIRST_ALERT_DELAY = 'abandonment/first_alert_config/delay';
7
 
8
- const XML_PATH_SECOND_ALERT_ENABLED = 'abandonment/second_alert_config/enabled';
9
  const XML_PATH_SECOND_ALERT_TEMPLATE = 'abandonment/second_alert_config/template';
10
- const XML_PATH_SECOND_ALERT_DELAY = 'abandonment/second_alert_config/delay';
11
 
12
- const XML_PATH_THIRD_ALERT_ENABLED = 'abandonment/third_alert_config/enabled';
13
- const XML_PATH_THIRD_ALERT_TEMPLATE = 'abandonment/third_alert_config/template';
14
- const XML_PATH_THIRD_ALERT_DELAY = 'abandonment/third_alert_config/delay';
15
 
16
- const XML_PATH_ALERT_SENDER_IDENTITY = 'abandonment/alert_identity/email_identity';
17
 
18
- const FIRST_ALERT_FLAG = 'first_alert';
19
- const SECOND_ALERT_FLAG = 'second_alert';
20
- const THIRD_ALERT_FLAG = 'third_alert';
 
 
21
 
22
- const OUTDATED_FLAG = 'outdated';
23
- const TO_BE_PROCESSED_FLAG = 'to_be_processed';
 
 
 
 
24
 
25
- const OUTDATED_CART_DELAY = 168; // hour = 7 days
 
 
 
26
  }
1
  <?php
2
+ /**
3
+ * Cart alert constants
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
  interface Emv_CartAlert_Constants
10
  {
11
+ const XML_PATH_FIRST_ALERT_ENABLED = 'abandonment/first_alert_config/enabled';
12
+ const XML_PATH_FIRST_ALERT_TEMPLATE = 'abandonment/first_alert_config/template';
13
+ const XML_PATH_FIRST_ALERT_DELAY = 'abandonment/first_alert_config/delay';
14
 
15
+ const XML_PATH_SECOND_ALERT_ENABLED = 'abandonment/second_alert_config/enabled';
16
  const XML_PATH_SECOND_ALERT_TEMPLATE = 'abandonment/second_alert_config/template';
17
+ const XML_PATH_SECOND_ALERT_DELAY = 'abandonment/second_alert_config/delay';
18
 
19
+ const XML_PATH_THIRD_ALERT_ENABLED = 'abandonment/third_alert_config/enabled';
20
+ const XML_PATH_THIRD_ALERT_TEMPLATE = 'abandonment/third_alert_config/template';
21
+ const XML_PATH_THIRD_ALERT_DELAY = 'abandonment/third_alert_config/delay';
22
 
23
+ const XML_PATH_ALERT_SENDER_IDENTITY = 'abandonment/general/email_identity';
24
 
25
+ const XML_PATH_COUPON_CODE_LENGTH = 'abandonment/general/length';
26
+ const XML_PATH_COUPON_CODE_FORMAT = 'abandonment/general/format';
27
+ const XML_PATH_COUPON_CODE_PREFIX = 'abandonment/general/prefix';
28
+ const XML_PATH_COUPON_CODE_SUFFIX = 'abandonment/general/suffix';
29
+ const XML_PATH_COUPON_CODE_DASH = 'abandonment/general/dash';
30
 
31
+ const FIRST_ALERT_FLAG = 'first_alert';
32
+ const FIRST_ALERT_REMINDER_ID = 1;
33
+ const SECOND_ALERT_FLAG = 'second_alert';
34
+ const SECOND_ALERT_REMINDER_ID = 2;
35
+ const THIRD_ALERT_FLAG = 'third_alert';
36
+ const THIRD_ALERT_REMINDER_ID = 3;
37
 
38
+ const OUTDATED_FLAG = 'outdated';
39
+ const TO_BE_PROCESSED_FLAG = 'to_be_processed';
40
+
41
+ const OUTDATED_CART_DELAY = 168; // 168 hours = 7 days
42
  }
app/code/community/Emv/CartAlert/Helper/Data.php CHANGED
@@ -1,6 +1,50 @@
1
  <?php
 
 
 
 
 
 
 
2
  class Emv_CartAlert_Helper_Data extends Mage_Core_Helper_Abstract
3
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
  /**
6
  * Detect whether the quote is associated with a registered customer
@@ -15,90 +59,467 @@ class Emv_CartAlert_Helper_Data extends Mage_Core_Helper_Abstract
15
 
16
  /**
17
  * Get the link used to unsubscribe from the reminders.
18
- * The quote is used to determine whether the link is for a registered customer or a guest.
19
  *
20
  * @param Mage_Sales_Model_Quote $quote Quote
21
  * @return string the unsubscribe link
22
  */
23
  public function getUnsubscribeLink(Mage_Sales_Model_Quote $quote)
24
  {
25
- if ($this->_isFromRegisteredCustomer($quote))
26
- {
27
  return Mage::getUrl('abandonment/customer/unsubscribe');
28
- }
29
- else
30
- {
31
  $hash = Mage::helper('core')->getHash($quote->getCustomerEmail());
32
- return Mage::getUrl('abandonment/guest/unsubscribe', Array('quote' => $quote->getId(), 'key' => $hash));
33
  }
34
  }
35
 
36
  /**
37
  * Get the link used to view the cart.
38
- * The quote is used to determine whether the link is for a registered customer or a guest.
39
  *
40
  * @param Mage_Sales_Model_Quote $quote Quote
 
41
  * @return string the view cart/checkout link
42
  */
43
- public function getCartLink(Mage_Sales_Model_Quote $quote)
44
  {
45
- if ($this->_isFromRegisteredCustomer($quote))
46
- {
47
- return Mage::getUrl('abandonment/customer/cart');
 
 
 
 
 
 
 
48
  }
49
- else
50
- {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  $hash = Mage::helper('core')->getHash($quote->getCustomerEmail());
52
- return Mage::getUrl('abandonment/guest/cart', Array('quote' => $quote->getId(), 'key' => $hash));
 
 
 
53
  }
54
  }
55
 
56
  /**
57
- * Send a reminder
 
58
  *
59
- * @param Array $abandoned_cart Data extracted from the abandoned quote
60
- * @param string $template_code Config path from which the template to use is fetched
61
  */
62
- protected function _sendReminder($abandoned_cart, $template_code, $storeId)
63
  {
64
- /* @var $template Emv_Emt_Model_Mage_Core_Email_Template */
65
- $template = Mage::getModel('core/email_template');
66
 
67
- $model = Mage::getStoreConfig($template_code, $storeId);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
- $mode = $this->getTemplateSendMode($model, $storeId);
 
 
 
 
 
 
 
 
 
70
 
71
- // Force emv send mode
72
- if($mode == null || $mode == Emv_Emt_Constants::CLASSIC_FLAG)
73
- {
74
- $template->setEmvSend(true);
75
  }
76
 
77
- return $template->sendTransactional($model,
78
- Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_ALERT_SENDER_IDENTITY, $storeId),
79
- $abandoned_cart->getEmail(), $abandoned_cart->getCustomerName(),
80
- Array('cart' => $abandoned_cart), $storeId);
 
 
 
 
 
 
 
 
 
81
  }
82
 
83
- public function sendFirstReminder($abandoned_cart, $storeId)
 
 
 
 
 
84
  {
85
- return $this->_sendReminder($abandoned_cart, Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_TEMPLATE, $storeId);
 
 
 
 
86
  }
87
 
88
- public function sendSecondReminder($abandoned_cart, $storeId)
 
 
 
 
 
89
  {
90
- return $this->_sendReminder($abandoned_cart, Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_TEMPLATE, $storeId);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  }
92
 
93
- public function sendThirdReminder($abandoned_cart, $storeId)
 
 
 
 
 
 
94
  {
95
- return $this->_sendReminder($abandoned_cart, Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_TEMPLATE, $storeId);
 
 
 
 
96
  }
97
 
98
- protected function getTemplateSendMode($templateId, $storeId)
 
 
 
 
99
  {
100
- /* @var $emt Emv_Emt_Model_Emt */
101
- $emt = Mage::getModel('emvemt/emt');
102
- return $emt->getMode($templateId, $storeId);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  }
104
- }
1
  <?php
2
+ /**
3
+ * Cart alert helper
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
  class Emv_CartAlert_Helper_Data extends Mage_Core_Helper_Abstract
10
  {
11
+ /**
12
+ * @var Image size
13
+ */
14
+ const IMAGE_SIZE = 265;
15
+
16
+ /**
17
+ * XML PATH to get image size
18
+ */
19
+ const XML_PATH_IMAGE_SIZE = 'abandonment/general/image_size';
20
+
21
+ /**
22
+ * @var array
23
+ */
24
+ protected $_loadedProducts = array();
25
+
26
+ /**
27
+ * @var array
28
+ */
29
+ protected $_sendingModeForTemplate = array();
30
+
31
+ /**
32
+ * Add dash after every x characters
33
+ */
34
+ const DASH_EVERY_X_CHARACTERS = 0;
35
+
36
+ /**
37
+ * Coupon length without prefix and suffix
38
+ */
39
+ const COUPON_LENTH = 6;
40
+ const XML_PATH_SHOPING_CART_RULE_ID = 'abandonment/general/cart_rule';
41
+
42
+ /**
43
+ * Shopping cart rules
44
+ *
45
+ * @var array
46
+ */
47
+ protected $_rules = array();
48
 
49
  /**
50
  * Detect whether the quote is associated with a registered customer
59
 
60
  /**
61
  * Get the link used to unsubscribe from the reminders.
62
+ * The quote is used to determine whether the link is for a registered customer or a guest.
63
  *
64
  * @param Mage_Sales_Model_Quote $quote Quote
65
  * @return string the unsubscribe link
66
  */
67
  public function getUnsubscribeLink(Mage_Sales_Model_Quote $quote)
68
  {
69
+ if ($this->_isFromRegisteredCustomer($quote)) {
 
70
  return Mage::getUrl('abandonment/customer/unsubscribe');
71
+ } else {
 
 
72
  $hash = Mage::helper('core')->getHash($quote->getCustomerEmail());
73
+ return Mage::getUrl('abandonment/guest/unsubscribe', array('quote' => $quote->getId(), 'key' => $hash));
74
  }
75
  }
76
 
77
  /**
78
  * Get the link used to view the cart.
79
+ * The quote is used to determine whether the link is for a registered customer or a guest.
80
  *
81
  * @param Mage_Sales_Model_Quote $quote Quote
82
+ * @param string $reminderFlag
83
  * @return string the view cart/checkout link
84
  */
85
+ public function getCartLink(Mage_Sales_Model_Quote $quote, $reminderFlag)
86
  {
87
+ $reminderId = $this->getReminderIdFromFlag($reminderFlag);
88
+
89
+ if ($this->_isFromRegisteredCustomer($quote)) {
90
+ return Mage::getUrl('abandonment/customer/cart', array('reminder' => $reminderId));
91
+ } else {
92
+ $hash = Mage::helper('core')->getHash($quote->getCustomerEmail());
93
+ return Mage::getUrl(
94
+ 'abandonment/guest/cart',
95
+ array('quote' => $quote->getId(), 'key' => $hash, 'reminder' => $reminderId)
96
+ );
97
  }
98
+ }
99
+
100
+ /**
101
+ * Get the link used to view the store homepage.
102
+ * The quote is used to determine whether the link is for a registered customer or a guest.
103
+ *
104
+ * @param Mage_Sales_Model_Quote $quote Quote
105
+ * @return string the view store link
106
+ */
107
+ public function getStoreLink(Mage_Sales_Model_Quote $quote, $reminderFlag)
108
+ {
109
+ $reminderId = $this->getReminderIdFromFlag($reminderFlag);
110
+
111
+ if ($this->_isFromRegisteredCustomer($quote)) {
112
+ return Mage::getUrl('abandonment/customer/store', array('reminder' => $reminderId));
113
+ } else {
114
  $hash = Mage::helper('core')->getHash($quote->getCustomerEmail());
115
+ return Mage::getUrl(
116
+ 'abandonment/guest/store',
117
+ array('quote' => $quote->getId(), 'key' => $hash, 'reminder' => $reminderId)
118
+ );
119
  }
120
  }
121
 
122
  /**
123
+ * Get the link used to view the a product page.
124
+ * The quote is used to determine whether the link is for a registered customer or a guest.
125
  *
126
+ * @param Mage_Sales_Model_Quote $quote Quote
127
+ * @return string the view product link
128
  */
129
+ public function getItemLink(Mage_Sales_Model_Quote $quote, $reminderFlag, $productId)
130
  {
131
+ $reminderId = $this->getReminderIdFromFlag($reminderFlag);
 
132
 
133
+ if ($this->_isFromRegisteredCustomer($quote)) {
134
+ return Mage::getUrl('abandonment/customer/product',
135
+ array(
136
+ 'reminder' => $reminderId,
137
+ 'productid' => $productId
138
+ )
139
+ );
140
+ } else {
141
+ $hash = Mage::helper('core')->getHash($quote->getCustomerEmail());
142
+ return Mage::getUrl('abandonment/guest/product',
143
+ array(
144
+ 'quote' => $quote->getId(),
145
+ 'key' => $hash,
146
+ 'reminder' => $reminderId,
147
+ 'productid' => $productId,
148
+ )
149
+ );
150
+ }
151
+ }
152
 
153
+ /**
154
+ * Retrieves an image URL for the product, if it exists.
155
+ * The priority is: thumbnail -> small image -> image -> Magento's placeholder.
156
+ *
157
+ * @param $productId
158
+ * @return string the image's URL
159
+ */
160
+ public function getProductImageUrl ($productId)
161
+ {
162
+ $product = $this->getProduct($productId);
163
 
164
+ $imageSize = Mage::getStoreConfig(self::XML_PATH_IMAGE_SIZE);
165
+ if (!$imageSize) {
166
+ $imageSize = self::IMAGE_SIZE;
 
167
  }
168
 
169
+ if (($product->getThumbnail() != 'no_selection')) {
170
+ return Mage::helper('catalog/image')->init($product, 'thumbnail')
171
+ ->resize($imageSize)
172
+ ->__toString();
173
+ } elseif (($product->getSmallImage() != 'no_selection')) {
174
+ return Mage::helper('catalog/image')->init($product, 'small_image')
175
+ ->resize($imageSize)
176
+ ->__toString();
177
+ } else {
178
+ return Mage::helper('catalog/image')->init($product, 'image')
179
+ ->resize($imageSize)
180
+ ->__toString();
181
+ }
182
  }
183
 
184
+ /**
185
+ * Get product object
186
+ * @param string $productId
187
+ * @return multitype:
188
+ */
189
+ public function getProduct($productId)
190
  {
191
+ if (!isset($this->_loadedProducts[$productId])) {
192
+ $this->_loadedProducts[$productId] = Mage::getModel('catalog/product')->load($productId);
193
+ }
194
+
195
+ return $this->_loadedProducts[$productId];
196
  }
197
 
198
+ /**
199
+ * @param string $templateName
200
+ * @param string $storeId
201
+ * @return NULL
202
+ */
203
+ public function getTemplateSendMode($templateName, $storeId)
204
  {
205
+ $key = $templateName . $storeId;
206
+ if (!isset($this->_sendingModeForTemplate[$key])) {
207
+ $mode = null;
208
+
209
+ $accountId = Mage::getStoreConfig(Emv_Emt_Model_Mage_Core_Email_Template::XML_PATH_CONFIG_ACCOUNT, $storeId);
210
+ if ($accountId) {
211
+ $emvemt = Mage::helper('emvemt/emvtemplate')->getEmvEmt($templateName, $accountId);
212
+ $mode = $emvemt->getData('emv_send_mail_mode_id');
213
+ }
214
+ $this->_sendingModeForTemplate[$key] = $mode;
215
+ }
216
+
217
+ return $this->_sendingModeForTemplate[$key];
218
+ }
219
+
220
+ /**
221
+ * Send a reminder
222
+ *
223
+ * @param Mage_Sales_Model_Quote $abandonedCart
224
+ * @param $storeId
225
+ * @param Emv_CartAlert_Model_Abandonment $abandonment
226
+ * @param Mage_Core_Model_Email_Template
227
+ */
228
+ public function sendReminder(
229
+ Mage_Sales_Model_Quote $abandonedCart,
230
+ $storeId,
231
+ Emv_CartAlert_Model_Abandonment $abandonment
232
+ ) {
233
+ // determine which template should be used
234
+ $reminderId = false;
235
+ $templatePath = false;
236
+ switch ($abandonedCart->getReminderTemplate()) {
237
+ case Emv_CartAlert_Constants::FIRST_ALERT_FLAG :
238
+ $reminderId = $this->getReminderIdFromFlag(Emv_CartAlert_Constants::FIRST_ALERT_FLAG);
239
+ $templatePath = Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_TEMPLATE;
240
+ break;
241
+ case Emv_CartAlert_Constants::SECOND_ALERT_FLAG :
242
+ $reminderId = $this->getReminderIdFromFlag(Emv_CartAlert_Constants::SECOND_ALERT_FLAG);
243
+ $templatePath = Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_TEMPLATE;
244
+ break;
245
+ case Emv_CartAlert_Constants::THIRD_ALERT_FLAG :
246
+ $reminderId = $this->getReminderIdFromFlag(Emv_CartAlert_Constants::THIRD_ALERT_FLAG);
247
+ $templatePath = Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_TEMPLATE;
248
+ break;
249
+ }
250
+
251
+ if ($templatePath) {
252
+ // get template name
253
+ $templateName = Mage::getStoreConfig($templatePath, $storeId);
254
+
255
+ $mode = $this->getTemplateSendMode($templateName, $storeId);
256
+
257
+ /* @var $template Emv_Emt_Model_Mage_Core_Email_Template */
258
+ $template = Mage::getModel('core/email_template');
259
+ // Force emv send mode
260
+ if ($mode == null || $mode == Emv_Emt_Model_Mailmode::CLASSIC_MODE) {
261
+ $template->setEmvSend(true);
262
+ }
263
+
264
+ // set design config to frontend
265
+ $template->setDesignConfig(array('area' => 'frontend', 'store' => $storeId));
266
+
267
+ $template->sendTransactional(
268
+ $templateName,
269
+ Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_ALERT_SENDER_IDENTITY, $storeId),
270
+ $abandonedCart->getCustomerEmail(),
271
+ $abandonedCart->getPreparedCustomerName(),
272
+ Array('cart' => $abandonedCart, 'promo_code' => $abandonment->getCouponCode()),
273
+ $storeId
274
+ );
275
+
276
+ // update reminder statistic
277
+ $this->updateStats($reminderId, $abandonedCart->getId(), $storeId);
278
+ }
279
  }
280
 
281
+ /**
282
+ * Update statistic information about the reminder sending
283
+ * @param int $reminderId
284
+ * @param int $quoteId
285
+ * @param int $storeId
286
+ */
287
+ public function updateStats($reminderId, $quoteId, $storeId)
288
  {
289
+ $stats = Mage::getModel('abandonment/stats');
290
+ $stats->setQuoteId($quoteId);
291
+ $stats->setSendDate(Zend_Date::now()->toString(Varien_Date::DATETIME_INTERNAL_FORMAT));
292
+ $stats->setReminderId($reminderId);
293
+ $stats->save();
294
  }
295
 
296
+ /**
297
+ * @param int $reminderId
298
+ * @return string
299
+ */
300
+ public function getReminderFlagFromId($reminderId)
301
  {
302
+ $reminderFlag = null;
303
+
304
+ switch ($reminderId) {
305
+ case Emv_CartAlert_Constants::SECOND_ALERT_REMINDER_ID:
306
+ $reminderFlag = Emv_CartAlert_Constants::SECOND_ALERT_FLAG;
307
+ break;
308
+
309
+ case Emv_CartAlert_Constants::THIRD_ALERT_REMINDER_ID:
310
+ $reminderFlag = Emv_CartAlert_Constants::THIRD_ALERT_FLAG;
311
+ break;
312
+
313
+ case Emv_CartAlert_Constants::FIRST_ALERT_REMINDER_ID:
314
+ default:
315
+ $reminderFlag = Emv_CartAlert_Constants::FIRST_ALERT_FLAG;
316
+ break;
317
+ }
318
+
319
+ return $reminderFlag;
320
+ }
321
+
322
+ /**
323
+ * @param string $reminderFlag
324
+ * @return int
325
+ */
326
+ public function getReminderIdFromFlag($reminderFlag)
327
+ {
328
+ $reminderId = null;
329
+ switch ($reminderFlag) {
330
+ case Emv_CartAlert_Constants::SECOND_ALERT_FLAG:
331
+ $reminderId = Emv_CartAlert_Constants::SECOND_ALERT_REMINDER_ID;
332
+ break;
333
+
334
+ case Emv_CartAlert_Constants::THIRD_ALERT_FLAG:
335
+ $reminderId = Emv_CartAlert_Constants::THIRD_ALERT_REMINDER_ID;
336
+ break;
337
+
338
+ case Emv_CartAlert_Constants::FIRST_ALERT_FLAG:
339
+ default:
340
+ $reminderId = Emv_CartAlert_Constants::FIRST_ALERT_REMINDER_ID;
341
+ break;
342
+ }
343
+
344
+ return $reminderId;
345
+ }
346
+
347
+ /**
348
+ * Get shopping cart price rule for a given id.
349
+ * If id is null, get from store config
350
+ *
351
+ * @param string $id
352
+ * @param string $storeId
353
+ * @return Mage_SalesRule_Model_Rule
354
+ */
355
+ public function getShoppingCartPriceRule($id = null, $storeId = null)
356
+ {
357
+ if ($id == null) {
358
+ $id = Mage::getStoreConfig(self::XML_PATH_SHOPING_CART_RULE_ID, $storeId);
359
+ }
360
+
361
+ $key = 'rule_' . $id;
362
+ if (!isset($this->_rules[$key])) {
363
+ $rule = Mage::getModel('salesrule/rule');
364
+ if ($id) {
365
+ // Get the rule you want to make a code from (this should be made in admin panel)
366
+ $rule->load($id); // ID of coupon
367
+ }
368
+ $this->_rules[$key] = $rule;
369
+ }
370
+
371
+ return $this->_rules[$key];
372
+ }
373
+
374
+ /**
375
+ * Get promo code according to a given shopping cart price rule
376
+ *
377
+ * @param string $id
378
+ * @param string $storeId
379
+ * @return boolean | string
380
+ */
381
+ public function getCouponCode($id = null, $storeId = null)
382
+ {
383
+ $rule = $this->getShoppingCartPriceRule($id, $storeId);
384
+
385
+ $code = false;
386
+ if ($rule->getId()) {
387
+ if (
388
+ $rule->getCouponType() == Mage_SalesRule_Model_Rule::COUPON_TYPE_SPECIFIC
389
+ && !$rule->getUseAutoGeneration()
390
+ ) {
391
+ $code = $rule->getCouponCode();
392
+ } else {
393
+ // Define the coupon generator model instance
394
+ // Look at Mage_SalesRule_Model_Coupon_Massgenerator for options
395
+ $generator = Mage::getModel('salesrule/coupon_massgenerator');
396
+
397
+ //This sets custom Prefix-GeneratedValues-Suffix
398
+ $parameters = array(
399
+ 'format' => Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_COUPON_CODE_FORMAT),
400
+ 'dash_every_x_characters' => Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_COUPON_CODE_DASH),
401
+ 'prefix' => Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_COUPON_CODE_PREFIX),
402
+ 'suffix' => Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_COUPON_CODE_SUFFIX),
403
+ 'length' => Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_COUPON_CODE_LENGTH)
404
+ );
405
+
406
+ // Fallback if no params
407
+ if (!empty($parameters['format'])){
408
+ $generator->setFormat(strtolower($parameters['format']));
409
+ }
410
+
411
+ $generator->setDash(!empty($parameters['dash_every_x_characters'])
412
+ ? (int) $parameters['dash_every_x_characters'] : self::DASH_EVERY_X_CHARACTERS
413
+ );
414
+ $generator->setLength(!empty($parameters['length'])? (int) $parameters['length'] : self::COUPON_LENTH);
415
+ $generator->setPrefix(!empty($parameters['prefix'])? $parameters['prefix'] : '');
416
+ $generator->setSuffix(!empty($parameters['suffix'])? $parameters['suffix'] : '');
417
+
418
+ // Set the generator, and coupon type so it's able to generate in Mage
419
+ $rule->setCouponCodeGenerator($generator);
420
+ $coupon = $rule->acquireCoupon();
421
+ if ($coupon) {
422
+ $type = 0;
423
+ if (
424
+ $rule->getCouponType() == Mage_SalesRule_Model_Rule::COUPON_TYPE_SPECIFIC
425
+ && $rule->getUseAutoGeneration()
426
+ ) {
427
+ $type = Mage_SalesRule_Helper_Coupon::COUPON_TYPE_SPECIFIC_AUTOGENERATED;
428
+ }
429
+
430
+ $coupon
431
+ ->setType($type)
432
+ ->save();
433
+
434
+ //This will return something like this Email-ZC6V-ZJWD-Vision if you have configured suffix/prefix parameters
435
+ $code = $coupon->getCode();
436
+ }
437
+ }
438
+ }
439
+
440
+ return $code;
441
+ }
442
+
443
+ /**
444
+ * Support functions - Used for debugging purposes
445
+ */
446
+
447
+ /**
448
+ * Delete all records from quote table (resource)
449
+ */
450
+ private static function deleteQuoteData() {
451
+
452
+ // @var $quotes Mage_Sales_Model_Mysql4_Quote_Collection
453
+ $quotes = Mage::getModel('sales/quote')->getCollection();
454
+ $quotes
455
+ ->addFieldToFilter('items_count', array('gt' => 0))
456
+ ->addFieldToFilter('customer_email', array('notnull' => 1))
457
+ ->addFieldToFilter('is_active', 1)
458
+ ->setOrder('updated_at')
459
+ ->getSelect()->joinLeft(
460
+ array('a' => $quotes->getTable('abandonment/abandonment')),
461
+ 'main_table.entity_id = a.entity_id',
462
+ array('template')
463
+ )
464
+ ->where('a.customer_abandonment_subscribed = ? OR a.customer_abandonment_subscribed IS NULL', 1)
465
+ ->where('a.template <> ? OR a.template IS NULL', Emv_CartAlert_Constants::OUTDATED_FLAG)
466
+ ->where('a.template <> ? OR a.template IS NULL', Emv_CartAlert_Constants::THIRD_ALERT_FLAG);
467
+
468
+ // @var $quote Mage_Sales_Model_Quote
469
+ foreach ($quotes as $quote) {
470
+ $quote->delete();
471
+ }
472
+ }
473
+
474
+ /**
475
+ * Delete records from quote table (resource) for a particular email address
476
+ */
477
+ private static function deleteQuoteDataFor($email) {
478
+
479
+ // @var $quotes Mage_Sales_Model_Mysql4_Quote_Collection
480
+ $quotes = Mage::getModel('sales/quote')->getCollection();
481
+ $quotes
482
+ ->addFieldToFilter('items_count', array('gt' => 0))
483
+ ->addFieldToFilter('customer_email', array('eq' => $email))
484
+ ->addFieldToFilter('is_active', 1)
485
+ ->setOrder('updated_at')
486
+ ->getSelect()->joinLeft(
487
+ array('a' => $quotes->getTable('abandonment/abandonment')),
488
+ 'main_table.entity_id = a.entity_id',
489
+ array('template')
490
+ )
491
+ ->where('a.customer_abandonment_subscribed = ? OR a.customer_abandonment_subscribed IS NULL', 1)
492
+ ->where('a.template <> ? OR a.template IS NULL', Emv_CartAlert_Constants::OUTDATED_FLAG)
493
+ ->where('a.template <> ? OR a.template IS NULL', Emv_CartAlert_Constants::THIRD_ALERT_FLAG);
494
+
495
+ // @var $quote Mage_Sales_Model_Quote
496
+ foreach ($quotes as $quote) {
497
+ $quote->delete();
498
+ }
499
+ }
500
+
501
+ /**
502
+ * Delete all records from abandonment table (resource)
503
+ */
504
+ private static function deleteAbandonmentData() {
505
+ $acs = Mage::getModel('abandonment/abandonment');
506
+ $ac = $acs->getCollection()->load();
507
+
508
+ foreach($ac as $c) {
509
+ $c->delete();
510
+ }
511
+ }
512
+
513
+ /**
514
+ * Print data in all rows from abandonment table (resource)
515
+ */
516
+ private static function printAbandonmentData() {
517
+ $acs = Mage::getModel('abandonment/abandonment');
518
+ $ac = $acs->getCollection()
519
+ ->load();
520
+
521
+ foreach($ac as $c) {
522
+ print_r($c->getData());
523
+ }
524
  }
525
+ }
app/code/community/Emv/CartAlert/Model/Abandonedcart.php DELETED
@@ -1,68 +0,0 @@
1
- <?php
2
-
3
- class Emv_CartAlert_Model_Abandonedcart extends Mage_Core_Model_Abstract {
4
-
5
- public $items;
6
- private $id;
7
- private $cid;
8
- private $cname;
9
- private $total;
10
- private $email;
11
- private $template;
12
- private $unsub_link;
13
- private $cart_link;
14
-
15
- public function __construct($attr) {
16
- $this->_init('abandonment/abandonedcart');
17
- $this->id = $attr['id'];
18
- $this->cid = $attr['cid'];
19
- $this->cname = $attr['cname'];
20
- $this->items = $attr['items'];
21
- $this->total = $attr['total'];
22
- $this->email = $attr['email'];
23
- $this->template = $attr['template'];
24
- $this->unsubLink = $attr['unsub_link'];
25
- $this->cartLink = $attr['cart_link'];
26
- }
27
-
28
- public function __destruct() {}
29
-
30
- public function getId() {
31
- return $this->id;
32
- }
33
-
34
- public function getCustomerId() {
35
- return $this->cid;
36
- }
37
-
38
- public function getCustomerName() {
39
- return $this->cname;
40
- }
41
-
42
- public function getTotalPrice($formatted = false) {
43
- return $formatted ? number_format($this->total, 2) : $this->total;
44
- }
45
-
46
- public function getEmail() {
47
- return $this->email;
48
- }
49
-
50
- public function getTemplate() {
51
- return $this->template;
52
- }
53
-
54
- public function getUnsubLink()
55
- {
56
- return $this->unsubLink;
57
- }
58
-
59
- public function getCartLink()
60
- {
61
- return $this->cartLink;
62
- }
63
-
64
- public function getItems()
65
- {
66
- return $this->items;
67
- }
68
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/CartAlert/Model/Abandonedcartitem.php DELETED
@@ -1,43 +0,0 @@
1
- <?php
2
-
3
- class Emv_CartAlert_Model_Abandonedcartitem extends Mage_Core_Model_Abstract {
4
-
5
- private $attr;
6
-
7
- public function __construct($attr) {
8
- $this->_init('abandonment/abandonedcartitem');
9
- $this->attr = $attr;
10
- }
11
-
12
- /**
13
- * Accessors
14
- */
15
- public function getAttr() {
16
- return $this->attr;
17
- }
18
-
19
- public function getImage() {
20
- return $this->attr['image'];
21
- }
22
-
23
- public function getBasePrice() {
24
- return $this->attr['base_price'];
25
- }
26
-
27
- public function getTotalPrice() {
28
- return $this->attr['total_price'];
29
- }
30
-
31
- public function getName() {
32
- return $this->attr['name'];
33
- }
34
-
35
- public function getQuantity() {
36
- return $this->attr['quantity'];
37
- }
38
-
39
- public function getUrl() {
40
- return $this->attr['url'];
41
- }
42
-
43
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/CartAlert/Model/Abandonment.php CHANGED
@@ -1,15 +1,31 @@
1
  <?php
2
-
 
 
 
 
 
 
3
  class Emv_CartAlert_Model_Abandonment extends Mage_Core_Model_Abstract
4
  {
 
 
 
 
5
  public function _construct()
6
  {
7
- $this->_init('abandonment/abandonment'); // this is location of the resource file.
8
  }
9
 
10
- public function loadByQuoteId($quote_id)
 
 
 
 
 
 
11
  {
12
- $this->setData($this->getResource()->loadByQuoteId($quote_id));
13
  return $this;
14
  }
15
  }
1
  <?php
2
+ /**
3
+ * Abadonment Model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
  class Emv_CartAlert_Model_Abandonment extends Mage_Core_Model_Abstract
10
  {
11
+ /**
12
+ * (non-PHPdoc)
13
+ * @see Varien_Object::_construct()
14
+ */
15
  public function _construct()
16
  {
17
+ $this->_init('abandonment/abandonment');
18
  }
19
 
20
+ /**
21
+ * Load abandonment cart by quote id
22
+ *
23
+ * @param string $quoteId
24
+ * @return Emv_CartAlert_Model_Abandonment
25
+ */
26
+ public function loadByQuoteId($quoteId)
27
  {
28
+ $this->setData($this->getResource()->loadByQuoteId($quoteId));
29
  return $this;
30
  }
31
  }
app/code/community/Emv/CartAlert/Model/Mysql4/Abandonment.php CHANGED
@@ -1,24 +1,36 @@
1
  <?php
2
-
 
 
 
 
 
 
3
  class Emv_CartAlert_Model_Mysql4_Abandonment extends Mage_Core_Model_Mysql4_Abstract {
4
 
 
 
 
 
5
  public function _construct() {
6
  $this->_init('abandonment/abandonment', 'abandonment_id');
7
  }
8
 
9
- public function loadByQuoteId($quote_id)
 
 
 
 
 
 
10
  {
11
  $adapter = $this->_getReadAdapter();
12
 
13
  $select = $adapter->select()
14
  ->from($this->getMainTable())
15
- ->where('entity_id=:entity_id');
16
-
17
- $binds = array(
18
- 'entity_id' => $quote_id
19
- );
20
 
21
- $result = $adapter->fetchRow($select, $binds);
22
 
23
  return count($result) ? $result : Array();
24
  }
1
  <?php
2
+ /**
3
+ * Abandonment Resource Model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
  class Emv_CartAlert_Model_Mysql4_Abandonment extends Mage_Core_Model_Mysql4_Abstract {
10
 
11
+ /**
12
+ * (non-PHPdoc)
13
+ * @see Mage_Core_Model_Resource_Abstract::_construct()
14
+ */
15
  public function _construct() {
16
  $this->_init('abandonment/abandonment', 'abandonment_id');
17
  }
18
 
19
+ /**
20
+ * Get abandonment data for a quote id
21
+ *
22
+ * @param string $quoteId
23
+ * @return array
24
+ */
25
+ public function loadByQuoteId($quoteId)
26
  {
27
  $adapter = $this->_getReadAdapter();
28
 
29
  $select = $adapter->select()
30
  ->from($this->getMainTable())
31
+ ->where('entity_id=?', $quoteId);
 
 
 
 
32
 
33
+ $result = $adapter->fetchRow($select);
34
 
35
  return count($result) ? $result : Array();
36
  }
app/code/community/Emv/CartAlert/Model/Mysql4/Abandonment/Collection.php CHANGED
@@ -1,10 +1,45 @@
1
  <?php
2
-
 
 
 
 
 
 
3
  class Emv_CartAlert_Model_Mysql4_Abandonment_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
4
  {
 
 
 
 
5
  public function _construct() {
6
- //parent::__construct();
7
  $this->_init('abandonment/abandonment');
8
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  }
10
 
1
  <?php
2
+ /**
3
+ * Abandonment Collection Model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
  class Emv_CartAlert_Model_Mysql4_Abandonment_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
10
  {
11
+ /**
12
+ * (non-PHPdoc)
13
+ * @see Mage_Core_Model_Resource_Db_Collection_Abstract::_construct()
14
+ */
15
  public function _construct() {
 
16
  $this->_init('abandonment/abandonment');
17
  }
18
+
19
+ /**
20
+ * Update customer abandonment subscribed flag for a given customer
21
+ *
22
+ * @param string $customerId
23
+ * @param boolean $isSubscribed
24
+ * @return boolean
25
+ */
26
+ public function updateCustomerAbadonementSubscribed($customerId, $isSubscribed)
27
+ {
28
+ if (!$customerId) {
29
+ return false;
30
+ }
31
+
32
+ $customerId = $this->getConnection()->quote($customerId);
33
+ $isSubscribed = $this->getConnection()->quote($isSubscribed);
34
+
35
+ $sql = 'UPDATE ' . $this->getMainTable()
36
+ . ' SET customer_abandonment_subscribed = ' . $isSubscribed
37
+ . ' WHERE customer_id = ' . $customerId
38
+ ;
39
+
40
+ $this->getConnection()->query($sql);
41
+
42
+ return true;
43
+ }
44
  }
45
 
app/code/community/Emv/CartAlert/Model/Mysql4/Orderflag.php ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Order Flag Resource Model - contains the reminder information for a given order
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_CartAlert_Model_Mysql4_Orderflag extends Mage_Core_Model_Mysql4_Abstract {
10
+
11
+ /**
12
+ * (non-PHPdoc)
13
+ * @see Mage_Core_Model_Resource_Abstract::_construct()
14
+ */
15
+ public function _construct() {
16
+ $this->_init('abandonment/order_flag', 'id');
17
+ }
18
+
19
+ /**
20
+ * @param string $orderId
21
+ * @return array
22
+ */
23
+ public function loadByOrderId($orderId)
24
+ {
25
+ $adapter = $this->_getReadAdapter();
26
+
27
+ $select = $adapter->select()
28
+ ->from($this->getMainTable())
29
+ ->where('entity_id=:entity_id');
30
+
31
+ $binds = array(
32
+ 'entity_id' => $orderId
33
+ );
34
+
35
+ $result = $adapter->fetchRow($select, $binds);
36
+
37
+ return count($result) ? $result : Array();
38
+ }
39
+
40
+ /**
41
+ * Get the number of converted carts for a given reminder (1 - first_alert, 2 - second_alert, 3 - third alert)
42
+ *
43
+ * @param string $reminderId
44
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
45
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
46
+ * @return int | boolean - false
47
+ */
48
+ public function getNbConvertedCarts($reminderId, $from = null, $to = null)
49
+ {
50
+ $select = $this->_getReadAdapter()->select()
51
+ ->from($this->getMainTable(), "COUNT(*)")
52
+ ->where("flag = ?", Mage::helper('abandonment')->getReminderFlagFromId($reminderId));
53
+
54
+ if ($from !== null) {
55
+ $select->where('flag_date >= ?', $from);
56
+ }
57
+ if ($to !== null) {
58
+ $select->where('flag_date <= ?', $to);
59
+ }
60
+
61
+ return $this->_getReadAdapter()->fetchOne($select);
62
+ }
63
+
64
+ /**
65
+ * Get the number of converted carts for the first reminder
66
+ *
67
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
68
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
69
+ * @return int | boolean - false
70
+ */
71
+ public function getNbFirstReminderConvertedCarts($from = null, $to = null)
72
+ {
73
+ return $this->getNbConvertedCarts(Emv_CartAlert_Constants::FIRST_ALERT_REMINDER_ID, $from, $to);
74
+ }
75
+
76
+ /**
77
+ * Get the number of converted carts for the second reminder
78
+ *
79
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
80
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
81
+ * @return int | boolean - false
82
+ */
83
+ public function getNbSecondReminderConvertedCarts($from = null, $to = null)
84
+ {
85
+ return $this->getNbConvertedCarts(Emv_CartAlert_Constants::SECOND_ALERT_REMINDER_ID, $from, $to);
86
+ }
87
+
88
+ /**
89
+ * Get the number of converted carts for the third reminder
90
+ *
91
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
92
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
93
+ * @return int | boolean - false
94
+ */
95
+ public function getNbThirdReminderConvertedCarts($from = null, $to = null)
96
+ {
97
+ return $this->getNbConvertedCarts(Emv_CartAlert_Constants::THIRD_ALERT_REMINDER_ID, $from, $to);
98
+ }
99
+
100
+ /**
101
+ * Get total amount's converted carts for a specific reminder ( 1 - first_alert, 2 - second_alert, 3 - third alert)
102
+ *
103
+ * @param string $reminderId
104
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
105
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
106
+ * @return float | boolean - false
107
+ */
108
+ public function getTotalFlagedOrderAmount($reminderId, $from = null, $to = null)
109
+ {
110
+ $select = $this->_getReadAdapter()->select()
111
+ ->from(array('flag' => $this->getMainTable()), array())
112
+ ->join(
113
+ array('order' => $this->getTable('sales/order')),
114
+ 'order.entity_id = flag.entity_id',
115
+ array('SUM(base_grand_total)')
116
+ )
117
+ ->where("flag.flag = ?", Mage::helper('abandonment')->getReminderFlagFromId($reminderId));
118
+
119
+ if ($from !== null) {
120
+ $select->where('flag_date >= ?', $from);
121
+ }
122
+ if ($to !== null) {
123
+ $select->where('flag_date <= ?', $to);
124
+ }
125
+
126
+ return $this->_getReadAdapter()->fetchOne($select);
127
+ }
128
+
129
+ /**
130
+ * Get total amount's converted carts for the first reminder
131
+ *
132
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
133
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
134
+ * @return float | boolean - false
135
+ */
136
+ public function getSumAmountFirstReminderConvertedCarts($from = null, $to = null)
137
+ {
138
+ return $this->getTotalFlagedOrderAmount(Emv_CartAlert_Constants::FIRST_ALERT_REMINDER_ID, $from, $to);
139
+ }
140
+
141
+ /**
142
+ * Get total amount's converted carts for the second reminder
143
+ *
144
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
145
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
146
+ * @return float | boolean - false
147
+ */
148
+ public function getSumAmountSecondReminderConvertedCarts($from = null, $to = null)
149
+ {
150
+ return $this->getTotalFlagedOrderAmount(Emv_CartAlert_Constants::SECOND_ALERT_REMINDER_ID, $from, $to);
151
+ }
152
+
153
+ /**
154
+ * Get total amount's converted carts for the third reminder
155
+ *
156
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
157
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
158
+ * @return float | boolean - false
159
+ */
160
+ public function getSumAmountThirdReminderConvertedCarts($from = null, $to = null)
161
+ {
162
+ return $this->getTotalFlagedOrderAmount(Emv_CartAlert_Constants::THIRD_ALERT_REMINDER_ID, $from, $to);
163
+ }
164
+
165
+ /**
166
+ * Get total amount's converted carts for all reminders
167
+ *
168
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
169
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
170
+ * @return float | boolean - false
171
+ */
172
+ public function getSumAmountConvertedCarts($from = null, $to = null)
173
+ {
174
+ return $this->getSumAmountFirstReminderConvertedCarts($from, $to)
175
+ + $this->getSumAmountSecondReminderConvertedCarts($from, $to)
176
+ + $this->getSumAmountThirdReminderConvertedCarts($from, $to);
177
+ }
178
+
179
+ /**
180
+ * Get the number of converted carts for all reminders
181
+ *
182
+ * @param string $from
183
+ * @param string $to
184
+ * @return number
185
+ */
186
+ public function getSumNbConvertedCarts($from = null, $to = null)
187
+ {
188
+ return $this->getNbFirstReminderConvertedCarts($from, $to)
189
+ + $this->getNbSecondReminderConvertedCarts($from, $to)
190
+ + $this->getNbThirdReminderConvertedCarts($from, $to);
191
+ }
192
+ }
193
+
app/code/community/Emv/CartAlert/Model/Mysql4/Orderflag/Collection.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Converted Cart Collection Model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_CartAlert_Model_Mysql4_Orderflag_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
10
+ {
11
+ /**
12
+ * (non-PHPdoc)
13
+ * @see Mage_Core_Model_Resource_Db_Collection_Abstract::_construct()
14
+ */
15
+ public function _construct() {
16
+ $this->_init('abandonment/orderflag');
17
+ }
18
+
19
+ /**
20
+ * Add additional information
21
+ *
22
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
23
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
24
+ * @return Emv_CartAlert_Model_Mysql4_Orderflag_Collection
25
+ */
26
+ public function joinConvertedCartDetails($from = null, $to = null)
27
+ {
28
+ $this->getSelect()->join(
29
+ array('order' => $this->getTable('sales/order')),
30
+ 'main_table.entity_id = order.entity_id',
31
+ array(
32
+ 'created_at',
33
+ 'customer_email',
34
+ 'customer_firstname',
35
+ 'customer_lastname',
36
+ 'increment_id',
37
+
38
+ 'subtotal',
39
+ 'discount_amount',
40
+ 'shipping_amount',
41
+ 'grand_total',
42
+ 'coupon_code',
43
+ 'total_qty_ordered'
44
+ )
45
+ )
46
+ ;
47
+
48
+ if ($from !== null) {
49
+ $this->getSelect()->where('main_table.flag_date >= ?', $from);
50
+ }
51
+ if ($to !== null) {
52
+ $this->getSelect()->where('main_table.flag_date <= ?', $to);
53
+ }
54
+
55
+ return $this;
56
+ }
57
+
58
+ /**
59
+ * Get all order flaged by a reminder flag
60
+ *
61
+ * @param string $reminderFlag
62
+ * @return Emv_CartAlert_Model_Mysql4_Orderflag_Collection
63
+ */
64
+ public function filterByReminderFlag($reminderFlag)
65
+ {
66
+ $this->addFieldToFilter('flag', $reminderFlag);
67
+
68
+ return $this;
69
+ }
70
+ }
71
+
app/code/community/Emv/CartAlert/Model/Mysql4/Stats.php ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Reminder Statistic Resource Model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_CartAlert_Model_Mysql4_Stats extends Mage_Core_Model_Mysql4_Abstract {
10
+
11
+ /**
12
+ * (non-PHPdoc)
13
+ * @see Mage_Core_Model_Resource_Abstract::_construct()
14
+ */
15
+ public function _construct() {
16
+ $this->_init('abandonment/stats', 'id');
17
+ }
18
+
19
+ /**
20
+ * Get the number of sent emails for a given reminder
21
+ *
22
+ * @param string $reminderId
23
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
24
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
25
+ * @return int
26
+ */
27
+ protected function _getTotalReminderStats($reminderId, $from = null, $to = null)
28
+ {
29
+ $select = $this->_getReadAdapter()->select()
30
+ ->from($this->getMainTable(), "COUNT(*)")
31
+ ->where("reminder_id = ?", $reminderId);
32
+
33
+ if ($from !== null) {
34
+ $select->where('send_date >= ?', $from);
35
+ }
36
+ if ($to !== null) {
37
+ $select->where('send_date <= ?', $to);
38
+ }
39
+
40
+ return $this->_getReadAdapter()->fetchOne($select);
41
+ }
42
+
43
+ /**
44
+ * Get the number of sent emails for the first reminder
45
+ *
46
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
47
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
48
+ * @return int
49
+ */
50
+ public function getTotalFirstReminderSent($from = null, $to = null)
51
+ {
52
+ return $this->_getTotalReminderStats(Emv_CartAlert_Constants::FIRST_ALERT_REMINDER_ID, $from, $to);
53
+ }
54
+
55
+ /**
56
+ * Get the number of sent emails for the second reminder
57
+ *
58
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
59
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
60
+ * @return int
61
+ */
62
+ public function getTotalSecondReminderSent($from = null, $to = null)
63
+ {
64
+ return $this->_getTotalReminderStats(Emv_CartAlert_Constants::SECOND_ALERT_REMINDER_ID, $from, $to);
65
+ }
66
+
67
+ /**
68
+ * Get the number of sent emails for the third reminder
69
+ *
70
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
71
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
72
+ * @return int
73
+ */
74
+ public function getTotalThirdReminderSent($from = null, $to = null)
75
+ {
76
+ return $this->_getTotalReminderStats(Emv_CartAlert_Constants::THIRD_ALERT_REMINDER_ID, $from, $to);
77
+ }
78
+
79
+ /**
80
+ * Get the number of sent emails for all kinds of reminders
81
+ *
82
+ * @param string $from - Varien_Date::DATETIME_INTERNAL_FORMAT
83
+ * @param string $to - Varien_Date::DATETIME_INTERNAL_FORMAT
84
+ * @return int
85
+ */
86
+ public function getSumReminderSent($from = null, $to = null)
87
+ {
88
+ return $this->getTotalFirstReminderSent($from, $to)
89
+ + $this->getTotalSecondReminderSent($from, $to)
90
+ + $this->getTotalThirdReminderSent($from, $to);
91
+ }
92
+ }
93
+
app/code/community/Emv/CartAlert/Model/Mysql4/Stats/Collection.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Reminder Statistic Collection Model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_CartAlert_Model_Mysql4_Stats_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
10
+ {
11
+ /**
12
+ * (non-PHPdoc)
13
+ * @see Mage_Core_Model_Resource_Db_Collection_Abstract::_construct()
14
+ */
15
+ public function _construct() {
16
+ $this->_init('abandonment/stats');
17
+ }
18
+ }
19
+
app/code/community/Emv/CartAlert/Model/Observer.php CHANGED
@@ -3,223 +3,257 @@
3
  /**
4
  * Observer - checks for abandoned carts and sends the data to campaign commander
5
  *
 
 
 
6
  */
7
  class Emv_CartAlert_Model_Observer extends Mage_Core_Model_Abstract
8
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
  /**
11
  * Observer to check for abandoned shopping carts
12
- *
13
- * @return null
14
  */
15
  public function processAbandonedCarts ()
16
  {
17
- if(Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_ENABLED) == 1||
18
- Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_ENABLED) == 1 ||
19
- Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_ENABLED) == 1)
20
- {
 
 
 
 
 
21
  /* @var $helper Emv_CartAlert_Helper_Data */
22
  $helper = Mage::helper('abandonment');
23
 
24
- // prepare query for abandoned quotes
25
- $minHour = Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_DELAY);
26
-
27
- /* @var $date Zend_Date */
28
- $date = new Zend_Date();
29
-
30
- $date->sub($minHour, Zend_Date::HOUR);
31
-
32
- $from = $date->toString('YYYY-MM-dd HH:mm:ss');
33
-
34
- // get abandoned quotes
35
- /* @var $quotes Mage_Sales_Model_Mysql4_Quote_Collection */
36
- $quotes = Mage::getModel('sales/quote')->getCollection();
37
- $quotes
38
- ->addFieldToFilter('updated_at', array('to' => $from))
39
- ->addFieldToFilter('items_count', array('gt' => 0))
40
- ->addFieldToFilter('customer_email', array('notnull' => 1))
41
- ->addFieldToFilter('is_active', 1)
42
- ->setOrder('updated_at')
43
- ->getSelect()->joinLeft( array('a' => $quotes->getTable('abandonment/abandonment')),
44
- 'main_table.entity_id = a.entity_id', array('template'))
45
- ->where('a.customer_abandonment_subscribed = ? OR a.customer_abandonment_subscribed IS NULL', 1)
46
- ->where('a.template <> ? OR a.template IS NULL', Emv_CartAlert_Constants::OUTDATED_FLAG)
47
- ->where('a.template <> ? OR a.template IS NULL', Emv_CartAlert_Constants::THIRD_ALERT_FLAG);
48
-
49
  /* @var $quote Mage_Sales_Model_Quote */
50
- foreach ($quotes as $quote)
51
- {
 
 
 
 
52
 
53
  // search abandoned carts for this particular quote
54
  $abandonment = Mage::getModel('abandonment/abandonment')->loadByQuoteId($quote->getEntityId());
55
- $data = $abandonment->getData();
56
 
57
- if (! $abandonment->getId())
58
- {
59
  $abandonment->setEntityId($quote->getId())
60
- ->setCustomerAbandonmentSubscribed($quote->getCustomer()->getAbandonmentSubscribed());
61
- $data = $abandonment->getData();
 
 
62
  }
63
 
64
- // parameters for abandoned cart
65
- $cart['items'] = array();
66
- $cart['email'] = $quote->getCustomerEmail();
67
- $cart['cid'] = $quote->getCustomerId();
68
- $cart['id'] = $quote->getEntityId();
69
- $cart['total'] = $quote->getGrandTotal();
70
- $cart['unsub_link'] = $helper->getUnsubscribeLink($quote); // get the unsubscription link (depends on whether the user was logged in)
71
- $cart['cart_link'] = $helper->getCartLink($quote); // get the cart link (depends on whether the user was logged in)
72
- $cart['updated'] = $quote->getUpdatedAt();
73
- $cart['count'] = $quote->getItemsCount();
74
- $cart['cname'] = ($quote->getCustomerPrefix() ? $quote->getCustomerPrefix() . ' ' : '') .
75
- $quote->getCustomerFirstname() . ' ' .
76
- ($quote->getCustomerMiddlename() ? $quote->getCustomerMiddlename() . ' ' : '') .
77
- $quote->getCustomerLastname() .
78
- ($quote->getCustomerSuffix() ? ' ' . $quote->getCustomerSuffix() : '');
79
-
80
  // if the quote has not yet been processed for abandonment, set it up for processing
81
- if (empty($data))
82
- {
83
- $previous_template = Emv_CartAlert_Constants::TO_BE_PROCESSED_FLAG;
84
  }
85
- else
86
- {
87
- // set up the cart for updating
88
- $previous_template = $abandonment->getTemplate();
89
- }
90
-
91
- // get updated template
92
- $updated_template = $this->getUpdatedTemplate(
93
- $this->getTimeAbandoned($quote->getUpdatedAt()), $previous_template,
94
- $quote->getStoreId());
95
-
96
- if($updated_template != null)
97
- {
98
- if ($previous_template != $updated_template)
99
- {
100
- // insert/update the abandoned cart
101
- $abandonment->setTemplate($updated_template)->save();
102
- }
103
-
104
- $cart['template'] = $updated_template;
105
 
106
- // get items in quote
107
- $items = $quote->getAllVisibleItems();
108
-
109
- // for each item in quote
110
- foreach ($items as $item)
111
- {
112
- // get item attributes
113
- $item = $this->getItemAttributes($item);
114
-
115
- // create a new Abandoned Cart Item
116
- $cart['items'][] = Mage::getModel('abandonment/abandonedcartitem', $item);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  }
 
118
 
119
- // create a new Abandoned Cart
120
- $recent_cart = Mage::getModel('abandonment/abandonedcart', $cart);
121
-
122
- // decide which email to send
123
- switch ($recent_cart->getTemplate()) {
124
-
125
- case Emv_CartAlert_Constants::FIRST_ALERT_FLAG:
126
- $helper->sendFirstReminder($recent_cart, $quote->getStoreId());
127
- break;
128
-
129
- case Emv_CartAlert_Constants::SECOND_ALERT_FLAG:
130
- $helper->sendSecondReminder($recent_cart, $quote->getStoreId());
131
- break;
132
-
133
- case Emv_CartAlert_Constants::THIRD_ALERT_FLAG:
134
- $helper->sendThirdReminder($recent_cart, $quote->getStoreId());
135
- break;
136
-
137
- default:
138
- break;
139
- }
140
  }
141
  }
142
  }
 
 
 
143
  }
144
 
145
  /**
146
- * Get the item attributes we need
 
 
 
 
 
 
147
  */
148
- public function getItemAttributes ($item)
149
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
150
 
151
- $item_attr = array();
152
-
153
- // get the product image
154
- $item_attr['image'] = $this->_getProductImageUrl($item->getProduct());
155
-
156
- // get the item name
157
- $item_attr['name'] = $item->getName();
158
-
159
- // get the item URL
160
- $item_attr['url'] = Mage::getUrl() . $item->getProduct()->getUrlPath();
161
-
162
- // get the item base price
163
- $item_attr['base_price'] = $item->getBasePrice();
164
-
165
- // get the item total price
166
- $item_attr['total_price'] = $item->getBaseRowTotal();
167
-
168
- // get the item quantity
169
- $item_attr['quantity'] = $item->getQty();
170
-
171
- return $item_attr;
172
- }
173
 
174
- /**
175
- * Convert time abandoned to minutes
176
- * @return Zend_Date
177
- */
178
- public function getTimeAbandoned($from)
179
- {
180
- return new Zend_Date($from , Zend_Date::ISO_8601);
181
- }
182
 
183
- /**
184
- * Get the updated template
185
- * Returns the same template if time frame hasn't changed
186
- */
187
- public function getUpdatedTemplate(Zend_Date $lastUpdate, $template, $store = null)
188
- {
189
- $updated_template = $template;
190
-
191
- $firstAlertDelay = Zend_Date::now()->subHour(Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_DELAY, $store));
192
- $secondAlertDelay = Zend_Date::now()->subHour(Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_DELAY, $store));
193
- $thirdAlertDelay = Zend_Date::now()->subHour(Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_DELAY, $store));
194
- $outdatedDelay = Zend_Date::now()->subHour(Emv_CartAlert_Constants::OUTDATED_CART_DELAY);
195
-
196
- if ($lastUpdate->isEarlier($firstAlertDelay) && $lastUpdate->isLater($secondAlertDelay) &&
197
- $template != Emv_CartAlert_Constants::FIRST_ALERT_FLAG &&
198
- Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_ENABLED))
199
- {
200
- $updated_template = Emv_CartAlert_Constants::FIRST_ALERT_FLAG;
201
- }
202
- else if ($lastUpdate->isEarlier($secondAlertDelay) && $lastUpdate->isLater($thirdAlertDelay) &&
203
- $template != Emv_CartAlert_Constants::SECOND_ALERT_FLAG &&
204
- Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_ENABLED))
205
- {
206
- $updated_template = Emv_CartAlert_Constants::SECOND_ALERT_FLAG;
207
- }
208
- else if ($lastUpdate->isEarlier($thirdAlertDelay) && $lastUpdate->isLater($outdatedDelay)
209
- && $template != Emv_CartAlert_Constants::THIRD_ALERT_FLAG &&
210
- Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_ENABLED))
211
- {
212
- $updated_template = Emv_CartAlert_Constants::THIRD_ALERT_FLAG;
213
- }else if ($lastUpdate->isEarlier($outdatedDelay))
214
- {
215
- $updated_template = Emv_CartAlert_Constants::OUTDATED_FLAG;
216
- }
217
- else
218
- {
219
- $updated_template = null;
220
  }
221
 
222
- return $updated_template;
223
  }
224
 
225
  /**
@@ -239,43 +273,38 @@ class Emv_CartAlert_Model_Observer extends Mage_Core_Model_Abstract
239
  $isSubscribed = $customer->getAbandonmentSubscribed();
240
 
241
  /* @var $abandonments Emv_CartAlert_Model_Mysql4_Abandonment_Collection */
242
- $abandonments = Mage::getResourceModel('abandonment/abandonment_collection');
243
- $abandonments->getSelect()->join(Array('quote' => $abandonments->getTable('sales/quote')),
244
- 'quote.entity_id = main_table.entity_id', 'customer_id');
245
- $abandonments->addFieldToFilter('customer_id', $customer->getId())
246
- ->addFieldToFilter('customer_abandonment_subscribed', Array('eq' => $isSubscribed));
247
-
248
- $abandonments->setDataToAll('customer_abandonment_subscribed', $isSubscribed)->save();
249
 
250
  return $this;
251
  }
252
 
253
  /**
254
- * Retrieves an image URL for the product, if it exists.
255
- * The priority is: thumbnail -> small image -> image -> Magento's placeholder.
256
- *
257
- * @param Mage_Catalog_Model_Product $product
258
- * @return string the image's URL
259
  */
260
- protected function _getProductImageUrl ($product)
261
  {
262
- if (($product->getThumbnail() != 'no_selection'))
263
- {
264
- return Mage::helper('catalog/image')->init($product, 'thumbnail')
265
- ->resize(265)
266
- ->__toString();
267
- }
268
- elseif (($product->getSmallImage() != 'no_selection'))
269
- {
270
- return Mage::helper('catalog/image')->init($product, 'small_image')
271
- ->resize(265)
272
- ->__toString();
273
  }
274
- else
275
- {
276
- return Mage::helper('catalog/image')->init($product, 'image')
277
- ->resize(265)
278
- ->__toString();
 
 
 
 
279
  }
 
 
 
280
  }
281
  }
3
  /**
4
  * Observer - checks for abandoned carts and sends the data to campaign commander
5
  *
6
+ * @category Emv
7
+ * @package Emv_CartAlert
8
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
9
  */
10
  class Emv_CartAlert_Model_Observer extends Mage_Core_Model_Abstract
11
  {
12
+ /**
13
+ * Get abandoned quotes to send reminders
14
+ * @return Mage_Sales_Model_Mysql4_Quote_Collection
15
+ */
16
+ protected function _getConcernedQuotes()
17
+ {
18
+ // prepare query for abandoned quotes
19
+ $minHour = Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_DELAY);
20
+
21
+ // all date criteria need to be in utc timezone
22
+ $now = Mage::app()->getLocale()->date();
23
+
24
+ /* @var $date Zend_Date */
25
+ $from = Mage::app()->getLocale()->utcDate(null, $now);
26
+ $from->subHour($minHour);
27
+ $from = $from->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
28
+
29
+ // the expiration date
30
+ $expDate = Mage::app()->getLocale()->utcDate(null, $now);
31
+ $expDate->sub(Emv_CartAlert_Constants::OUTDATED_CART_DELAY, Zend_Date::HOUR);
32
+ $expDate = $expDate->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
33
+
34
+ // get abandoned quotes
35
+ /* @var $quotes Mage_Sales_Model_Mysql4_Quote_Collection */
36
+ $quotes = Mage::getModel('sales/quote')->getCollection();
37
+ $select = $quotes->getSelect();
38
+ // make a left join to abandonment table in order to know which template has been used
39
+ $select->joinLeft(
40
+ array('a' => $quotes->getTable('abandonment/abandonment')),
41
+ 'main_table.entity_id = a.entity_id',
42
+ array('template')
43
+ );
44
+
45
+ //get customers' abandonment_subscribed value
46
+ $attr = Mage::getModel('customer/customer')->getAttribute('abandonment_subscribed');
47
+ $adapter = $quotes->getConnection();
48
+ if ($attr->getAttributeId()) {
49
+ $select->joinLeft(
50
+ array('abandonment_subscribed' => $attr->getBackend()->getTable()),
51
+ $adapter->quoteInto(
52
+ 'main_table.customer_id = abandonment_subscribed.entity_id'
53
+ . ' AND abandonment_subscribed.attribute_id = ?',
54
+ $attr->getAttributeId()
55
+ ),
56
+ // by default, we activate abandonment reminder subscription for all clients
57
+ array('abandonment_subscribed_value' => 'IF(abandonment_subscribed.value IS NULL, 1, abandonment_subscribed.value)')
58
+ );
59
+ }
60
+
61
+ $select->where('a.customer_abandonment_subscribed = ? OR a.customer_abandonment_subscribed IS NULL', 1)
62
+ ->where('a.template <> ? OR a.template IS NULL', Emv_CartAlert_Constants::OUTDATED_FLAG)
63
+ ->where('a.template <> ? OR a.template IS NULL', Emv_CartAlert_Constants::THIRD_ALERT_FLAG)
64
+ ;
65
+
66
+ $quotes
67
+ ->addFieldToFilter('updated_at', array('to' => $from, 'from' => $expDate))
68
+ ->addFieldToFilter('items_count', array('gt' => 0))
69
+ ->addFieldToFilter('customer_email', array('notnull' => 1)) // a quote with a valid email address
70
+ ->addFieldToFilter('is_active', 1) // only get active quotes
71
+ ->setOrder('updated_at')
72
+ ;
73
+
74
+ return $quotes;
75
+ }
76
 
77
  /**
78
  * Observer to check for abandoned shopping carts
 
 
79
  */
80
  public function processAbandonedCarts ()
81
  {
82
+ // save the current store so that this observer doesn't interfere with any other functions
83
+ $currentStore = Mage::app()->getStore()->getStoreId();
84
+
85
+ // if Shopping Cart Abandonment is enabled
86
+ if(
87
+ Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_ENABLED) == 1
88
+ || Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_ENABLED) == 1
89
+ || Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_ENABLED) == 1
90
+ ) {
91
  /* @var $helper Emv_CartAlert_Helper_Data */
92
  $helper = Mage::helper('abandonment');
93
 
94
+ $quotes = $this->_getConcernedQuotes();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  /* @var $quote Mage_Sales_Model_Quote */
96
+ foreach ($quotes as $quote) {
97
+ // Set the current store
98
+ Mage::app()->setCurrentStore($quote->getStoreId());
99
+
100
+ // flag to indicate if we need to save the abandonment
101
+ $needToSaveAbandonment = false;
102
 
103
  // search abandoned carts for this particular quote
104
  $abandonment = Mage::getModel('abandonment/abandonment')->loadByQuoteId($quote->getEntityId());
 
105
 
106
+ if (!$abandonment->getId()) {
 
107
  $abandonment->setEntityId($quote->getId())
108
+ ->setCustomerAbandonmentSubscribed((boolean)$quote->getData('abandonment_subscribed_value'))
109
+ ->setCustomerId($quote->getCustomerId())
110
+ ;
111
+ $needToSaveAbandonment = true;
112
  }
113
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
  // if the quote has not yet been processed for abandonment, set it up for processing
115
+ $previousTemplate = $abandonment->getTemplate();
116
+ if (empty($previousTemplate)) {
117
+ $previousTemplate = Emv_CartAlert_Constants::TO_BE_PROCESSED_FLAG;
118
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
 
120
+ // only send email if client allows to do that
121
+ if ($quote->getData('abandonment_subscribed_value')) {
122
+ // get updated template
123
+ $updatedTemplate = $this->getUpdatedTemplate(
124
+ $quote,
125
+ $previousTemplate,
126
+ $quote->getStoreId()
127
+ );
128
+
129
+ if ($updatedTemplate != null) {
130
+ $preparedCustomerName = ($quote->getCustomerPrefix() ? $quote->getCustomerPrefix() . ' ' : '')
131
+ . $quote->getCustomerFirstname()
132
+ . ' ' . ($quote->getCustomerMiddlename() ? $quote->getCustomerMiddlename() . ' ' : '')
133
+ . $quote->getCustomerLastname()
134
+ . ($quote->getCustomerSuffix() ? ' ' . $quote->getCustomerSuffix() : '')
135
+ ;
136
+ $quote->setPreparedCustomerName($preparedCustomerName);
137
+
138
+ // set the unsubscription link (depends on whether the user was logged in)
139
+ $quote->setUnsubLink($helper->getUnsubscribeLink($quote));
140
+ // set the cart link (depends on whether the user was logged in)
141
+ $quote->setCartLink($helper->getCartLink($quote, $updatedTemplate));
142
+ // set the store link (depends on whether the user was logged in)
143
+ $quote->setStoreLink($helper->getStoreLink($quote, $updatedTemplate));
144
+ // set the reminder template will be used to send
145
+ $quote->setReminderTemplate($updatedTemplate);
146
+
147
+ // set formated grand total
148
+ $quote->setPreparedGrandToTal(Mage::helper('checkout')->formatPrice($quote->getGrandTotal(), true, true));
149
+
150
+ if ($previousTemplate != $updatedTemplate) {
151
+ // update the reminder template will be used to send
152
+ $abandonment->setTemplate($updatedTemplate);
153
+
154
+ $rule = $helper->getShoppingCartPriceRule();
155
+ if ($rule->getId() != $abandonment->getShoppingCartRuleId()) {
156
+ $abandonment->setShoppingCartRuleId($rule->getId());
157
+ $abandonment->setCouponCode($helper->getCouponCode($rule->getId()));
158
+ }
159
+
160
+ $needToSaveAbandonment = true;
161
+ }
162
+
163
+ $helper->sendReminder($quote, $quote->getStoreId(), $abandonment);
164
  }
165
+ }
166
 
167
+ if ($needToSaveAbandonment) {
168
+ $abandonment->save();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
169
  }
170
  }
171
  }
172
+
173
+ // return the store to normal
174
+ Mage::app()->setCurrentStore($currentStore);
175
  }
176
 
177
  /**
178
+ * Indicate which reminder template can be used to send.
179
+ * Return null if we can't send the reminder else the reminder name
180
+ *
181
+ * @param Mage_Sales_Model_Quote $quote
182
+ * @param string $currentTemplate
183
+ * @param string $store
184
+ * @return NULL | string
185
  */
186
+ public function getUpdatedTemplate(Mage_Sales_Model_Quote $quote, $currentTemplate, $store = null)
187
  {
188
+ // By default, we don't allow to send any reminder
189
+ $updatedTemplate = null;
190
+ $locale = Mage::app()->getLocale();
191
+
192
+ // By default, Magento uses UTC as its timezone, so all date criteria need to be in utc timezone
193
+ /* @var $lastUpdate Zend_Date */
194
+ $lastUpdate = $locale->date($quote->getUpdatedAt(), Varien_Date::DATETIME_INTERNAL_FORMAT);
195
+ $lastUpdate = $locale->utcDate(null, $lastUpdate);
196
+
197
+ // now
198
+ $now = $locale->date(null, Varien_Date::DATETIME_INTERNAL_FORMAT);
199
+
200
+ // expiration date
201
+ $expirationDate = $locale->utcDate(null, $now);
202
+ $expirationDate->subHour(Emv_CartAlert_Constants::OUTDATED_CART_DELAY);
203
+
204
+ if ($expirationDate->isLater($lastUpdate)) {
205
+ $updatedTemplate = Emv_CartAlert_Constants::OUTDATED_FLAG;
206
+ } else { // if the template is not yet outdated
207
+ $firstAlertDelay = false;
208
+ $secondAlertDelay = false;
209
+ $thirdAlertDelay = false;
210
+
211
+ if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_ENABLED, $store)) {
212
+ $firstAlertDelay = $locale->utcDate(null, $now);
213
+ $firstAlertDelay->subHour(
214
+ Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_DELAY, $store)
215
+ );
216
+ }
217
 
218
+ if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_ENABLED, $store)) {
219
+ $secondAlertDelay = $locale->utcDate(null, $now);
220
+ $secondAlertDelay->subHour(
221
+ Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_DELAY, $store)
222
+ );
223
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
224
 
225
+ if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_ENABLED, $store)) {
226
+ $thirdAlertDelay = $locale->utcDate(null, $now);
227
+ $thirdAlertDelay->subHour(
228
+ Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_DELAY, $store)
229
+ );
230
+ }
 
 
231
 
232
+ // determine which reminder (first, second, third) needs to be sent
233
+ if (
234
+ $currentTemplate == Emv_CartAlert_Constants::TO_BE_PROCESSED_FLAG
235
+ && $firstAlertDelay
236
+ && $firstAlertDelay->isLater($lastUpdate)
237
+ ) {
238
+ $updatedTemplate = Emv_CartAlert_Constants::FIRST_ALERT_FLAG;
239
+ } else if (
240
+ // only send second reminder when the first one was sent, and the second delay is later than the last update
241
+ $currentTemplate == Emv_CartAlert_Constants::FIRST_ALERT_FLAG
242
+ && $secondAlertDelay
243
+ && $secondAlertDelay->isLater($lastUpdate)
244
+ ) {
245
+ $updatedTemplate = Emv_CartAlert_Constants::SECOND_ALERT_FLAG;
246
+ } else if (
247
+ $currentTemplate == Emv_CartAlert_Constants::SECOND_ALERT_FLAG
248
+ && $thirdAlertDelay
249
+ && $thirdAlertDelay->isLater($lastUpdate)
250
+ ) {
251
+ // only send second reminder when the second one was sent, and the third delay is later than the last update
252
+ $updatedTemplate = Emv_CartAlert_Constants::THIRD_ALERT_FLAG;
253
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  }
255
 
256
+ return $updatedTemplate;
257
  }
258
 
259
  /**
273
  $isSubscribed = $customer->getAbandonmentSubscribed();
274
 
275
  /* @var $abandonments Emv_CartAlert_Model_Mysql4_Abandonment_Collection */
276
+ $abandonments = Mage::getResourceModel('abandonment/abandonment_collection')
277
+ ->updateCustomerAbadonementSubscribed($customer->getId(), $isSubscribed);
 
 
 
 
 
278
 
279
  return $this;
280
  }
281
 
282
  /**
283
+ * Handle order save after event
284
+ * @param Varien_Event_Observer $observer
 
 
 
285
  */
286
+ public function handleOrderSaveAfter(Varien_Event_Observer $observer)
287
  {
288
+ /* @var $order Mage_Sales_Model_Order */
289
+ $order = $observer->getEvent()->getOrder();
290
+
291
+ $session = Mage::getSingleton('customer/session');
292
+
293
+ if (!$session->getData('abandonment_flag')) {
294
+ return;
 
 
 
 
295
  }
296
+
297
+ /* @var $orderFlag Emailvision_Abandonment_Model_Orderflag */
298
+ $orderFlag = Mage::getModel('abandonment/orderflag')->loadByOrderId($order->getId());
299
+
300
+ if (!$orderFlag->getId()) {
301
+ $orderFlag->setEntityId($order->getId());
302
+ $orderFlag->setFlag($session->getData('abandonment_flag'));
303
+ $orderFlag->setFlagDate($session->getData('abandonment_date'));
304
+ $orderFlag->save();
305
  }
306
+
307
+ $session->unsetData('abandonment_flag');
308
+ $session->unsetData('abandonment_date');
309
  }
310
  }
app/code/community/Emv/CartAlert/Model/Orderflag.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Coverted Cart Model - contains the reminder information for a given order
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_CartAlert_Model_Orderflag extends Mage_Core_Model_Abstract
10
+ {
11
+ /**
12
+ * (non-PHPdoc)
13
+ * @see Varien_Object::_construct()
14
+ */
15
+ public function _construct()
16
+ {
17
+ $this->_init('abandonment/orderflag');
18
+ }
19
+
20
+ /**
21
+ * Load Order flag for a given order id
22
+ * @param string $orderId
23
+ * @return Emv_CartAlert_Model_Orderflag
24
+ */
25
+ public function loadByOrderId($orderId)
26
+ {
27
+ $this->setData($this->getResource()->loadByOrderId($orderId));
28
+ return $this;
29
+ }
30
+ }
app/code/community/Emv/CartAlert/Model/Resource/Setup.php CHANGED
@@ -1,6 +1,16 @@
1
  <?php
 
 
 
 
 
 
 
2
  class Emv_CartAlert_Model_Resource_Setup extends Mage_Eav_Model_Entity_Setup
3
  {
 
 
 
4
  public function getDefaultEntities()
5
  {
6
  $entities = parent::getDefaultEntities();
@@ -8,25 +18,27 @@ class Emv_CartAlert_Model_Resource_Setup extends Mage_Eav_Model_Entity_Setup
8
  return $entities;
9
  }
10
 
 
 
 
11
  public function getAdditionalEntities()
12
  {
13
  return Array(
14
  'customer' => Array(
15
  'attributes' => Array(
16
-
17
  'abandonment_subscribed' => Array(
18
- 'label' => 'Subscribed from abandonned cart notifications',
19
- 'type' => 'int',
20
- 'input' => 'select',
21
- 'is_visible' => true,
22
- 'source' => 'eav/entity_attribute_source_boolean',
23
- 'required' => true,
24
- 'user_defined' => true,
25
- 'default' => true,
26
- 'sort_order' => 1000,
27
- 'system' => false,
28
- 'position' => 1000,
29
- 'adminhtml_only' => 0,
30
  ),
31
  )
32
  )
@@ -39,33 +51,30 @@ class Emv_CartAlert_Model_Resource_Setup extends Mage_Eav_Model_Entity_Setup
39
  public function updateCustomerForms()
40
  {
41
  $entities = $this->getAdditionalEntities();
 
42
  $attributes = $entities['customer']['attributes'];
43
- foreach ($attributes as $attributeCode => $data)
44
- {
45
  $eavConfig = Mage::getSingleton('eav/config');
46
  $attribute = $eavConfig->getAttribute('customer', $attributeCode);
47
- if (!$attribute)
48
- {
49
  continue;
50
  }
51
- if (false === ($attribute->getData('is_system') == 1 && $attribute->getData('is_visible') == 0))
52
- {
53
  $usedInForms = array(
54
  'customer_account_create',
55
  'customer_account_edit',
56
  'checkout_register',
57
  );
58
- if (!empty($data['adminhtml_only']))
59
- {
60
  $usedInForms = array('adminhtml_customer');
61
- } else
62
- {
63
  $usedInForms[] = 'adminhtml_customer';
64
  }
65
- if (!empty($data['admin_checkout']))
66
- {
67
  $usedInForms[] = 'adminhtml_checkout';
68
  }
 
69
  $attribute->setData('used_in_forms', $usedInForms);
70
  }
71
 
1
  <?php
2
+ /**
3
+ * Set up for module cart alert
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
  class Emv_CartAlert_Model_Resource_Setup extends Mage_Eav_Model_Entity_Setup
10
  {
11
+ /**
12
+ * @return array
13
+ */
14
  public function getDefaultEntities()
15
  {
16
  $entities = parent::getDefaultEntities();
18
  return $entities;
19
  }
20
 
21
+ /**
22
+ * @return array
23
+ */
24
  public function getAdditionalEntities()
25
  {
26
  return Array(
27
  'customer' => Array(
28
  'attributes' => Array(
 
29
  'abandonment_subscribed' => Array(
30
+ 'label' => 'Subscribed from abandonned cart notifications',
31
+ 'type' => 'int',
32
+ 'input' => 'select',
33
+ 'is_visible' => true,
34
+ 'source' => 'eav/entity_attribute_source_boolean',
35
+ 'required' => true,
36
+ 'user_defined' => true,
37
+ 'default' => true,
38
+ 'sort_order' => 1000,
39
+ 'system' => false,
40
+ 'position' => 1000,
41
+ 'adminhtml_only' => 0,
42
  ),
43
  )
44
  )
51
  public function updateCustomerForms()
52
  {
53
  $entities = $this->getAdditionalEntities();
54
+
55
  $attributes = $entities['customer']['attributes'];
56
+ foreach ($attributes as $attributeCode => $data) {
 
57
  $eavConfig = Mage::getSingleton('eav/config');
58
  $attribute = $eavConfig->getAttribute('customer', $attributeCode);
59
+ if (!$attribute) {
 
60
  continue;
61
  }
62
+ if (false === ($attribute->getData('is_system') == 1 && $attribute->getData('is_visible') == 0)) {
 
63
  $usedInForms = array(
64
  'customer_account_create',
65
  'customer_account_edit',
66
  'checkout_register',
67
  );
68
+
69
+ if (!empty($data['adminhtml_only'])) {
70
  $usedInForms = array('adminhtml_customer');
71
+ } else {
 
72
  $usedInForms[] = 'adminhtml_customer';
73
  }
74
+ if (!empty($data['admin_checkout'])) {
 
75
  $usedInForms[] = 'adminhtml_checkout';
76
  }
77
+
78
  $attribute->setData('used_in_forms', $usedInForms);
79
  }
80
 
app/code/community/Emv/CartAlert/Model/Stats.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Reminder Statistic Model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_CartAlert_Model_Stats extends Mage_Core_Model_Abstract
10
+ {
11
+ /**
12
+ * (non-PHPdoc)
13
+ * @see Varien_Object::_construct()
14
+ */
15
+ public function _construct()
16
+ {
17
+ $this->_init('abandonment/stats');
18
+ }
19
+ }
app/code/community/Emv/CartAlert/controllers/CustomerController.php CHANGED
@@ -1,5 +1,11 @@
1
  <?php
2
-
 
 
 
 
 
 
3
  class Emv_CartAlert_CustomerController extends Mage_Core_Controller_Front_Action
4
  {
5
  /**
@@ -21,33 +27,100 @@ class Emv_CartAlert_CustomerController extends Mage_Core_Controller_Front_Action
21
  */
22
  public function unsubscribeAction()
23
  {
 
 
24
  /* @var $helper Emv_CartAlert_Helper_Data */
25
  $helper = Mage::helper('abandonment');
26
 
27
  /* @var $session Mage_Customer_Model_Session */
28
  $session = Mage::getSingleton('customer/session');
29
-
30
- // No need to test if the customer is logged in: guests are automatically redirected to the login page
31
-
32
  /* @var $customer Mage_Customer_Model_Customer */
33
  $customer = $session->getCustomer();
34
 
35
  /* @var $session Mage_Checkout_Model_Session */
36
  $session = Mage::getSingleton('checkout/session');
37
- if (!$customer->getAbandonmentSubscribed())
38
- {
39
  $message = $helper->__('You are already unsubscribed from abandoned carts notifications.');
40
  $session->addError($message);
41
- }
42
- else
43
- {
44
  $customer->setAbandonmentSubscribed(0)->save();
45
  $message = $helper->__('You were successfully unsubscribed from abandoned carts notifications.');
46
  $session->addSuccess($message);
47
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
48
  $this->_redirect('checkout/cart/index');
49
  }
50
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  public function manageAction()
52
  {
53
  $this->loadLayout();
@@ -57,36 +130,38 @@ class Emv_CartAlert_CustomerController extends Mage_Core_Controller_Front_Action
57
  if ($block = $this->getLayout()->getBlock('customer_abandonment')) {
58
  $block->setRefererUrl($this->_getRefererUrl());
59
  }
60
- $this->getLayout()->getBlock('head')->setTitle($this->__('Cart Reminder Subscription'));
61
  $this->renderLayout();
62
  }
63
 
 
 
 
64
  public function saveAction()
65
  {
66
  if (!$this->_validateFormKey()) {
67
  return $this->_redirect('customer/account/');
68
  }
 
69
  try {
 
 
70
  Mage::getSingleton('customer/session')->getCustomer()
71
- ->setAbandonmentSubscribed((boolean)$this->getRequest()->getParam('is_subscribed', false))
72
- ->save();
73
- if ((boolean)$this->getRequest()->getParam('is_subscribed', false)) {
74
- Mage::getSingleton('customer/session')->addSuccess($this->__('The subscription has been saved.'));
 
 
75
  } else {
76
- Mage::getSingleton('customer/session')->addSuccess($this->__('The subscription has been removed.'));
 
77
  }
 
 
 
78
  }
79
- catch (Exception $e) {
80
- Mage::getSingleton('customer/session')->addError($this->__('An error occurred while saving your subscription.'));
81
- }
82
- $this->_redirect('customer/account/');
83
- }
84
 
85
- /**
86
- * Redirect the user to the cart
87
- */
88
- public function cartAction()
89
- {
90
- $this->_redirect('checkout/cart/index');
91
  }
92
  }
1
  <?php
2
+ /**
3
+ * Customer controller
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
  class Emv_CartAlert_CustomerController extends Mage_Core_Controller_Front_Action
10
  {
11
  /**
27
  */
28
  public function unsubscribeAction()
29
  {
30
+ // No need to test if the customer is logged in: guests are automatically redirected to the login page
31
+
32
  /* @var $helper Emv_CartAlert_Helper_Data */
33
  $helper = Mage::helper('abandonment');
34
 
35
  /* @var $session Mage_Customer_Model_Session */
36
  $session = Mage::getSingleton('customer/session');
 
 
 
37
  /* @var $customer Mage_Customer_Model_Customer */
38
  $customer = $session->getCustomer();
39
 
40
  /* @var $session Mage_Checkout_Model_Session */
41
  $session = Mage::getSingleton('checkout/session');
42
+ if (!$customer->getAbandonmentSubscribed()) {
 
43
  $message = $helper->__('You are already unsubscribed from abandoned carts notifications.');
44
  $session->addError($message);
45
+ } else {
 
 
46
  $customer->setAbandonmentSubscribed(0)->save();
47
  $message = $helper->__('You were successfully unsubscribed from abandoned carts notifications.');
48
  $session->addSuccess($message);
49
  }
50
+
51
+ $this->_redirect('checkout/cart/index');
52
+ }
53
+
54
+ /**
55
+ * Save reminder id with current date time in to customer session
56
+ *
57
+ * @param string $reminderId
58
+ * @return Emv_CartAlert_CustomerController
59
+ */
60
+ protected function _saveReminderIdInSession($reminderId)
61
+ {
62
+ $reminderFlag = Mage::helper('abandonment')->getReminderFlagFromId($reminderId);
63
+
64
+ // store the reminder flag in the session (first_alert, second_alert ..)
65
+ $session = Mage::getSingleton('customer/session');
66
+ $session->setData('abandonment_flag', $reminderFlag);
67
+ // store the current date time in the session too
68
+ $now = Zend_Date::now();
69
+ $session->setData('abandonment_date', $now->toString('YYYY-MM-dd HH:mm:ss'));
70
+
71
+ return $this;
72
+ }
73
+
74
+ /**
75
+ * Redirect the user to the cart
76
+ */
77
+ public function cartAction()
78
+ {
79
+ $reminderId = $this->getRequest()->getParam('reminder', 1);
80
+
81
+ $this->_saveReminderIdInSession($reminderId);
82
+
83
  $this->_redirect('checkout/cart/index');
84
  }
85
 
86
+ /**
87
+ * Redirect the user to the store
88
+ */
89
+ public function storeAction()
90
+ {
91
+ $reminderId = $this->getRequest()->getParam('reminder', 1);
92
+
93
+ $this->_saveReminderIdInSession($reminderId);
94
+
95
+ $this->_redirect('');
96
+ }
97
+
98
+ /**
99
+ * Redirect the user to the product
100
+ */
101
+ public function productAction()
102
+ {
103
+ $reminderId = $this->getRequest()->getParam('reminder', 1);
104
+ $productId = $this->getRequest()->getParam('productid', null);
105
+
106
+ $this->_saveReminderIdInSession($reminderId);
107
+
108
+ if ($productId !== null) {
109
+ $product = Mage::getModel('catalog/product');
110
+ $product->load($productId);
111
+ $productUrl = Mage::getModel('catalog/product_url');
112
+ $url = $productUrl->getUrlPath($product);
113
+
114
+ $this->_redirect($url);
115
+ return;
116
+ }
117
+
118
+ $this->_redirect('');
119
+ }
120
+
121
+ /**
122
+ * Cart Reminder Subscription Management Action
123
+ */
124
  public function manageAction()
125
  {
126
  $this->loadLayout();
130
  if ($block = $this->getLayout()->getBlock('customer_abandonment')) {
131
  $block->setRefererUrl($this->_getRefererUrl());
132
  }
133
+ $this->getLayout()->getBlock('head')->setTitle(Mage::helper('abandonment')->__('Cart Reminder Subscription'));
134
  $this->renderLayout();
135
  }
136
 
137
+ /**
138
+ * Cart Reminder Subscription Save Action
139
+ */
140
  public function saveAction()
141
  {
142
  if (!$this->_validateFormKey()) {
143
  return $this->_redirect('customer/account/');
144
  }
145
+
146
  try {
147
+ $subscribed = (boolean)$this->getRequest()->getParam('is_subscribed', false);
148
+
149
  Mage::getSingleton('customer/session')->getCustomer()
150
+ ->setAbandonmentSubscribed($subscribed)
151
+ ->save();
152
+
153
+ if ($subscribed) {
154
+ Mage::getSingleton('customer/session')
155
+ ->addSuccess(Mage::helper('abandonment')->__('The subscription has been saved.'));
156
  } else {
157
+ Mage::getSingleton('customer/session')
158
+ ->addSuccess(Mage::helper('abandonment')->__('The subscription has been removed.'));
159
  }
160
+ } catch (Exception $e) {
161
+ Mage::getSingleton('customer/session')
162
+ ->addError(Mage::helper('abandonment')->__('An error occurred while saving your subscription.'));
163
  }
 
 
 
 
 
164
 
165
+ $this->_redirect('customer/account/');
 
 
 
 
 
166
  }
167
  }
app/code/community/Emv/CartAlert/controllers/GuestController.php CHANGED
@@ -1,5 +1,11 @@
1
  <?php
2
-
 
 
 
 
 
 
3
  class Emv_CartAlert_GuestController extends Mage_Core_Controller_Front_Action
4
  {
5
  /**
@@ -19,19 +25,20 @@ class Emv_CartAlert_GuestController extends Mage_Core_Controller_Front_Action
19
  * Checks if the customer is logged in. In order for this controller to run properly, the
20
  * customer must be logged out.
21
  * Causes an error message to be displayed if the customer is logged in.
 
22
  * @return boolean
23
  */
24
  protected function _isCustomerLoggedIn()
25
  {
26
  $loggedIn = Mage::getSingleton('customer/session')->authenticate($this);
27
 
28
- if ($loggedIn)
29
- {
30
  /* @var $session Mage_Checkout_Model_Session */
31
  $session = Mage::getSingleton('checkout/session');
32
  $message = Mage::helper('abandonment')->__('The link cannot be used by registered customers.');
33
  $session->addError($message);
34
  }
 
35
  return $loggedIn;
36
  }
37
 
@@ -45,26 +52,28 @@ class Emv_CartAlert_GuestController extends Mage_Core_Controller_Front_Action
45
  {
46
  /* @var $session Mage_Checkout_Model_Session */
47
  $session = Mage::getSingleton('checkout/session');
48
-
49
  $quoteId = $this->getRequest()->getParam('quote');
50
  $hash = $this->getRequest()->getParam('key', '');
 
 
51
  /* @var $quote Mage_Sales_Model_Quote */
 
52
  $quote = Mage::getModel('sales/quote')->load($quoteId);
53
- $validHash = false;
54
- if ($quote->getId())
55
- {
56
  $this->_quoteId = $quote->getId();
57
  $this->_quote = $quote;
58
- if (!$quote->getCustomerId())
59
- {
60
  $validHash = Mage::helper('core')->validateHash($quote->getCustomerEmail(), $hash);
61
  }
62
  }
63
- if (!$validHash)
64
- {
65
  $message = Mage::helper('abandonment')->__('The link is invalid.');
66
  $session->addError($message);
67
  }
 
68
  return $validHash;
69
  }
70
 
@@ -73,12 +82,9 @@ class Emv_CartAlert_GuestController extends Mage_Core_Controller_Front_Action
73
  */
74
  public function unsubscribeAction()
75
  {
76
- if ($this->_isCustomerLoggedIn() || (!$this->_validateParameters()))
77
- {
78
  $this->_redirect('checkout/cart/index');
79
- }
80
- else
81
- {
82
  /* @var $helper Emv_CartAlert_Helper_Data */
83
  $helper = Mage::helper('abandonment');
84
 
@@ -86,20 +92,17 @@ class Emv_CartAlert_GuestController extends Mage_Core_Controller_Front_Action
86
  $session = Mage::getSingleton('checkout/session');
87
 
88
  $abandonment = Mage::getModel('abandonment/abandonment')->loadByQuoteId($this->_quote->getId());
89
- if ($abandonment->getId())
90
- {
91
- if ($abandonment->getCustomerAbandonmentSubscribed())
92
- {
93
  $abandonment->setCustomerAbandonmentSubscribed(0)->save();
94
  $message = $helper->__('You were successfully unsubscribed from abandoned carts notifications.');
95
  $session->addSuccess($message);
96
- }
97
- else
98
- {
99
  $message = $helper->__('You are already unsubscribed from abandoned carts notifications.');
100
  $session->addError($message);
101
  }
102
  }
 
103
  Mage::getSingleton('checkout/session')->setQuote($this->_quote);
104
  Mage::getSingleton('checkout/cart')->setQuote($this->_quote);
105
  Mage::getSingleton('checkout/session')->setQuoteId($this->_quote->getId());
@@ -112,12 +115,80 @@ class Emv_CartAlert_GuestController extends Mage_Core_Controller_Front_Action
112
  */
113
  public function cartAction()
114
  {
115
- if (!$this->_isCustomerLoggedIn() && ($this->_validateParameters()))
116
- {
117
  Mage::getSingleton('checkout/cart')->setQuote($this->_quote);
118
  Mage::getSingleton('checkout/session')->setQuote($this->_quote);
119
  Mage::getSingleton('checkout/session')->setQuoteId($this->_quote->getId());
120
  }
 
 
 
 
 
121
  $this->_redirect('checkout/cart/index');
122
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  }
1
  <?php
2
+ /**
3
+ * Guest controller
4
+ *
5
+ * @category Emv
6
+ * @package Emv_CartAlert
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
  class Emv_CartAlert_GuestController extends Mage_Core_Controller_Front_Action
10
  {
11
  /**
25
  * Checks if the customer is logged in. In order for this controller to run properly, the
26
  * customer must be logged out.
27
  * Causes an error message to be displayed if the customer is logged in.
28
+ *
29
  * @return boolean
30
  */
31
  protected function _isCustomerLoggedIn()
32
  {
33
  $loggedIn = Mage::getSingleton('customer/session')->authenticate($this);
34
 
35
+ if ($loggedIn) {
 
36
  /* @var $session Mage_Checkout_Model_Session */
37
  $session = Mage::getSingleton('checkout/session');
38
  $message = Mage::helper('abandonment')->__('The link cannot be used by registered customers.');
39
  $session->addError($message);
40
  }
41
+
42
  return $loggedIn;
43
  }
44
 
52
  {
53
  /* @var $session Mage_Checkout_Model_Session */
54
  $session = Mage::getSingleton('checkout/session');
 
55
  $quoteId = $this->getRequest()->getParam('quote');
56
  $hash = $this->getRequest()->getParam('key', '');
57
+ $validHash = false;
58
+
59
  /* @var $quote Mage_Sales_Model_Quote */
60
+ // try to load the quote object from quote id
61
  $quote = Mage::getModel('sales/quote')->load($quoteId);
62
+
63
+ if ($quote->getId()) {
 
64
  $this->_quoteId = $quote->getId();
65
  $this->_quote = $quote;
66
+ // only guest check out is allowed
67
+ if (!$quote->getCustomerId()) {
68
  $validHash = Mage::helper('core')->validateHash($quote->getCustomerEmail(), $hash);
69
  }
70
  }
71
+
72
+ if (!$validHash) {
73
  $message = Mage::helper('abandonment')->__('The link is invalid.');
74
  $session->addError($message);
75
  }
76
+
77
  return $validHash;
78
  }
79
 
82
  */
83
  public function unsubscribeAction()
84
  {
85
+ if ($this->_isCustomerLoggedIn() || (!$this->_validateParameters())) {
 
86
  $this->_redirect('checkout/cart/index');
87
+ } else {
 
 
88
  /* @var $helper Emv_CartAlert_Helper_Data */
89
  $helper = Mage::helper('abandonment');
90
 
92
  $session = Mage::getSingleton('checkout/session');
93
 
94
  $abandonment = Mage::getModel('abandonment/abandonment')->loadByQuoteId($this->_quote->getId());
95
+ if ($abandonment->getId()) {
96
+ if ($abandonment->getCustomerAbandonmentSubscribed()) {
 
 
97
  $abandonment->setCustomerAbandonmentSubscribed(0)->save();
98
  $message = $helper->__('You were successfully unsubscribed from abandoned carts notifications.');
99
  $session->addSuccess($message);
100
+ } else {
 
 
101
  $message = $helper->__('You are already unsubscribed from abandoned carts notifications.');
102
  $session->addError($message);
103
  }
104
  }
105
+
106
  Mage::getSingleton('checkout/session')->setQuote($this->_quote);
107
  Mage::getSingleton('checkout/cart')->setQuote($this->_quote);
108
  Mage::getSingleton('checkout/session')->setQuoteId($this->_quote->getId());
115
  */
116
  public function cartAction()
117
  {
118
+ if (!$this->_isCustomerLoggedIn() && ($this->_validateParameters())) {
 
119
  Mage::getSingleton('checkout/cart')->setQuote($this->_quote);
120
  Mage::getSingleton('checkout/session')->setQuote($this->_quote);
121
  Mage::getSingleton('checkout/session')->setQuoteId($this->_quote->getId());
122
  }
123
+
124
+ $reminderId = $this->getRequest()->getParam('reminder', 1);
125
+
126
+ $this->_saveReminderIdInSession($reminderId);
127
+
128
  $this->_redirect('checkout/cart/index');
129
  }
130
+
131
+ /**
132
+ * After checking the session, and the provided parameters, redirect the user to the store
133
+ */
134
+ public function storeAction()
135
+ {
136
+ if (!$this->_isCustomerLoggedIn() && ($this->_validateParameters())) {
137
+ Mage::getSingleton('checkout/cart')->setQuote($this->_quote);
138
+ Mage::getSingleton('checkout/session')->setQuote($this->_quote);
139
+ Mage::getSingleton('checkout/session')->setQuoteId($this->_quote->getId());
140
+ }
141
+
142
+ $reminderId = $this->getRequest()->getParam('reminder', 1);
143
+
144
+ $this->_saveReminderIdInSession($reminderId);
145
+
146
+ $this->_redirect('');
147
+ }
148
+
149
+ /**
150
+ * After checking the session, and the provided parameters, redirect the user to the product
151
+ */
152
+ public function productAction()
153
+ {
154
+ if (!$this->_isCustomerLoggedIn() && ($this->_validateParameters())) {
155
+ Mage::getSingleton('checkout/cart')->setQuote($this->_quote);
156
+ Mage::getSingleton('checkout/session')->setQuote($this->_quote);
157
+ Mage::getSingleton('checkout/session')->setQuoteId($this->_quote->getId());
158
+ }
159
+
160
+ $reminderId = $this->getRequest()->getParam('reminder', 1);
161
+ $productId = $this->getRequest()->getParam('productid', null);
162
+
163
+ if ($productId !== null) {
164
+ $this->_saveReminderIdInSession($reminderId);
165
+
166
+ $product = Mage::getModel('catalog/product');
167
+ $product->load($productId);
168
+ $productUrl = Mage::getModel('catalog/product_url');
169
+ $url = $productUrl->getUrlPath($product);
170
+
171
+ $this->_redirect($url);
172
+ }
173
+ return;
174
+ }
175
+
176
+ /**
177
+ * Save reminder id with current date time in to customer session
178
+ *
179
+ * @param string $reminderId
180
+ * @return Emv_CartAlert_CustomerController
181
+ */
182
+ protected function _saveReminderIdInSession($reminderId)
183
+ {
184
+ $reminderFlag = Mage::helper('abandonment')->getReminderFlagFromId($reminderId);
185
+
186
+ // store the reminder flag in the session (first_alert, second_alert ..)
187
+ $session = Mage::getSingleton('customer/session');
188
+ $session->setData('abandonment_flag', $reminderFlag);
189
+ // store the current date time in the session too
190
+ $now = Zend_Date::now();
191
+ $session->setData('abandonment_date', $now->toString('YYYY-MM-dd HH:mm:ss'));
192
+ return $this;
193
+ }
194
  }
app/code/community/Emv/CartAlert/etc/adminhtml.xml CHANGED
@@ -6,14 +6,10 @@
6
  <children>
7
  <system>
8
  <children>
9
- <abandonment translate="title" module="abandonment">
10
- <title>Emailvision abandonment cart config</title>
11
- <sort_order>1000</sort_order>
12
- </abandonment>
13
  <config>
14
  <children>
15
  <abandonment translate="title" module="abandonment">
16
- <title>Emailvision section</title>
17
  </abandonment>
18
  </children>
19
  </config>
6
  <children>
7
  <system>
8
  <children>
 
 
 
 
9
  <config>
10
  <children>
11
  <abandonment translate="title" module="abandonment">
12
+ <title>SmartFocus - Abandonment cart configs</title>
13
  </abandonment>
14
  </children>
15
  </config>
app/code/community/Emv/CartAlert/etc/config.xml CHANGED
@@ -1,7 +1,7 @@
1
  <config>
2
  <modules>
3
  <Emv_CartAlert>
4
- <version>0.4.0</version>
5
  </Emv_CartAlert>
6
  </modules>
7
  <global>
@@ -16,6 +16,12 @@
16
  <abandonment>
17
  <table>abandonment</table>
18
  </abandonment>
 
 
 
 
 
 
19
  </entities>
20
  </abandonment_mysql4>
21
  </models>
@@ -39,21 +45,21 @@
39
  </resources>
40
  <template>
41
  <email>
42
- <abandonment_first_email_template translate="label" module="abandonment">
43
  <label>Abandoned Cart 1</label>
44
- <file>abandonment/template1.html</file>
45
  <type>html</type>
46
- </abandonment_first_email_template>
47
- <abandonment_second_email_template translate="label" module="abandonment">
48
  <label>Abandoned Cart 2</label>
49
- <file>abandonment/template2.html</file>
50
  <type>html</type>
51
- </abandonment_second_email_template>
52
- <abandonment_third_email_template translate="label" module="abandonment">
53
  <label>Abandoned Cart 3</label>
54
- <file>abandonment/template3.html</file>
55
  <type>html</type>
56
- </abandonment_third_email_template>
57
  </email>
58
  </template>
59
  <events>
@@ -65,11 +71,19 @@
65
  </abandonment>
66
  </observers>
67
  </customer_save_after>
 
 
 
 
 
 
 
 
68
  </events>
69
  <layout>
70
  <updates>
71
  <abandonment module="Emv_CartAlert">
72
- <file>abandonment.xml</file>
73
  </abandonment>
74
  </updates>
75
  </layout>
@@ -87,7 +101,7 @@
87
  <layout>
88
  <updates>
89
  <abandonment module="Emv_CartAlert">
90
- <file>abandonment.xml</file>
91
  </abandonment>
92
  </updates>
93
  </layout>
@@ -114,14 +128,33 @@
114
  </adminhtml>
115
  <crontab>
116
  <jobs>
117
- <process_abandoned_carts>
118
  <schedule>
119
  <cron_expr>*/5 * * * *</cron_expr>
120
  </schedule>
121
  <run>
122
  <model>abandonment/observer::processAbandonedCarts</model>
123
  </run>
124
- </process_abandoned_carts>
125
  </jobs>
126
  </crontab>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
127
  </config>
1
  <config>
2
  <modules>
3
  <Emv_CartAlert>
4
+ <version>0.5.2</version>
5
  </Emv_CartAlert>
6
  </modules>
7
  <global>
16
  <abandonment>
17
  <table>abandonment</table>
18
  </abandonment>
19
+ <stats>
20
+ <table>stats_email_abandonment_sent</table>
21
+ </stats>
22
+ <order_flag>
23
+ <table>emv_order_flag</table>
24
+ </order_flag>
25
  </entities>
26
  </abandonment_mysql4>
27
  </models>
45
  </resources>
46
  <template>
47
  <email>
48
+ <abandonment_first_alert_config_template translate="label" module="abandonment">
49
  <label>Abandoned Cart 1</label>
50
+ <file>emailvision/abandonment/template1.html</file>
51
  <type>html</type>
52
+ </abandonment_first_alert_config_template>
53
+ <abandonment_second_alert_config_template translate="label" module="abandonment">
54
  <label>Abandoned Cart 2</label>
55
+ <file>emailvision/abandonment/template2.html</file>
56
  <type>html</type>
57
+ </abandonment_second_alert_config_template>
58
+ <abandonment_third_alert_config_template translate="label" module="abandonment">
59
  <label>Abandoned Cart 3</label>
60
+ <file>emailvision/abandonment/template3.html</file>
61
  <type>html</type>
62
+ </abandonment_third_alert_config_template>
63
  </email>
64
  </template>
65
  <events>
71
  </abandonment>
72
  </observers>
73
  </customer_save_after>
74
+ <sales_order_save_after>
75
+ <observers>
76
+ <abandonment>
77
+ <class>abandonment/observer</class>
78
+ <method>handleOrderSaveAfter</method>
79
+ </abandonment>
80
+ </observers>
81
+ </sales_order_save_after>
82
  </events>
83
  <layout>
84
  <updates>
85
  <abandonment module="Emv_CartAlert">
86
+ <file>emailvision/abandonment.xml</file>
87
  </abandonment>
88
  </updates>
89
  </layout>
101
  <layout>
102
  <updates>
103
  <abandonment module="Emv_CartAlert">
104
+ <file>emailvision/abandonment.xml</file>
105
  </abandonment>
106
  </updates>
107
  </layout>
128
  </adminhtml>
129
  <crontab>
130
  <jobs>
131
+ <emailvision_process_abandoned_carts>
132
  <schedule>
133
  <cron_expr>*/5 * * * *</cron_expr>
134
  </schedule>
135
  <run>
136
  <model>abandonment/observer::processAbandonedCarts</model>
137
  </run>
138
+ </emailvision_process_abandoned_carts>
139
  </jobs>
140
  </crontab>
141
+ <default>
142
+ <abandonment>
143
+ <general>
144
+ <image_size>256</image_size>
145
+ <length>8</length>
146
+ <format>Alphanumeric</format>
147
+ <dash>4</dash>
148
+ </general>
149
+ <first_alert_config>
150
+ <template>abandonment_first_alert_config_template</template>
151
+ </first_alert_config>
152
+ <second_alert_config>
153
+ <template>abandonment_second_alert_config_template</template>
154
+ </second_alert_config>
155
+ <third_alert_config>
156
+ <template>abandonment_third_alert_config_template</template>
157
+ </third_alert_config>
158
+ </abandonment>
159
+ </default>
160
  </config>
app/code/community/Emv/CartAlert/etc/system.xml CHANGED
@@ -5,19 +5,102 @@
5
  <label>Abandonment Cart Alert</label>
6
  <tab>emailvision</tab>
7
  <frontend_type>text</frontend_type>
8
- <sort_order>500</sort_order>
9
  <show_in_default>1</show_in_default>
10
- <show_in_website>0</show_in_website>
11
- <show_in_store>0</show_in_store>
12
  <groups>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  <first_alert_config translate="label" module="abandonment">
14
  <label>First Alert Configuration</label>
15
- <expanded>1</expanded>
16
  <frontend_type>text</frontend_type>
17
- <sort_order>1</sort_order>
18
  <show_in_default>1</show_in_default>
19
- <show_in_website>0</show_in_website>
20
- <show_in_store>0</show_in_store>
21
  <fields>
22
  <enabled translate="label" module="abandonment">
23
  <label>First Email Alert Enable</label>
@@ -25,16 +108,16 @@
25
  <source_model>adminhtml/system_config_source_yesno</source_model>
26
  <sort_order>10</sort_order>
27
  <show_in_default>1</show_in_default>
28
- <show_in_website>0</show_in_website>
29
- <show_in_store>0</show_in_store>
30
  </enabled>
31
  <delay translate="label" module="abandonment">
32
  <label>First Email Alert Delay (in hour)</label>
33
  <frontend_type>text</frontend_type>
34
  <sort_order>20</sort_order>
35
  <show_in_default>1</show_in_default>
36
- <show_in_website>0</show_in_website>
37
- <show_in_store>0</show_in_store>
38
  </delay>
39
  <template translate="label" module="abandonment">
40
  <label>First Email Alert Template</label>
@@ -42,21 +125,19 @@
42
  <source_model>adminhtml/system_config_source_email_template</source_model>
43
  <sort_order>30</sort_order>
44
  <show_in_default>1</show_in_default>
45
- <show_in_website>0</show_in_website>
46
- <show_in_store>0</show_in_store>
47
  </template>
48
  </fields>
49
  </first_alert_config>
50
- </groups>
51
- <groups>
52
  <second_alert_config translate="label" module="abandonment">
53
  <label>Second Alert Configuration</label>
54
- <expanded>1</expanded>
55
  <frontend_type>text</frontend_type>
56
  <sort_order>10</sort_order>
57
  <show_in_default>1</show_in_default>
58
- <show_in_website>0</show_in_website>
59
- <show_in_store>0</show_in_store>
60
  <fields>
61
  <enabled translate="label" module="abandonment">
62
  <label>Second Email Alert Enable</label>
@@ -64,16 +145,16 @@
64
  <source_model>adminhtml/system_config_source_yesno</source_model>
65
  <sort_order>10</sort_order>
66
  <show_in_default>1</show_in_default>
67
- <show_in_website>0</show_in_website>
68
- <show_in_store>0</show_in_store>
69
  </enabled>
70
  <delay translate="label" module="abandonment">
71
  <label>Second Email Alert Delay (in hour)</label>
72
  <frontend_type>text</frontend_type>
73
  <sort_order>20</sort_order>
74
  <show_in_default>1</show_in_default>
75
- <show_in_website>0</show_in_website>
76
- <show_in_store>0</show_in_store>
77
  </delay>
78
  <template translate="label" module="abandonment">
79
  <label>Second Email Template</label>
@@ -81,21 +162,19 @@
81
  <source_model>adminhtml/system_config_source_email_template</source_model>
82
  <sort_order>30</sort_order>
83
  <show_in_default>1</show_in_default>
84
- <show_in_website>0</show_in_website>
85
- <show_in_store>0</show_in_store>
86
  </template>
87
  </fields>
88
  </second_alert_config>
89
- </groups>
90
- <groups>
91
  <third_alert_config translate="label" module="abandonment">
92
  <label>Third Alert Configuration</label>
93
- <expanded>1</expanded>
94
  <frontend_type>text</frontend_type>
95
  <sort_order>20</sort_order>
96
  <show_in_default>1</show_in_default>
97
- <show_in_website>0</show_in_website>
98
- <show_in_store>0</show_in_store>
99
  <fields>
100
  <enabled translate="label" module="abandonment">
101
  <label>Third Email Alert Enable</label>
@@ -103,16 +182,16 @@
103
  <source_model>adminhtml/system_config_source_yesno</source_model>
104
  <sort_order>10</sort_order>
105
  <show_in_default>1</show_in_default>
106
- <show_in_website>0</show_in_website>
107
- <show_in_store>0</show_in_store>
108
  </enabled>
109
  <delay translate="label" module="abandonment">
110
  <label>Third Email Alert Delay (in hour)</label>
111
  <frontend_type>text</frontend_type>
112
  <sort_order>20</sort_order>
113
  <show_in_default>1</show_in_default>
114
- <show_in_website>0</show_in_website>
115
- <show_in_store>0</show_in_store>
116
  </delay>
117
  <template translate="label" module="abandonment">
118
  <label>Third Email Alert Template</label>
@@ -120,34 +199,12 @@
120
  <source_model>adminhtml/system_config_source_email_template</source_model>
121
  <sort_order>30</sort_order>
122
  <show_in_default>1</show_in_default>
123
- <show_in_website>0</show_in_website>
124
- <show_in_store>0</show_in_store>
125
  </template>
126
  </fields>
127
  </third_alert_config>
128
  </groups>
129
- <groups>
130
- <alert_identity translate="label" module="abandonment">
131
- <label>Sender Identity</label>
132
- <expanded>1</expanded>
133
- <frontend_type>text</frontend_type>
134
- <sort_order>50</sort_order>
135
- <show_in_default>1</show_in_default>
136
- <show_in_website>0</show_in_website>
137
- <show_in_store>0</show_in_store>
138
- <fields>
139
- <email_identity translate="label" module="abandonment">
140
- <label>Email Sender</label>
141
- <frontend_type>select</frontend_type>
142
- <source_model>adminhtml/system_config_source_email_identity</source_model>
143
- <sort_order>10</sort_order>
144
- <show_in_default>1</show_in_default>
145
- <show_in_website>0</show_in_website>
146
- <show_in_store>0</show_in_store>
147
- </email_identity>
148
- </fields>
149
- </alert_identity>
150
- </groups>
151
  </abandonment>
152
  </sections>
153
  </config>
5
  <label>Abandonment Cart Alert</label>
6
  <tab>emailvision</tab>
7
  <frontend_type>text</frontend_type>
8
+ <sort_order>50</sort_order>
9
  <show_in_default>1</show_in_default>
10
+ <show_in_website>1</show_in_website>
11
+ <show_in_store>1</show_in_store>
12
  <groups>
13
+ <general translate="label" module="abandonment">
14
+ <label>General</label>
15
+ <expanded>0</expanded>
16
+ <frontend_type>text</frontend_type>
17
+ <sort_order>0</sort_order>
18
+ <show_in_default>1</show_in_default>
19
+ <show_in_website>1</show_in_website>
20
+ <show_in_store>1</show_in_store>
21
+ <fields>
22
+ <email_identity translate="label" module="abandonment">
23
+ <label>Email Sender</label>
24
+ <frontend_type>select</frontend_type>
25
+ <source_model>adminhtml/system_config_source_email_identity</source_model>
26
+ <sort_order>1</sort_order>
27
+ <show_in_default>1</show_in_default>
28
+ <show_in_website>1</show_in_website>
29
+ <show_in_store>1</show_in_store>
30
+ </email_identity>
31
+ <image_size translate="label" module="abandonment">
32
+ <label>Image Size</label>
33
+ <frontend_type>text</frontend_type>
34
+ <sort_order>5</sort_order>
35
+ <show_in_default>1</show_in_default>
36
+ <show_in_website>1</show_in_website>
37
+ <show_in_store>1</show_in_store>
38
+ <frontend_class>validate-digits</frontend_class>
39
+ </image_size>
40
+ <cart_rule translate="label comment" module="abandonment">
41
+ <label>Shopping Cart Prices Rule Id</label>
42
+ <frontend_type>text</frontend_type>
43
+ <sort_order>12</sort_order>
44
+ <show_in_default>1</show_in_default>
45
+ <show_in_website>1</show_in_website>
46
+ <show_in_store>1</show_in_store>
47
+ <frontend_class>validate-digits</frontend_class>
48
+ </cart_rule>
49
+ <length translate="label comment" module="abandonment">
50
+ <label>Coupon Code Length</label>
51
+ <frontend_type>text</frontend_type>
52
+ <sort_order>15</sort_order>
53
+ <show_in_default>1</show_in_default>
54
+ <show_in_website>1</show_in_website>
55
+ <show_in_store>1</show_in_store>
56
+ <comment>Excluding prefix, suffix and separators.</comment>
57
+ <frontend_class>validate-digits</frontend_class>
58
+ </length>
59
+ <format translate="label" module="abandonment">
60
+ <label>Coupon Code Format</label>
61
+ <frontend_type>select</frontend_type>
62
+ <source_model>salesrule/system_config_source_coupon_format</source_model>
63
+ <sort_order>20</sort_order>
64
+ <show_in_default>1</show_in_default>
65
+ <show_in_website>1</show_in_website>
66
+ <show_in_store>1</show_in_store>
67
+ </format>
68
+ <prefix translate="label" module="abandonment">
69
+ <label>Coupon Code Prefix</label>
70
+ <frontend_type>text</frontend_type>
71
+ <sort_order>30</sort_order>
72
+ <show_in_default>1</show_in_default>
73
+ <show_in_website>1</show_in_website>
74
+ <show_in_store>1</show_in_store>
75
+ </prefix>
76
+ <suffix translate="label" module="abandonment">
77
+ <label>Coupon Code Suffix</label>
78
+ <frontend_type>text</frontend_type>
79
+ <sort_order>40</sort_order>
80
+ <show_in_default>1</show_in_default>
81
+ <show_in_website>1</show_in_website>
82
+ <show_in_store>1</show_in_store>
83
+ </suffix>
84
+ <dash translate="label comment" module="abandonment">
85
+ <label>Dash Every X Characters For Coupon Code</label>
86
+ <frontend_type>text</frontend_type>
87
+ <sort_order>50</sort_order>
88
+ <show_in_default>1</show_in_default>
89
+ <show_in_website>1</show_in_website>
90
+ <show_in_store>1</show_in_store>
91
+ <comment>If empty no separation.</comment>
92
+ <frontend_class>validate-digits</frontend_class>
93
+ </dash>
94
+ </fields>
95
+ </general>
96
  <first_alert_config translate="label" module="abandonment">
97
  <label>First Alert Configuration</label>
98
+ <expanded>0</expanded>
99
  <frontend_type>text</frontend_type>
100
+ <sort_order>5</sort_order>
101
  <show_in_default>1</show_in_default>
102
+ <show_in_website>1</show_in_website>
103
+ <show_in_store>1</show_in_store>
104
  <fields>
105
  <enabled translate="label" module="abandonment">
106
  <label>First Email Alert Enable</label>
108
  <source_model>adminhtml/system_config_source_yesno</source_model>
109
  <sort_order>10</sort_order>
110
  <show_in_default>1</show_in_default>
111
+ <show_in_website>1</show_in_website>
112
+ <show_in_store>1</show_in_store>
113
  </enabled>
114
  <delay translate="label" module="abandonment">
115
  <label>First Email Alert Delay (in hour)</label>
116
  <frontend_type>text</frontend_type>
117
  <sort_order>20</sort_order>
118
  <show_in_default>1</show_in_default>
119
+ <show_in_website>1</show_in_website>
120
+ <show_in_store>1</show_in_store>
121
  </delay>
122
  <template translate="label" module="abandonment">
123
  <label>First Email Alert Template</label>
125
  <source_model>adminhtml/system_config_source_email_template</source_model>
126
  <sort_order>30</sort_order>
127
  <show_in_default>1</show_in_default>
128
+ <show_in_website>1</show_in_website>
129
+ <show_in_store>1</show_in_store>
130
  </template>
131
  </fields>
132
  </first_alert_config>
 
 
133
  <second_alert_config translate="label" module="abandonment">
134
  <label>Second Alert Configuration</label>
135
+ <expanded>0</expanded>
136
  <frontend_type>text</frontend_type>
137
  <sort_order>10</sort_order>
138
  <show_in_default>1</show_in_default>
139
+ <show_in_website>1</show_in_website>
140
+ <show_in_store>1</show_in_store>
141
  <fields>
142
  <enabled translate="label" module="abandonment">
143
  <label>Second Email Alert Enable</label>
145
  <source_model>adminhtml/system_config_source_yesno</source_model>
146
  <sort_order>10</sort_order>
147
  <show_in_default>1</show_in_default>
148
+ <show_in_website>1</show_in_website>
149
+ <show_in_store>1</show_in_store>
150
  </enabled>
151
  <delay translate="label" module="abandonment">
152
  <label>Second Email Alert Delay (in hour)</label>
153
  <frontend_type>text</frontend_type>
154
  <sort_order>20</sort_order>
155
  <show_in_default>1</show_in_default>
156
+ <show_in_website>1</show_in_website>
157
+ <show_in_store>1</show_in_store>
158
  </delay>
159
  <template translate="label" module="abandonment">
160
  <label>Second Email Template</label>
162
  <source_model>adminhtml/system_config_source_email_template</source_model>
163
  <sort_order>30</sort_order>
164
  <show_in_default>1</show_in_default>
165
+ <show_in_website>1</show_in_website>
166
+ <show_in_store>1</show_in_store>
167
  </template>
168
  </fields>
169
  </second_alert_config>
 
 
170
  <third_alert_config translate="label" module="abandonment">
171
  <label>Third Alert Configuration</label>
172
+ <expanded>0</expanded>
173
  <frontend_type>text</frontend_type>
174
  <sort_order>20</sort_order>
175
  <show_in_default>1</show_in_default>
176
+ <show_in_website>1</show_in_website>
177
+ <show_in_store>1</show_in_store>
178
  <fields>
179
  <enabled translate="label" module="abandonment">
180
  <label>Third Email Alert Enable</label>
182
  <source_model>adminhtml/system_config_source_yesno</source_model>
183
  <sort_order>10</sort_order>
184
  <show_in_default>1</show_in_default>
185
+ <show_in_website>1</show_in_website>
186
+ <show_in_store>1</show_in_store>
187
  </enabled>
188
  <delay translate="label" module="abandonment">
189
  <label>Third Email Alert Delay (in hour)</label>
190
  <frontend_type>text</frontend_type>
191
  <sort_order>20</sort_order>
192
  <show_in_default>1</show_in_default>
193
+ <show_in_website>1</show_in_website>
194
+ <show_in_store>1</show_in_store>
195
  </delay>
196
  <template translate="label" module="abandonment">
197
  <label>Third Email Alert Template</label>
199
  <source_model>adminhtml/system_config_source_email_template</source_model>
200
  <sort_order>30</sort_order>
201
  <show_in_default>1</show_in_default>
202
+ <show_in_website>1</show_in_website>
203
+ <show_in_store>1</show_in_store>
204
  </template>
205
  </fields>
206
  </third_alert_config>
207
  </groups>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
208
  </abandonment>
209
  </sections>
210
  </config>
app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-install-0.1.0.php CHANGED
@@ -1,8 +1,6 @@
1
  <?php
2
-
3
- $installer = $this;
4
- $installer->startSetup();
5
- $installer->run("
6
  -- DROP TABLE IF EXISTS {$this->getTable('abandonment')};
7
  CREATE TABLE {$this->getTable('abandonment')} (
8
  `abandonment_id` int(11) unsigned NOT NULL auto_increment,
@@ -11,5 +9,5 @@ CREATE TABLE {$this->getTable('abandonment')} (
11
  PRIMARY KEY (`abandonment_id`)
12
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
13
  ");
14
- $installer->endSetup();
15
 
1
  <?php
2
+ $this->startSetup();
3
+ $this->run("
 
 
4
  -- DROP TABLE IF EXISTS {$this->getTable('abandonment')};
5
  CREATE TABLE {$this->getTable('abandonment')} (
6
  `abandonment_id` int(11) unsigned NOT NULL auto_increment,
9
  PRIMARY KEY (`abandonment_id`)
10
  ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
11
  ");
12
+ $this->endSetup();
13
 
app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.1.0-0.2.0.php CHANGED
@@ -1,22 +1,21 @@
1
  <?php
2
- /* @var $installer Emv_CartAlert_Model_Resource_Setup */
3
- $installer = $this;
4
 
5
- $installer->addAttribute('customer', 'abandonment_subscribed', array(
6
- 'label' => 'Subscribed from abandonned cart notifications',
7
- 'type' => 'int',
8
- 'input' => 'select',
9
- 'visible' => true,
10
- 'source' => 'eav/entity_attribute_source_boolean',
11
- 'required' => false,
12
- 'user_defined' => false,
13
- 'nullable' => false,
14
- 'default' => '1',
15
- 'sort_order' => 1000
16
  ));
17
 
18
- $installer->getConnection()
19
- ->addColumn($installer->getTable('abandonment/abandonment'), 'customer_abandonment_subscribed', 'TINYINT(1) NOT NULL DEFAULT 1');
20
 
21
- $installer->updateCustomerForms();
22
- $installer->endSetup();
1
  <?php
2
+ /* @var $this Emv_CartAlert_Model_Resource_Setup */
3
+ $this->startSetup();
4
 
5
+ $this->addAttribute('customer', 'abandonment_subscribed', array(
6
+ 'label' => 'Subscribed from abandonned cart notifications',
7
+ 'type' => 'int',
8
+ 'input' => 'select',
9
+ 'visible' => true,
10
+ 'source' => 'eav/entity_attribute_source_boolean',
11
+ 'required' => false,
12
+ 'user_defined' => false,
13
+ 'nullable' => false,
14
+ 'default' => '1',
15
+ 'sort_order' => 1000
16
  ));
17
 
18
+ $this->getConnection()
19
+ ->addColumn($this->getTable('abandonment/abandonment'), 'customer_abandonment_subscribed', 'TINYINT(1) NOT NULL DEFAULT 1');
20
 
21
+ $this->endSetup();
 
app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.2.0-0.3.0.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Emv_CartAlert_Model_Resource_Setup */
3
+ $this->startSetup();
4
+ $this->run("
5
+ DROP TABLE IF EXISTS {$this->getTable('abandonment/stats')};
6
+ CREATE TABLE {$this->getTable('abandonment/stats')} (
7
+ `id` int(11) unsigned NOT NULL auto_increment,
8
+ `reminder_id` int(11) unsigned NOT NULL,
9
+ `send_date` DATETIME NOT NULL,
10
+ `quote_id` int(11) unsigned NOT NULL,
11
+ PRIMARY KEY (`id`)
12
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
13
+ ");
14
+
15
+ $this->run("
16
+ DROP TABLE IF EXISTS {$this->getTable('abandonment/order_flag')};
17
+ CREATE TABLE {$this->getTable('abandonment/order_flag')} (
18
+ `id` int(11) unsigned NOT NULL auto_increment,
19
+ `entity_id` int(11) unsigned NOT NULL,
20
+ `flag` VARCHAR(64),
21
+ `flag_date` DATETIME,
22
+ PRIMARY KEY (`id`)
23
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
24
+ ");
25
+
26
+ $this->endSetup();
app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.3.0-0.4.0.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Emv_CartAlert_Model_Resource_Setup */
3
+
4
+ $this->startSetup();
5
+
6
+ $this->addAttribute('customer', 'newsletter_subscribed', array(
7
+ 'label' => 'Subscribed to newsletter(s)',
8
+ 'type' => 'int',
9
+ 'input' => 'select',
10
+ 'visible' => true,
11
+ 'source' => 'eav/entity_attribute_source_boolean',
12
+ 'required' => false,
13
+ 'user_defined' => false,
14
+ 'nullable' => false,
15
+ 'default' => '1',
16
+ 'sort_order' => 1000
17
+ ));
18
+
19
+ $this->updateCustomerForms();
20
+ $this->endSetup();
app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.4.0-0.5.0.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Emv_CartAlert_Model_Resource_Setup */
3
+
4
+ $this->startSetup();
5
+
6
+ $this->getConnection()
7
+ ->addColumn($this->getTable('abandonment/abandonment'), 'customer_id', 'INT(10) NULL');
8
+
9
+ // get customer_id for all exisiting abandonment
10
+ $sql = "UPDATE {$this->getTable('abandonment/abandonment')} AS aband"
11
+ . " JOIN {$this->getTable('sales/quote')} AS quote ON quote.entity_id = aband.entity_id"
12
+ . " SET aband.customer_id = quote.customer_id";
13
+
14
+ $this->run($sql);
15
+
16
+ $this->endSetup();
app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.5.0-0.5.1.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Emv_CartAlert_Model_Resource_Setup */
3
+ $this->startSetup();
4
+
5
+ $this->getConnection()
6
+ ->addColumn($this->getTable('abandonment/abandonment'), 'shopping_cart_rule_id', 'INT(9) NULL');
7
+ $this->getConnection()
8
+ ->addColumn($this->getTable('abandonment/abandonment'), 'coupon_code', 'TEXT NULL');
9
+
10
+ $this->endSetup();
app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.5.1-0.5.2.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Emv_CartAlert_Model_Resource_Setup */
3
+ $this->startSetup();
4
+
5
+ $this->removeAttribute('customer', 'newsletter_subscribed');
6
+
7
+ $this->updateCustomerForms();
8
+ $this->endSetup();
app/code/community/Emv/Core/Block/Adminhtml/Account/Edit.php CHANGED
@@ -1,16 +1,17 @@
1
  <?php
2
  /**
 
3
  *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{9A8DC590-314F-402c-A1B5-45669D8D3DA0}
8
  */
9
  class Emv_Core_Block_Adminhtml_Account_Edit extends Mage_Adminhtml_Block_Widget_Form_Container
10
  {
11
 
12
  /**
13
- * opGUID{E35B4FB9-C0A2-4362-8A9C-9F73B3A95889}
14
  */
15
  public function __construct()
16
  {
@@ -19,11 +20,6 @@ class Emv_Core_Block_Adminhtml_Account_Edit extends Mage_Adminhtml_Block_Widget_
19
  $this->_controller = 'adminhtml_account';
20
  $this->_headerText = $this->getHeaderText();
21
 
22
- if(!Mage::getSingleton('admin/session')->isAllowed('emvcore/account/delete'))
23
- {
24
- $this->removeButton('delete');
25
- }
26
-
27
  $this->_addButton('saveandcontinue', array(
28
  'label' => Mage::helper('adminhtml')->__('Save and Continue Edit'),
29
  'onclick' => 'saveAndContinueEdit()',
@@ -44,13 +40,10 @@ class Emv_Core_Block_Adminhtml_Account_Edit extends Mage_Adminhtml_Block_Widget_
44
  */
45
  public function getHeaderText()
46
  {
47
- if (Mage::registry('current_emvaccount')->getId())
48
- {
49
- return Mage::helper('emvcore')->__("Edit Campaign Commander Account '%s'", $this->htmlEscape(Mage::registry('current_emvaccount')->getName()));
50
- }
51
- else
52
- {
53
- return Mage::helper('emvcore')->__('New Campaign Commander Account');
54
  }
55
  }
56
  }
1
  <?php
2
  /**
3
+ * This block is used to manage account edit view
4
  *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
  */
10
  class Emv_Core_Block_Adminhtml_Account_Edit extends Mage_Adminhtml_Block_Widget_Form_Container
11
  {
12
 
13
  /**
14
+ * Prepare edit view
15
  */
16
  public function __construct()
17
  {
20
  $this->_controller = 'adminhtml_account';
21
  $this->_headerText = $this->getHeaderText();
22
 
 
 
 
 
 
23
  $this->_addButton('saveandcontinue', array(
24
  'label' => Mage::helper('adminhtml')->__('Save and Continue Edit'),
25
  'onclick' => 'saveAndContinueEdit()',
40
  */
41
  public function getHeaderText()
42
  {
43
+ if (Mage::registry('current_emvaccount')->getId()) {
44
+ return Mage::helper('emvcore')->__("Edit SmartFocus Account '%s'", $this->htmlEscape(Mage::registry('current_emvaccount')->getName()));
45
+ } else {
46
+ return Mage::helper('emvcore')->__('New SmartFocus Account');
 
 
 
47
  }
48
  }
49
  }
app/code/community/Emv/Core/Block/Adminhtml/Account/Edit/AssociatedUrls.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Associated Urls block for account form
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Core_Block_Adminhtml_Account_Edit_AssociatedUrls extends Mage_Adminhtml_Block_Widget_Form_Renderer_Fieldset_Element
11
+ {
12
+ /**
13
+ * XML path for default wsdl
14
+ */
15
+ const XML_PATH_EMV_WSDL_LIST_TRANSACTIONNAL = 'global/emv/wsdl_list';
16
+
17
+ /**
18
+ * Set template phtml
19
+ */
20
+ public function __construct()
21
+ {
22
+ $this->setTemplate('emailvision/account/associated_urls.phtml');
23
+ }
24
+
25
+ /**
26
+ * Get webservice div id
27
+ *
28
+ * @return string
29
+ */
30
+ public function getWebserviceDivId()
31
+ {
32
+ return 'associated_webservices';
33
+ }
34
+
35
+ /**
36
+ * Get add button id
37
+ * @return string
38
+ */
39
+ public function getAddId()
40
+ {
41
+ return 'webservice_add';
42
+ }
43
+
44
+ /**
45
+ * Get available service select id
46
+ * @return string
47
+ */
48
+ public function getAvailableServiceId()
49
+ {
50
+ return 'available_webservices';
51
+ }
52
+
53
+ /**
54
+ * @return string
55
+ */
56
+ public function getDefaultUrls()
57
+ {
58
+ $config = Mage::getConfig()->getNode(self::XML_PATH_EMV_WSDL_LIST_TRANSACTIONNAL);
59
+ $node = $config->rest_notification_service;
60
+ $url = $node ? $node->asArray() : null;
61
+ $defaultUrls = array(
62
+ Emv_Core_Model_Account::URL_REST_NOTIFICATION_SERVICE_TYPE => $url
63
+ );
64
+ return Mage::helper('core')->jsonEncode($defaultUrls);
65
+ }
66
+ }
app/code/community/Emv/Core/Block/Adminhtml/Account/Edit/Form.php CHANGED
@@ -1,122 +1,169 @@
1
  <?php
2
  /**
 
3
  *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{F6ADA887-E2B8-4107-9915-B14420DCDFE7}
8
  */
9
  class Emv_Core_Block_Adminhtml_Account_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
10
  {
 
 
 
 
 
 
 
11
 
12
  /**
13
- * opGUID{AB2272B3-0BEE-42bd-96EC-E2C54C40CB9B}
 
 
 
14
  */
15
  protected function _prepareForm()
16
  {
17
  $form = new Varien_Data_Form(
18
- array(
19
- 'id' => 'edit_form',
20
- 'action' => $this->getUrl('*/*/save'),
21
- 'method' => 'post',
22
- ));
23
-
24
- $model = Mage::registry('current_emvaccount');
25
- if(null === $model)
26
- {
27
- $model = new Varien_Object();
28
- }
29
-
30
- $yesno = array(
31
  array(
32
- 'value' => 0,
33
- 'label' => Mage::helper('emvcore')->__('No')
34
- ),
35
- array(
36
- 'value' => 1,
37
- 'label' => Mage::helper('emvcore')->__('Yes')
38
- ),
39
  );
40
 
41
- if ($model->getId()) {
 
 
 
 
 
42
  $form->addField('id', 'hidden', array(
43
  'name' => 'id',
44
  ));
45
  }
46
 
47
- $fieldset = $form->addFieldset('account_info',
 
48
  array(
49
  'legend' => Mage::helper('emvcore')->__('Account Information'),
50
- ));
 
51
 
52
  $fieldset->addField('name', 'text', array(
53
- 'value' => '',
54
- 'label' => Mage::helper('emvcore')->__('Account Name'),
55
- 'name' => 'name',
56
  'required' => true,
57
- 'class' => 'required-entry',
58
  ));
59
 
60
- $fieldset = $form->addFieldset('api_info',
 
 
61
  array(
62
  'legend' => Mage::helper('emvcore')->__('API Information'),
63
- ));
 
64
 
65
  $fieldset->addField('account_login', 'text', array(
66
- 'value' => '',
67
- 'label' => Mage::helper('emvcore')->__('API Login'),
68
- 'name' => 'account_login',
69
  'required' => true,
70
- 'class' => 'required-entry',
71
  ));
72
 
73
  $fieldset->addField('account_password', 'password', array(
74
- 'value' => '',
75
- 'label' => Mage::helper('emvcore')->__('API Password'),
76
- 'name' => 'account_password',
77
  'required' => true,
78
- 'class' => 'required-entry',
79
  ));
80
 
81
  $fieldset->addField('manager_key', 'text', array(
82
- 'value' => '',
83
- 'label' => Mage::helper('emvcore')->__('API Manager Key'),
84
- 'name' => 'manager_key',
85
  'required' => true,
86
- 'class' => 'required-entry',
87
  ));
88
 
89
- $fieldset = $form->addFieldset('proxy_info',
 
 
90
  array(
91
  'legend' => Mage::helper('emvcore')->__('Proxy Information'),
92
- ));
 
93
 
94
  $fieldset->addField('use_proxy', 'select', array(
95
- 'value' => '',
96
- 'label' => Mage::helper('emvcore')->__('API Uses Proxy'),
97
- 'name' => 'use_proxy',
98
  'required' => true,
99
- 'class' => 'validate-select',
100
- 'values' => $yesno,
101
  ));
102
 
103
  $fieldset->addField('proxy_host', 'text', array(
104
- 'value' => '',
105
- 'label' => Mage::helper('emvcore')->__('Proxy Host'),
106
- 'name' => 'proxy_host',
107
  ));
108
 
109
  $fieldset->addField('proxy_port', 'text', array(
110
  'value' => '',
111
  'label' => Mage::helper('emvcore')->__('Proxy Port'),
112
- 'name' => 'proxy_port',
113
  'class' => 'validate-digits validate-greater-than-zero',
114
  ));
115
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
116
  $form->setUseContainer(true);
117
- $form->setValues($model->getData());
118
  $this->setForm($form);
119
 
120
  return parent::_prepareForm();
121
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  }
1
  <?php
2
  /**
3
+ * Account edit view form
4
  *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
  */
10
  class Emv_Core_Block_Adminhtml_Account_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
11
  {
12
+ protected function _prepareLayout()
13
+ {
14
+ $this->setChild('webservice',
15
+ $this->getLayout()->createBlock('emvcore/adminhtml_account_edit_associatedUrls')
16
+ );
17
+ return parent::_prepareLayout();
18
+ }
19
 
20
  /**
21
+ * Prepare form
22
+ *
23
+ * (non-PHPdoc)
24
+ * @see Mage_Adminhtml_Block_Widget_Form::_prepareForm()
25
  */
26
  protected function _prepareForm()
27
  {
28
  $form = new Varien_Data_Form(
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  array(
30
+ 'id' => 'edit_form',
31
+ 'action' => $this->getUrl('*/*/save'),
32
+ 'method' => 'post',
33
+ )
 
 
 
34
  );
35
 
36
+ // get account from registry, if empty create a new one
37
+ $account = Mage::registry('current_emvaccount');
38
+ if (null === $account) {
39
+ $account = Mage::getModel('emvcore/account');
40
+ }
41
+ if ($account->getId()) {
42
  $form->addField('id', 'hidden', array(
43
  'name' => 'id',
44
  ));
45
  }
46
 
47
+ $fieldset = $form->addFieldset(
48
+ 'account_info',
49
  array(
50
  'legend' => Mage::helper('emvcore')->__('Account Information'),
51
+ )
52
+ );
53
 
54
  $fieldset->addField('name', 'text', array(
55
+ 'value' => '',
56
+ 'label' => Mage::helper('emvcore')->__('Account Name'),
57
+ 'name' => 'name',
58
  'required' => true,
59
+ 'class' => 'required-entry',
60
  ));
61
 
62
+ // api credential
63
+ $fieldset = $form->addFieldset(
64
+ 'api_info',
65
  array(
66
  'legend' => Mage::helper('emvcore')->__('API Information'),
67
+ )
68
+ );
69
 
70
  $fieldset->addField('account_login', 'text', array(
71
+ 'value' => '',
72
+ 'label' => Mage::helper('emvcore')->__('API Login'),
73
+ 'name' => 'account_login',
74
  'required' => true,
75
+ 'class' => 'required-entry',
76
  ));
77
 
78
  $fieldset->addField('account_password', 'password', array(
79
+ 'value' => '',
80
+ 'label' => Mage::helper('emvcore')->__('API Password'),
81
+ 'name' => 'account_password',
82
  'required' => true,
83
+ 'class' => 'required-entry',
84
  ));
85
 
86
  $fieldset->addField('manager_key', 'text', array(
87
+ 'value' => '',
88
+ 'label' => Mage::helper('emvcore')->__('API Manager Key'),
89
+ 'name' => 'manager_key',
90
  'required' => true,
91
+ 'class' => 'required-entry',
92
  ));
93
 
94
+ // proxy
95
+ $fieldset = $form->addFieldset(
96
+ 'proxy_info',
97
  array(
98
  'legend' => Mage::helper('emvcore')->__('Proxy Information'),
99
+ )
100
+ );
101
 
102
  $fieldset->addField('use_proxy', 'select', array(
103
+ 'value' => '',
104
+ 'label' => Mage::helper('emvcore')->__('API Uses Proxy'),
105
+ 'name' => 'use_proxy',
106
  'required' => true,
107
+ 'class' => 'validate-select',
108
+ 'values' => $this->_getYesNoArray(),
109
  ));
110
 
111
  $fieldset->addField('proxy_host', 'text', array(
112
+ 'value' => '',
113
+ 'label' => Mage::helper('emvcore')->__('Proxy Host'),
114
+ 'name' => 'proxy_host',
115
  ));
116
 
117
  $fieldset->addField('proxy_port', 'text', array(
118
  'value' => '',
119
  'label' => Mage::helper('emvcore')->__('Proxy Port'),
120
+ 'name' => 'proxy_port',
121
  'class' => 'validate-digits validate-greater-than-zero',
122
  ));
123
 
124
+ // urls
125
+ $fieldset = $form->addFieldset(
126
+ 'emv_urls',
127
+ array(
128
+ 'legend' => Mage::helper('emvcore')->__('Associated Webservice Urls'),
129
+ )
130
+ );
131
+ $fieldset->addField('available_webservices', 'select', array(
132
+ 'value' => '',
133
+ 'label' => Mage::helper('emvcore')->__('Available Webservices'),
134
+ 'name' => 'available_webservices',
135
+ 'values' => $account->getAvailableUrlTypesToEnter(),
136
+ ));
137
+
138
+ // add a new block to handle associated urls
139
+ $this->getChild('webservice')->setData('account', $account);
140
+ $fieldset->addField('webservice', 'note', array(
141
+ 'text' => $this->getChildHtml('webservice'),
142
+ ));
143
+
144
  $form->setUseContainer(true);
145
+ $form->setValues($account->getData());
146
  $this->setForm($form);
147
 
148
  return parent::_prepareForm();
149
  }
150
+
151
+ /**
152
+ * Get yes/no array
153
+ * @return array
154
+ */
155
+ protected function _getYesNoArray()
156
+ {
157
+ return array (
158
+ array (
159
+ 'value' => 0,
160
+ 'label' => Mage::helper('emvcore')->__('No')
161
+ ),
162
+ array(
163
+ 'value' => 1,
164
+ 'label' => Mage::helper('emvcore')->__('Yes')
165
+ ),
166
+ );
167
+ }
168
+
169
  }
app/code/community/Emv/Core/Block/Adminhtml/Account/Grid.php CHANGED
@@ -1,16 +1,19 @@
1
  <?php
2
  /**
 
3
  *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{66EEC752-FAC7-46e5-A082-FD050EC3BC62}
8
  */
9
  class Emv_Core_Block_Adminhtml_Account_Grid extends Mage_Adminhtml_Block_Widget_Grid
10
  {
11
-
12
  /**
13
- * opGUID{D8AC98BA-2A6A-4aac-A726-509BE45E2043}
 
 
 
14
  */
15
  protected function _prepareCollection()
16
  {
@@ -20,22 +23,47 @@ class Emv_Core_Block_Adminhtml_Account_Grid extends Mage_Adminhtml_Block_Widget_
20
  }
21
 
22
  /**
23
- * opGUID{69D76EE2-77B8-4186-A241-5B93CBCD26FD}
 
 
24
  */
25
  protected function _prepareColumns()
26
  {
 
27
  $this->addColumn('id', array(
28
  'header' => Mage::helper('emvcore')->__('Account ID'),
29
  'index' => 'id',
30
  'type' => 'number',
31
  ));
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  $this->addColumn('name', array(
34
- 'header' => Mage::helper('emvcore')->__('Campaign Commander Account'),
35
  'index' => 'name',
36
  'type' => 'varchar',
37
  ));
38
 
 
39
  $this->addColumn('action', array(
40
  'header' => Mage::helper('emvcore')->__('Action'),
41
  'type' => 'action',
@@ -58,7 +86,7 @@ class Emv_Core_Block_Adminhtml_Account_Grid extends Mage_Adminhtml_Block_Widget_
58
  }
59
 
60
  /**
61
- * opGUID{C2E0A665-A06F-49e1-BECB-CB983C5CF7C6}
62
  *
63
  * @param var $row
64
  */
1
  <?php
2
  /**
3
+ * This block is used to manage account grid list
4
  *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
  */
10
  class Emv_Core_Block_Adminhtml_Account_Grid extends Mage_Adminhtml_Block_Widget_Grid
11
  {
 
12
  /**
13
+ * Prepare SmartFocus Account Collection
14
+ *
15
+ * (non-PHPdoc)
16
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareCollection()
17
  */
18
  protected function _prepareCollection()
19
  {
23
  }
24
 
25
  /**
26
+ * Prepare columns
27
+ * (non-PHPdoc)
28
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareColumns()
29
  */
30
  protected function _prepareColumns()
31
  {
32
+ // Account id
33
  $this->addColumn('id', array(
34
  'header' => Mage::helper('emvcore')->__('Account ID'),
35
  'index' => 'id',
36
  'type' => 'number',
37
  ));
38
 
39
+ // Created at
40
+ $this->addColumn('created_at', array(
41
+ 'header' => Mage::helper('sales')->__('Created At'),
42
+ 'type' => 'datetime',
43
+ 'width' => '150',
44
+ 'align' => 'center',
45
+ 'index' => 'created_at',
46
+ 'gmtoffset' => true
47
+ ));
48
+
49
+ // Update at
50
+ $this->addColumn('updated_at', array(
51
+ 'header' => Mage::helper('sales')->__('Updated At'),
52
+ 'type' => 'datetime',
53
+ 'width' => '150',
54
+ 'align' => 'center',
55
+ 'index' => 'updated_at',
56
+ 'gmtoffset' => true
57
+ ));
58
+
59
+ // Name
60
  $this->addColumn('name', array(
61
+ 'header' => Mage::helper('emvcore')->__('SmartFocus Account'),
62
  'index' => 'name',
63
  'type' => 'varchar',
64
  ));
65
 
66
+ // Row Action
67
  $this->addColumn('action', array(
68
  'header' => Mage::helper('emvcore')->__('Action'),
69
  'type' => 'action',
86
  }
87
 
88
  /**
89
+ * Get row url
90
  *
91
  * @param var $row
92
  */
app/code/community/Emv/Core/Block/Adminhtml/Accounts.php CHANGED
@@ -1,32 +1,25 @@
1
  <?php
2
  /**
 
3
  *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr> <info@x2i.fr> <info@x2i.fr>
7
- * @version 1.0 eaGUID{43207B49-AF4C-46b9-A581-0B5EBF25A514} e eaGUID{F29DB436-
8
- * 7579-4c33-853F-4A002D9CBE2E}
9
  */
10
  class Emv_Core_Block_Adminhtml_Accounts extends Mage_Adminhtml_Block_Widget_Grid_Container
11
  {
12
 
13
  /**
14
- * opGUID{F0DC9F42-A5E1-4555-A620-A8C6F4FB58D6}
15
- */
16
- protected function _prepareLayout()
17
- {
18
- parent::_prepareLayout();
19
- }
20
-
21
- /**
22
- * opGUID{F99345CD-7535-4bb3-B834-20FD54BCE28D}
23
  */
24
  public function __construct()
25
  {
26
  parent::__construct();
27
  $this->_blockGroup = 'emvcore';
28
  $this->_controller = 'adminhtml_account';
29
- $this->_headerText = Mage::helper('emvcore')->__('Campaign Commander Accounts');
30
  $this->_updateButton('add', 'label', Mage::helper('emvcore')->__('Add New Account'));
31
  }
32
 
1
  <?php
2
  /**
3
+ * This block is used to manage account grid list
4
  *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
 
9
  */
10
  class Emv_Core_Block_Adminhtml_Accounts extends Mage_Adminhtml_Block_Widget_Grid_Container
11
  {
12
 
13
  /**
14
+ * Construct account menu
15
+ * @see Mage_Adminhtml_Block_Widget_Grid_Container::__construct()
 
 
 
 
 
 
 
16
  */
17
  public function __construct()
18
  {
19
  parent::__construct();
20
  $this->_blockGroup = 'emvcore';
21
  $this->_controller = 'adminhtml_account';
22
+ $this->_headerText = Mage::helper('emvcore')->__('SmartFocus Accounts');
23
  $this->_updateButton('add', 'label', Mage::helper('emvcore')->__('Add New Account'));
24
  }
25
 
app/code/community/Emv/Core/Exception.php DELETED
@@ -1,4 +0,0 @@
1
- <?php
2
- class Emv_Core_Exception extends Mage_Core_Exception
3
- {
4
- }
 
 
 
 
app/code/community/Emv/Core/Helper/Config.php DELETED
@@ -1,5 +0,0 @@
1
- <?php
2
- class Emv_Core_Helper_Config
3
- {
4
- const EMV_ACCOUNT_STORE_ATTRIBUTE_NAME = 'emvcore/emv_account/account';
5
- }
 
 
 
 
 
app/code/community/Emv/Core/Helper/Data.php CHANGED
@@ -1,12 +1,156 @@
1
  <?php
2
  /**
 
3
  *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{2C79A28D-B570-44c5-9CA2-0B9E84C54D87}
8
  */
9
  class Emv_Core_Helper_Data extends Mage_Core_Helper_Abstract
10
  {
11
- public $LOG_FILE = 'EmvCore.log';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  }
1
  <?php
2
  /**
3
+ * Emv core helper
4
  *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
  */
10
  class Emv_Core_Helper_Data extends Mage_Core_Helper_Abstract
11
  {
12
+ /**
13
+ * List of accounts
14
+ * @var array
15
+ */
16
+ protected $_accountList = array();
17
+
18
+ /**
19
+ * Get account for a given id
20
+ *
21
+ * @param string $id
22
+ * @return NULL|Emv_Core_Model_Account
23
+ */
24
+ public function getAccount($id)
25
+ {
26
+ if (!$id) {
27
+ return null;
28
+ }
29
+
30
+ if (!isset($this->_accountList[$id])) {
31
+ $account = Mage::getModel('emvcore/account')->load($id);
32
+ $this->_accountList[$id] = $account;
33
+ }
34
+ return $this->_accountList[$id];
35
+ }
36
+
37
+ /**
38
+ * Get lock file path directory
39
+ * @return string
40
+ */
41
+ public static function getLockPathDir()
42
+ {
43
+ return Mage::getBaseDir('export') . DS . 'emailvision' . DS . 'locks';
44
+ }
45
+
46
+ /**
47
+ * GET Lock handler
48
+ *
49
+ * @return Varien_Io_File
50
+ */
51
+ protected function _getLockHandler()
52
+ {
53
+ $args = array(
54
+ 'path' => $this->getLockPathDir(),
55
+ );
56
+ $mageFile = new Varien_Io_File();
57
+ $mageFile->setAllowCreateFolders(true);
58
+ $mageFile->open($args);
59
+ return $mageFile;
60
+ }
61
+
62
+ /**
63
+ * Create a lock file
64
+ *
65
+ * @param string $content
66
+ * @return number | boolean - false
67
+ */
68
+ public function createLockFile($fileName, $content = '')
69
+ {
70
+ if (!$content) {
71
+ $content = Mage::getModel('core/date')->date('Y-m-d H:i:s');
72
+ }
73
+
74
+ return $this->_getLockHandler()->write($fileName, $content);
75
+ }
76
+
77
+ /**
78
+ * Remove a lock file
79
+ *
80
+ * @param string $fileName
81
+ * @return boolean
82
+ */
83
+ public function removeLockFile($fileName)
84
+ {
85
+ return $this->_getLockHandler()->rm($fileName);
86
+ }
87
+
88
+ /**
89
+ * Check if lock file exists
90
+ * @param string $fileName
91
+ * @return boolean
92
+ */
93
+ public function checkLockFile($fileName)
94
+ {
95
+ return $this->_getLockHandler()->fileExists($fileName, true);
96
+ }
97
+
98
+ /**
99
+ * @param string $path
100
+ * @param mixed $store
101
+ * @param int $websiteId
102
+ * @return mixed
103
+ */
104
+ public function getAdminScopedConfig($path, $store = null, $websiteId = null)
105
+ {
106
+ if (!is_null($store)) {
107
+ return Mage::getStoreConfig($path, $store);
108
+ } elseif (!is_null($websiteId)) {
109
+ $website = Mage::app()->getWebsite($websiteId);
110
+ return $website->getConfig($path);
111
+ }
112
+
113
+ $action = Mage::app()->getFrontController()->getAction();
114
+ if ($action instanceOf Mage_Adminhtml_System_ConfigController) {
115
+ if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
116
+ $store = Mage::app()->getStore($storeCode);
117
+ return $store->getConfig($path);
118
+ } elseif ($websiteCode = Mage::app()->getRequest()->getParam('website')){
119
+ $website = Mage::app()->getWebsite($websiteCode);
120
+ return $website->getConfig($path);
121
+ } else if ($groupCode = Mage::app()->getRequest()->getParam('group')){
122
+ $website = Mage::app()->getGroup($groupCode)->getWebsite();
123
+ return $website->getConfig($path);
124
+ }
125
+ }
126
+
127
+ return Mage::getStoreConfig($path);
128
+ }
129
+
130
+ /**
131
+ * Format number in a given locale
132
+ *
133
+ * @param float $number
134
+ * @param string $locale
135
+ * @param int $precision
136
+ * @return string
137
+ */
138
+ public function formatNumberInLocale($number, $locale = null, $precision = 2)
139
+ {
140
+ if ($locale == null) {
141
+ $locale = Mage::app()->getLocale()->getLocaleCode();
142
+ }
143
+
144
+ $format = Zend_Locale_Data::getContent($locale, 'decimalnumber');
145
+ $number = Zend_Locale_Format::toNumber(
146
+ $number,
147
+ array(
148
+ 'locale' => $locale,
149
+ 'number_format' => $format,
150
+ 'precision' => $precision
151
+ )
152
+ );
153
+ return $number;
154
+ }
155
+
156
  }
app/code/community/Emv/Core/Model/Account.php CHANGED
@@ -1,16 +1,27 @@
1
  <?php
2
- /**
3
- *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{325B4237-19CC-4d7a-9BDA-71F947B5C240}
 
 
8
  */
9
  class Emv_Core_Model_Account extends Mage_Core_Model_Abstract
10
  {
 
 
 
 
 
 
 
11
 
12
  /**
13
- * opGUID{661B978A-5776-44cd-A9DD-00E8595A521B}
 
 
14
  */
15
  public function _construct()
16
  {
@@ -18,20 +29,122 @@ class Emv_Core_Model_Account extends Mage_Core_Model_Abstract
18
  }
19
 
20
  /**
21
- * opGUID{3A83B26B-6585-42f0-96DB-BBDBA31618D1}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  */
23
- protected function beforeSave()
24
  {
25
- $this->validate();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
  return parent::_beforeSave();
27
  }
28
 
29
  /**
30
- * opGUID{6A56E697-EEC4-46b8-85FF-0F36697FAB61}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  */
32
  public function validate()
33
  {
34
- $error = array();
35
 
36
  if (!Zend_Validate::is($this->getName(), 'NotEmpty')) {
37
  $errors[] = Mage::helper('emvcore')->__('Name is required.');
@@ -49,35 +162,26 @@ class Emv_Core_Model_Account extends Mage_Core_Model_Abstract
49
  $errors[] = Mage::helper('emvcore')->__('API Manager key is required field.');
50
  }
51
 
 
52
  if($this->getUse_proxy() && (null === $this->getProxyHost() || null === $this->getProxyPort()))
53
  {
54
  $errors[] = Mage::helper('emvcore')->__('Proxy host and port are required.');
55
- $error = 1;
56
  }
57
 
 
58
  if ($this->nameExists()) {
59
  $errors[] = Mage::helper('emvcore')->__('Account with the same name already exists.');
60
  }
61
 
 
62
  if ($this->managerKeyExists()) {
63
  $errors[] = Mage::helper('emvcore')
64
  ->__('Account with the same API manager key already exists.');
65
  }
66
 
67
- // check if account is valid
68
- try {
69
- /* @var $soap Emv_Core_Model_Service_Soap_Api */
70
- $soap = Mage::getModel('emvcore/service_soap_api', $this);
71
- $soap->openApiConnection();
72
- } catch (Emv_Core_Exception $e) {
73
- if($e->getCode() === 2)
74
- {
75
- $errors[] = $e->getMessage();
76
- }
77
- else
78
- {
79
- $errors[] = Mage::helper('emvcore')->__('This EMV account is invalid.');
80
- }
81
  }
82
 
83
  if (empty($errors)) {
@@ -86,12 +190,164 @@ class Emv_Core_Model_Account extends Mage_Core_Model_Abstract
86
  return $errors;
87
  }
88
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  public function nameExists()
90
  {
91
  $result = $this->_getResource()->nameExists($this);
92
  return (is_array($result) && count($result) > 0 ) ? true : false;
93
  }
94
 
 
 
 
 
95
  public function managerKeyExists()
96
  {
97
  $result = $this->_getResource()->managerKeyExists($this);
1
  <?php
2
+ /**
3
+ * Emailvision account class
4
+ * emv_urls => $type => array('url' => $url)
5
+ *
6
+ * @category Emv
7
+ * @package Emv_Core
8
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
9
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
10
  */
11
  class Emv_Core_Model_Account extends Mage_Core_Model_Abstract
12
  {
13
+ /**
14
+ * Constant types
15
+ */
16
+ const URL_TRANSACTIONAL_SERVICE_TYPE = 'transactional';
17
+ const URL_REST_NOTIFICATION_SERVICE_TYPE = 'rest_notification';
18
+ const URL_BATCH_MEMBER_SERVICE_TYPE = 'batch_member';
19
+ const URL_MEMBER_SERVICE_TYPE = 'member';
20
 
21
  /**
22
+ * Constructor
23
+ *
24
+ * @see Varien_Object::_construct()
25
  */
26
  public function _construct()
27
  {
29
  }
30
 
31
  /**
32
+ * Get Allowed Url Types
33
+ *
34
+ * @return array
35
+ */
36
+ public static function getAllowedUrlTypes()
37
+ {
38
+ return array(
39
+ self::URL_TRANSACTIONAL_SERVICE_TYPE,
40
+ self::URL_REST_NOTIFICATION_SERVICE_TYPE,
41
+ self::URL_BATCH_MEMBER_SERVICE_TYPE,
42
+ self::URL_MEMBER_SERVICE_TYPE
43
+ );
44
+ }
45
+
46
+ /**
47
+ * @return array
48
+ */
49
+ public static function getUrlTypesToTestCredential()
50
+ {
51
+ return array(
52
+ self::URL_TRANSACTIONAL_SERVICE_TYPE,
53
+ self::URL_BATCH_MEMBER_SERVICE_TYPE,
54
+ self::URL_MEMBER_SERVICE_TYPE
55
+ );
56
+ }
57
+
58
+ /**
59
+ * Get available url types that account can have
60
+ *
61
+ * @return array
62
  */
63
+ public function getAvailableUrlTypesToEnter()
64
  {
65
+ $emvUrls = $this->getEmvUrls();
66
+ $allAvailable = self::getAllowedUrlTypes();
67
+ $available = $allAvailable;
68
+ if (is_array($emvUrls) && count($emvUrls)) {
69
+ // try to take the rest of types
70
+ $usedTypes = array_keys($emvUrls);
71
+ $available = array_diff($allAvailable, $usedTypes);
72
+ }
73
+
74
+ $options = array();
75
+ $servicesAndLabels = self::getUrlTypesAndLabels();
76
+ foreach($available as $type) {
77
+ if (isset($servicesAndLabels[$type])) {
78
+ $options[] = array(
79
+ 'value' => $type,
80
+ 'label' => $servicesAndLabels[$type]
81
+ );
82
+ }
83
+ }
84
+
85
+ return $options;
86
+ }
87
+
88
+ /**
89
+ * Get url types and labels
90
+ *
91
+ * @return array
92
+ */
93
+ public static function getUrlTypesAndLabels()
94
+ {
95
+ return array (
96
+ self::URL_TRANSACTIONAL_SERVICE_TYPE => Mage::helper('emvcore')->__('Transactional Service'),
97
+ self::URL_REST_NOTIFICATION_SERVICE_TYPE => Mage::helper('emvcore')->__('REST Notification Service'),
98
+ self::URL_BATCH_MEMBER_SERVICE_TYPE => Mage::helper('emvcore')->__('Batch Member Service'),
99
+ self::URL_MEMBER_SERVICE_TYPE => Mage::helper('emvcore')->__('Member Service')
100
+ );
101
+ }
102
+
103
+ /**
104
+ * All urls need to be serialized before saving
105
+ *
106
+ * (non-PHPdoc)
107
+ * @see Mage_Core_Model_Abstract::_beforeSave()
108
+ */
109
+ protected function _beforeSave()
110
+ {
111
+ $emvUrls = $this->getData('emv_urls');
112
+ if ($emvUrls && is_array($emvUrls)) {
113
+ $this->setData('emv_urls', serialize($emvUrls));
114
+ }
115
+
116
+ // update datetime field
117
+ $gmtDate = Mage::getModel('core/date')->gmtDate();
118
+ if (!$this->getId()) {
119
+ $this->setData('created_at', $gmtDate);
120
+ }
121
+ $this->setData('updated_at', $gmtDate);
122
+
123
  return parent::_beforeSave();
124
  }
125
 
126
  /**
127
+ * Get emv urls
128
+ * @return array
129
+ */
130
+ public function getEmvUrls()
131
+ {
132
+ $emvUrls = $this->getData('emv_urls');
133
+ if ($emvUrls && !is_array($emvUrls)) {
134
+ $this->setData('emv_urls', unserialize($emvUrls));
135
+ }
136
+
137
+ return $this->getData('emv_urls');
138
+ }
139
+
140
+ /**
141
+ * Validate account - if everything is ok, return true - else the list of erros
142
+ *
143
+ * @return boolean|array
144
  */
145
  public function validate()
146
  {
147
+ $errors = array();
148
 
149
  if (!Zend_Validate::is($this->getName(), 'NotEmpty')) {
150
  $errors[] = Mage::helper('emvcore')->__('Name is required.');
162
  $errors[] = Mage::helper('emvcore')->__('API Manager key is required field.');
163
  }
164
 
165
+ // proxy
166
  if($this->getUse_proxy() && (null === $this->getProxyHost() || null === $this->getProxyPort()))
167
  {
168
  $errors[] = Mage::helper('emvcore')->__('Proxy host and port are required.');
 
169
  }
170
 
171
+ // check account name
172
  if ($this->nameExists()) {
173
  $errors[] = Mage::helper('emvcore')->__('Account with the same name already exists.');
174
  }
175
 
176
+ // check manager key
177
  if ($this->managerKeyExists()) {
178
  $errors[] = Mage::helper('emvcore')
179
  ->__('Account with the same API manager key already exists.');
180
  }
181
 
182
+ $apiErrors = $this->validateApiCredential();
183
+ if (count($apiErrors) > 0) {
184
+ $errors = array_merge($errors, $apiErrors);
 
 
 
 
 
 
 
 
 
 
 
185
  }
186
 
187
  if (empty($errors)) {
190
  return $errors;
191
  }
192
 
193
+ /**
194
+ * Validate api credential
195
+ *
196
+ * @return array
197
+ */
198
+ public function validateApiCredential()
199
+ {
200
+ $errors = array();
201
+
202
+ // check whether all given urls are valid
203
+ $invalidUrls = $this->checkEmvUrls();
204
+ if (count($invalidUrls)) {
205
+ $errors = array_merge($errors, $invalidUrls);
206
+ } else {
207
+ $typeToTest = '';
208
+ $url = false;
209
+ $labels = array();
210
+
211
+ // service urls
212
+ $emvUrls = $this->getData('emv_urls');
213
+ // find a service url to check credential
214
+ foreach (self::getUrlTypesToTestCredential() as $type) {
215
+ if (isset($emvUrls[$type])) {
216
+ $typeToTest = $type;
217
+ $url = $emvUrls[$type]['url'];
218
+ break;
219
+ } else {
220
+ $servicesAndLabels = self::getUrlTypesAndLabels();
221
+ if (isset($servicesAndLabels[$type])) {
222
+ $labels[] = $servicesAndLabels[$type];
223
+ }
224
+ }
225
+ }
226
+
227
+ if (!$url || !$typeToTest) {
228
+ $errors[] = Mage::helper('emvcore')
229
+ ->__('You need to enter at least one of the following service(s) : %s', implode(', ', $labels));
230
+ } else {
231
+ $serviceClient = null;
232
+ switch($typeToTest) {
233
+ case self::URL_TRANSACTIONAL_SERVICE_TYPE:
234
+ $serviceClient = Mage::getModel('emvcore/service_transactional');
235
+ break;
236
+ case self::URL_BATCH_MEMBER_SERVICE_TYPE:
237
+ $serviceClient = Mage::getModel('emvcore/service_batchMember');
238
+ break;
239
+ case self::URL_MEMBER_SERVICE_TYPE:
240
+ $serviceClient = Mage::getModel('emvcore/service_member');
241
+ break;
242
+ }
243
+
244
+ // check if account is valid
245
+ try {
246
+ $serviceClient->setAccount($this);
247
+ $serviceClient->checkConnection();
248
+ } catch (EmailVision_Api_Exception $e) {
249
+ if ($e->isRecoverable()) {
250
+ $errors[] = Mage::helper('emvcore')
251
+ ->__('Connection problem. Could not check api credential, please try again');
252
+ } else {
253
+ $errors[] = Mage::helper('emvcore'
254
+ )->__('This SmartFocus account is invalid. Please check your API credential');
255
+ }
256
+ }
257
+ }
258
+ }
259
+
260
+ return $errors;
261
+ }
262
+
263
+ /**
264
+ * Check all given SmartFocus service urls are valid.
265
+ * Return the eventual error messages in case of error
266
+ *
267
+ * @return array
268
+ */
269
+ public function checkEmvUrls()
270
+ {
271
+ $errors = array();
272
+ $emvUrls = $this->getData('emv_urls');
273
+
274
+ if (!$emvUrls || !is_array($emvUrls)) {
275
+ $errors[] = Mage::helper('emvcore')
276
+ ->__('This SmartFocus account does not have any SmartFocus service url');
277
+ } else {
278
+ // check if the urls are valid
279
+ foreach ($emvUrls as $type => $urlData) {
280
+ if (!in_array($type, self::getAllowedUrlTypes())) {
281
+ $errors[] = Mage::helper('emvcore')->__('%s is unknown by SmartFocus platform.', $type);
282
+ } else {
283
+ $invalidUrl = true;
284
+ if (is_array($urlData) && isset($urlData['url']) && Zend_Validate::is($urlData['url'], 'NotEmpty')) {
285
+ $url = $urlData['url'];
286
+
287
+ //get a Zend_Uri_Http object for our URL, this will only accept http(s) schemes
288
+ try {
289
+ $uriHttp = Zend_Uri_Http::fromString($url);
290
+ // if we have a valid URI then we check the hostname for valid TLDs, and not local urls
291
+ // do not allow local hostnames, this is the default
292
+ $hostnameValidator = new Zend_Validate_Hostname(Zend_Validate_Hostname::ALLOW_DNS);
293
+ if ($hostnameValidator->isValid($uriHttp->getHost())) {
294
+ $invalidUrl = false;
295
+ }
296
+ } catch (Exception $e) {
297
+ // here does not need to catch exception!!!
298
+ // Zend_Uri_Http::fromString will generate an exception if the protocol given in url is not supported
299
+ }
300
+ }
301
+
302
+ if ($invalidUrl) {
303
+ $servicesAndLabels = self::getUrlTypesAndLabels();
304
+ if (isset($servicesAndLabels[$type])) {
305
+ $errors[] = Mage::helper('emvcore')
306
+ ->__('Please enter a valid url for %s!', $servicesAndLabels[$type]);
307
+ }
308
+ }
309
+ }
310
+ }
311
+ }
312
+
313
+ return $errors;
314
+ }
315
+
316
+ /**
317
+ * Get url for type
318
+ * - if type is not allowed or not defined return false,
319
+ * - else the predefined url
320
+ *
321
+ * @param string $type
322
+ * @return boolean|string
323
+ */
324
+ public function getUrlForType($type)
325
+ {
326
+ $url = false;
327
+ if (in_array($type, self::getAllowedUrlTypes())) {
328
+ $emvUrls = $this->getEmvUrls();
329
+ if (isset($emvUrls[$type]) && isset($emvUrls[$type]['url'])) {
330
+ $url = $emvUrls[$type]['url'];
331
+ }
332
+ }
333
+ return $url;
334
+ }
335
+
336
+ /**
337
+ * Check if account name exists in database
338
+ *
339
+ * @return boolean
340
+ */
341
  public function nameExists()
342
  {
343
  $result = $this->_getResource()->nameExists($this);
344
  return (is_array($result) && count($result) > 0 ) ? true : false;
345
  }
346
 
347
+ /**
348
+ * Check if manager key exists in database
349
+ * @return boolean
350
+ */
351
  public function managerKeyExists()
352
  {
353
  $result = $this->_getResource()->managerKeyExists($this);
app/code/community/Emv/Core/Model/Adminhtml/System/Config/Backend/Account/Abstract.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Account Backend model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ abstract class Emv_Core_Model_Adminhtml_System_Config_Backend_Account_Abstract extends Mage_Core_Model_Config_Data
10
+ {
11
+ /**
12
+ * @var string
13
+ */
14
+ protected $_urlType = '';
15
+
16
+ /**
17
+ * @var Emv_Core_Model_Account
18
+ */
19
+ protected $_account;
20
+
21
+ /**
22
+ * @return Emv_Core_Model_Service_Abstract
23
+ */
24
+ protected abstract function _getService();
25
+
26
+ /**
27
+ * Check if account is valid
28
+ * - posesses a valid url
29
+ * - is allowed to use the defined service
30
+ *
31
+ * (non-PHPdoc)
32
+ * @see Mage_Core_Model_Abstract::_beforeSave()
33
+ */
34
+ protected function _beforeSave()
35
+ {
36
+ if ($this->isValueChanged() && $this->getValue()) {
37
+ $account = $this->_getAccount();
38
+ if (!$account->getId()) {
39
+ Mage::throwException(Mage::helper('emvcore')->__('Your selected account does not exist anymore!'));
40
+ }
41
+
42
+ // check url
43
+ $url = $this->_checkAndGetUrlForType($account, $this->_urlType);
44
+
45
+ try {
46
+ // check credentials
47
+ $service = $this->_getService();
48
+ $service->setAccount($account);
49
+ $service->checkConnection();
50
+ } catch (EmailVision_Api_Exception $e) {
51
+ if ($e->isRecoverable()) {
52
+ Mage::throwException(
53
+ Mage::helper('emvcore')
54
+ ->__('Could not verify the account. Network problems occured! Please Save again!')
55
+ );
56
+ } else {
57
+ $labels = Emv_Core_Model_Account::getUrlTypesAndLabels();
58
+ $serviceLabel = $this->_urlType;
59
+ if (isset($labels[$this->_urlType])) {
60
+ $serviceLabel = $labels[$this->_urlType];
61
+ }
62
+ Mage::throwException(
63
+ Mage::helper('emvcore')
64
+ ->__('Your account "%s" is not allowed for %s !', $account->getName(), $serviceLabel)
65
+ );
66
+ }
67
+ }
68
+ }
69
+ return parent::_beforeSave();
70
+ }
71
+
72
+ /**
73
+ * Get EmailVision account
74
+ *
75
+ * @return Emv_Core_Model_Account
76
+ */
77
+ protected function _getAccount()
78
+ {
79
+ if ($this->_account == null) {
80
+ $this->_account = Mage::getModel('emvcore/account')->load($this->getValue());
81
+ }
82
+ return $this->_account;
83
+ }
84
+
85
+ /**
86
+ * @param Emv_Core_Model_Account $account
87
+ * @param string $type
88
+ * @return boolean|string
89
+ */
90
+ protected function _checkAndGetUrlForType(Emv_Core_Model_Account $account, $type)
91
+ {
92
+ // get service label
93
+ $labels = Emv_Core_Model_Account::getUrlTypesAndLabels();
94
+ $serviceLabel = $type;
95
+ if (isset($labels[$type])) {
96
+ $serviceLabel = $labels[$type];
97
+ }
98
+
99
+ // check url
100
+ $url = $account->getUrlForType($type);
101
+ if (!$url) {
102
+ Mage::throwException(Mage::helper('emvcore')->__('Please define a valid url for %s !', $serviceLabel));
103
+ }
104
+
105
+ return $url;
106
+ }
107
+ }
app/code/community/Emv/Core/Model/Adminhtml/System/Config/Backend/Enabled.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Enabled Backend Model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_Core_Model_Adminhtml_System_Config_Backend_Enabled extends Mage_Core_Model_Config_Data
10
+ {
11
+ /**
12
+ * @var string
13
+ */
14
+ protected $_processName = '';
15
+
16
+ /**
17
+ * Allow to enable the service when having a valid account
18
+ *
19
+ * (non-PHPdoc)
20
+ * @see Mage_Core_Model_Abstract::_beforeSave()
21
+ */
22
+ protected function _beforeSave()
23
+ {
24
+ if ($this->getValue()) {
25
+ $account = $this->getFieldsetDataValue('account');
26
+ if (!$account) {
27
+ Mage::throwException(
28
+ Mage::helper('emvcore')
29
+ ->__('Could not enable "%s" process ! Please select an account in the list !', $this->_processName)
30
+ );
31
+ }
32
+ }
33
+ parent::_beforeSave();
34
+ }
35
+ }
app/code/community/Emv/Core/Model/Mysql4/Account.php CHANGED
@@ -1,22 +1,30 @@
1
  <?php
2
  /**
 
 
3
  *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{C39F6C25-AFD6-4986-84BF-75792E3A8B7C}
8
  */
9
  class Emv_Core_Model_Mysql4_Account extends Mage_Core_Model_Mysql4_Abstract
10
  {
11
 
12
  /**
13
- * opGUID{A4A48809-9C33-4743-A4FD-B256FE119907}
 
14
  */
15
  protected function _construct()
16
  {
17
  $this->_init('emvcore/account','id');
18
  }
19
 
 
 
 
 
 
20
  public function nameExists(Mage_Core_Model_Abstract $account)
21
  {
22
  $accountTable = $this->getTable('emvcore/account');
@@ -27,12 +35,17 @@ class Emv_Core_Model_Mysql4_Account extends Mage_Core_Model_Mysql4_Abstract
27
  return $this->_getReadAdapter()->fetchRow($select);
28
  }
29
 
 
 
 
 
 
30
  public function managerKeyExists(Mage_Core_Model_Abstract $account)
31
  {
32
  $accountTable = $this->getTable('emvcore/account');
33
  $select = $this->_getReadAdapter()->select();
34
  $select->from($accountTable);
35
- $select->where("{$accountTable}.manager_key = ?", addslashes($account->getManager_key()));
36
  $select->where("{$accountTable}.id != ?", $account->getId());
37
  return $this->_getReadAdapter()->fetchRow($select);
38
  }
1
  <?php
2
  /**
3
+ * Emailvision account resource model class
4
+ * emv_urls => $type => array('url' => $url)
5
  *
6
+ * @category Emv
7
+ * @package Emv_Core
8
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
9
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
10
  */
11
  class Emv_Core_Model_Mysql4_Account extends Mage_Core_Model_Mysql4_Abstract
12
  {
13
 
14
  /**
15
+ * (non-PHPdoc)
16
+ * @see Mage_Core_Model_Resource_Abstract::_construct()
17
  */
18
  protected function _construct()
19
  {
20
  $this->_init('emvcore/account','id');
21
  }
22
 
23
+ /**
24
+ * Check if account name exists in database
25
+ * @param Mage_Core_Model_Abstract $account
26
+ * @return null | array
27
+ */
28
  public function nameExists(Mage_Core_Model_Abstract $account)
29
  {
30
  $accountTable = $this->getTable('emvcore/account');
35
  return $this->_getReadAdapter()->fetchRow($select);
36
  }
37
 
38
+ /**
39
+ * Check if api manager key exsits in database
40
+ * @param Mage_Core_Model_Abstract $account
41
+ * @return null | array
42
+ */
43
  public function managerKeyExists(Mage_Core_Model_Abstract $account)
44
  {
45
  $accountTable = $this->getTable('emvcore/account');
46
  $select = $this->_getReadAdapter()->select();
47
  $select->from($accountTable);
48
+ $select->where("{$accountTable}.manager_key = ?", addslashes($account->getManagerKey()));
49
  $select->where("{$accountTable}.id != ?", $account->getId());
50
  return $this->_getReadAdapter()->fetchRow($select);
51
  }
app/code/community/Emv/Core/Model/Mysql4/Account/Collection.php CHANGED
@@ -1,22 +1,22 @@
1
  <?php
2
  /**
3
- *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{9734C4FC-55E8-4a2c-A2C8-57A4F5E406E2}
8
  */
9
  class Emv_Core_Model_Mysql4_Account_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
10
  {
11
-
12
- /**
13
- * opGUID{24F53796-F8CE-4f06-9AE2-F45A57F132CF}
14
- */
15
  protected function _construct()
16
  {
17
  $this->_init('emvcore/account','emvcore/account');
18
  }
19
 
 
 
 
 
20
  public function addNameFilter($name)
21
  {
22
  $this->addFieldToFilter('name', array('like' => $name));
@@ -24,6 +24,12 @@ class Emv_Core_Model_Mysql4_Account_Collection extends Mage_Core_Model_Mysql4_Co
24
  return $this;
25
  }
26
 
 
 
 
 
 
 
27
  public function addLoginFilter($login)
28
  {
29
  $this->addFieldToFilter('login', array('like' => $login));
@@ -31,6 +37,11 @@ class Emv_Core_Model_Mysql4_Account_Collection extends Mage_Core_Model_Mysql4_Co
31
  return $this;
32
  }
33
 
 
 
 
 
 
34
  public function addManagerKeyFilter($keyManager)
35
  {
36
  $this->addFieldToFilter('manager_key', array('like' => $keyManager));
@@ -38,6 +49,12 @@ class Emv_Core_Model_Mysql4_Account_Collection extends Mage_Core_Model_Mysql4_Co
38
  return $this;
39
  }
40
 
 
 
 
 
 
 
41
  public function addExcludeIdFilter($id)
42
  {
43
  $this->addFieldToFilter('id', array('neq' => $id));
@@ -45,6 +62,10 @@ class Emv_Core_Model_Mysql4_Account_Collection extends Mage_Core_Model_Mysql4_Co
45
  return $this;
46
  }
47
 
 
 
 
 
48
  public function toOptionArray()
49
  {
50
  return $this->_toOptionArray('id', 'name');
1
  <?php
2
  /**
3
+ * Emailvision account resource collection
4
+ * @category Emv
5
+ * @package Emv_Core
6
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
7
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
8
  */
9
  class Emv_Core_Model_Mysql4_Account_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
10
  {
 
 
 
 
11
  protected function _construct()
12
  {
13
  $this->_init('emvcore/account','emvcore/account');
14
  }
15
 
16
+ /**
17
+ * @param string $name
18
+ * @return Emv_Core_Model_Mysql4_Account_Collection
19
+ */
20
  public function addNameFilter($name)
21
  {
22
  $this->addFieldToFilter('name', array('like' => $name));
24
  return $this;
25
  }
26
 
27
+ /**
28
+ * Get an account corresponding to account login
29
+ *
30
+ * @param string $login
31
+ * @return Emv_Core_Model_Mysql4_Account_Collection
32
+ */
33
  public function addLoginFilter($login)
34
  {
35
  $this->addFieldToFilter('login', array('like' => $login));
37
  return $this;
38
  }
39
 
40
+ /**
41
+ * Get an account corresponding to key manager
42
+ * @param string $keyManager
43
+ * @return Emv_Core_Model_Mysql4_Account_Collection
44
+ */
45
  public function addManagerKeyFilter($keyManager)
46
  {
47
  $this->addFieldToFilter('manager_key', array('like' => $keyManager));
49
  return $this;
50
  }
51
 
52
+ /**
53
+ * Exclude id from the list
54
+ *
55
+ * @param string $id
56
+ * @return Emv_Core_Model_Mysql4_Account_Collection
57
+ */
58
  public function addExcludeIdFilter($id)
59
  {
60
  $this->addFieldToFilter('id', array('neq' => $id));
62
  return $this;
63
  }
64
 
65
+ /**
66
+ * (non-PHPdoc)
67
+ * @see Varien_Data_Collection::toOptionArray()
68
+ */
69
  public function toOptionArray()
70
  {
71
  return $this->_toOptionArray('id', 'name');
app/code/community/Emv/Core/Model/Resource/Setup.php CHANGED
@@ -1,10 +1,11 @@
1
  <?php
2
  /**
 
3
  *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{3E7D95EC-73E2-4a37-9B90-5DFC0A3C6763}
8
  */
9
  class Emv_Core_Model_Resource_Setup extends Mage_Core_Model_Resource_Setup
10
  {
1
  <?php
2
  /**
3
+ * Emv core resource setup class
4
  *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
  */
10
  class Emv_Core_Model_Resource_Setup extends Mage_Core_Model_Resource_Setup
11
  {
app/code/community/Emv/Core/Model/Service/Abstract.php ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Service Abstract class
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ abstract class Emv_Core_Model_Service_Abstract extends Mage_Core_Model_Abstract
11
+ {
12
+ /**
13
+ * Api service list separted by store
14
+ *
15
+ * @var array
16
+ */
17
+ protected $_apiService = array();
18
+
19
+ /**
20
+ * EmailVision Account
21
+ * @var Emv_Core_Model_Account
22
+ */
23
+ protected $_account;
24
+
25
+ /**
26
+ * Url type
27
+ * @var string
28
+ */
29
+ protected $_urlType = null;
30
+
31
+ /**
32
+ * Get api service
33
+ *
34
+ * @param string $storeId
35
+ * @throws Mage_Core_Exception
36
+ * @return EmailVision_Api_Common
37
+ */
38
+ public function getApiService(Emv_Core_Model_Account $account = null, $storeId = null)
39
+ {
40
+ if (!$account) {
41
+ $account = $this->getAccount();
42
+ if (!$account) {
43
+ $account = Mage::getModel('emvcore/account');
44
+ }
45
+ }
46
+
47
+ $key = 'store_id' . $storeId;
48
+ if ($account != null && $account->getId()) {
49
+ $key .= '-account_id-' . $account->getId();
50
+ } else {
51
+ $key .= '-account_id-undefined';
52
+ }
53
+
54
+ if (!isset($this->_apiService[$key])) {
55
+ $wsdl = $account->getUrlForType($this->_urlType);
56
+
57
+ if (!$wsdl) {
58
+ // prepare service label
59
+ $labels = Emv_Core_Model_Account::getUrlTypesAndLabels();
60
+ $serviceLabel = $this->_urlType;
61
+ if (isset($labels[$this->_urlType])) {
62
+ $serviceLabel = $labels[$this->_urlType];
63
+ }
64
+
65
+ Mage::throwException(
66
+ Mage::helper('emvcore')->__('Please give a valid url for %s !', $serviceLabel)
67
+ );
68
+ }
69
+
70
+ // prepare option
71
+ $options = array('wsdl' => $wsdl);
72
+ if ($account != null && $account->getUseProxy()) {
73
+ if ($account->getData('proxy_host')) {
74
+ $options['proxy_host'] = $account->getData('proxy_host');
75
+ }
76
+ if ($account->getData('proxy_port')) {
77
+ $options['proxy_port'] = $account->getData('proxy_port');
78
+ }
79
+ }
80
+
81
+ // create api object
82
+ $api = $this->createNewService($account, $options);
83
+ $this->_apiService[$key] = $api;
84
+ }
85
+
86
+ return $this->_apiService[$key];
87
+ }
88
+
89
+ /**
90
+ * Create a new service from account and option
91
+ *
92
+ * @param Emv_Core_Model_Account $account
93
+ * @param array $account
94
+ * @return EmailVision_Api_Common
95
+ */
96
+ public abstract function createNewService(Emv_Core_Model_Account $account, $options = array());
97
+
98
+ /**
99
+ * Set SmartFocus account
100
+ * @param Emv_Core_Model_Account $account
101
+ * @return Emv_Core_Model_Service_Transactional
102
+ */
103
+ public function setAccount(Emv_Core_Model_Account $account)
104
+ {
105
+ $this->_account = $account;
106
+ return $this;
107
+ }
108
+
109
+ /**
110
+ * Get SmartFocus
111
+ *
112
+ * @return Emv_Core_Model_Account
113
+ */
114
+ public function getAccount()
115
+ {
116
+ return $this->_account;
117
+ }
118
+
119
+ /**
120
+ * Check if API credential is valid. Return the token if success
121
+ *
122
+ * @throws Exception - in case of errors
123
+ * @return string
124
+ */
125
+ public function checkConnection()
126
+ {
127
+ $service = $this->getApiService($this->getAccount());
128
+ return $service->openApiConnection();
129
+ }
130
+
131
+ /**
132
+ * Throw exception
133
+ *
134
+ * @throws Mage_Core_Exception
135
+ * @param Exception $e
136
+ */
137
+ public function throwException(Exception $e)
138
+ {
139
+ if ($e instanceof EmailVision_Api_Exception) {
140
+ // network problem or server errors
141
+ if ($e->isRecoverable()) {
142
+ Mage::throwException(
143
+ Mage::helper('emvcore')
144
+ ->__('Network problems occured ! Please verify the service url or your network settings!')
145
+ );
146
+ }
147
+
148
+ switch ($e->getCode()) {
149
+ case EmailVision_Api_Exception::EXPIRED_SECURITY_TOKEN :
150
+ Mage::throwException(
151
+ Mage::helper('emvcore')->__('Your token has expired! Please retry your request again !')
152
+ );
153
+ break;
154
+ case EmailVision_Api_Exception::INVALID_CREDENTIAL :
155
+ Mage::throwException(
156
+ Mage::helper('emvcore')->__('Your API credential is not valid ! Please correct it !')
157
+ );
158
+ break;
159
+ case EmailVision_Api_Exception::INVALID_TEMPLATE_ID :
160
+ Mage::throwException(
161
+ Mage::helper('emvcore')
162
+ ->__('Your SmartFocus template is not found! Please select a new one!')
163
+ );
164
+ break;
165
+ case EmailVision_Api_Exception::APPLICATION_ERROR :
166
+ default :
167
+ Mage::throwException(Mage::helper('emvcore')->__('Unknown error with SmartFocus webservice'));
168
+ break;
169
+ }
170
+ } else {
171
+ Mage::throwException($e->getMessage());
172
+ }
173
+ }
174
+ }
app/code/community/Emv/Core/Model/Service/BatchMember.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Batch Member service - Update member data by files
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Core_Model_Service_BatchMember extends Emv_Core_Model_Service_Abstract
11
+ {
12
+ /**
13
+ * Url type
14
+ * @var string
15
+ */
16
+ protected $_urlType = Emv_Core_Model_Account::URL_BATCH_MEMBER_SERVICE_TYPE;
17
+
18
+ /**
19
+ * (non-PHPdoc)
20
+ * @see Emv_Core_Model_Service_Abstract::createNewService()
21
+ * @return EmailVision_Api_BatchMemberService
22
+ */
23
+ public function createNewService(Emv_Core_Model_Account $account, $options = array()){
24
+ // create api object
25
+ $api = new EmailVision_Api_BatchMemberService($options);
26
+ $api->setApiCredentials(array(
27
+ 'login' => $account->getAccountLogin(),
28
+ 'pwd' => $account->getAccountPassword(),
29
+ 'key' => $account->getManagerKey()
30
+ ));
31
+
32
+ return $api;
33
+ }
34
+ }
app/code/community/Emv/Core/Model/Service/Member.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Member service - Handle Member Data
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Core_Model_Service_Member extends Emv_Core_Model_Service_Abstract
11
+ {
12
+ const FIELD_EMAIL = 'EMAIL';
13
+ const FIELD_SUBSCRIBER_ID = 'CLIENTURN';
14
+
15
+ const FIELD_UNJOIN = 'DATEUNJOIN';
16
+ const FIELD_MEMBER_ID = 'MEMBER_ID';
17
+ const FIELD_CLIENT_ID = 'CLIENT_ID';
18
+
19
+ /**
20
+ * Url type
21
+ * @var string
22
+ */
23
+ protected $_urlType = Emv_Core_Model_Account::URL_MEMBER_SERVICE_TYPE;
24
+
25
+ /**
26
+ * (non-PHPdoc)
27
+ * @see Emv_Core_Model_Service_Abstract::createNewService()
28
+ * @return EmailVision_Api_MemberService
29
+ */
30
+ public function createNewService(Emv_Core_Model_Account $account, $options = array()){
31
+ // create api object
32
+ $api = new EmailVision_Api_MemberService($options);
33
+ $api->setApiCredentials(array(
34
+ 'login' => $account->getAccountLogin(),
35
+ 'pwd' => $account->getAccountPassword(),
36
+ 'key' => $account->getManagerKey()
37
+ ));
38
+
39
+ return $api;
40
+ }
41
+
42
+ /**
43
+ * Get EmailVision member fields
44
+ *
45
+ * @return array
46
+ */
47
+ public function getEmailVisionFields()
48
+ {
49
+ $fields = array();
50
+ $service = $this->getApiService();
51
+ try {
52
+ $fields = $service->descMemberTable();
53
+ } catch (Exception $e) {
54
+ // log errors
55
+ Mage::logException($e);
56
+ $this->throwException($e);
57
+ }
58
+
59
+ return $fields;
60
+ }
61
+ }
app/code/community/Emv/Core/Model/Service/Notification.php ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Notification service - handle all email sending to SmartFocus platform
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Core_Model_Service_Notification extends Mage_Core_Model_Abstract
11
+ {
12
+ /**
13
+ * XML path for default wsdl
14
+ */
15
+ const XML_PATH_EMV_WSDL_LIST_TRANSACTIONNAL = 'global/emv/wsdl_list';
16
+
17
+ /**
18
+ * Api service list separted by store
19
+ *
20
+ * @var array
21
+ */
22
+ protected $_apiService = array();
23
+
24
+ /**
25
+ * Get api service
26
+ *
27
+ * @param string $storeId
28
+ * @return EmailVision_Api_NotificationService
29
+ */
30
+ public function getApiService($storeId = null, Emv_Core_Model_Account $account = null)
31
+ {
32
+ $key = 'store_id' . $storeId;
33
+ if ($account != null && $account->getId()) {
34
+ $key .= '-account_id' . $account->getId();
35
+ }
36
+
37
+ if (!isset($this->_apiService[$key])) {
38
+ $restUrl = null;
39
+ if ($account) {
40
+ $restUrl = $account->getUrlForType(Emv_Core_Model_Account::URL_REST_NOTIFICATION_SERVICE_TYPE);
41
+ }
42
+
43
+ if (!$restUrl) {
44
+ Mage::throwException(Mage::helper('emvcore')
45
+ ->__('The given account does not have a valid url for Notification service'));
46
+ }
47
+
48
+ $api = new EmailVision_Api_NotificationService(array());
49
+ $api->setRestServiceUrl($restUrl);
50
+ $this->_apiService[$key] = $api;
51
+ }
52
+
53
+ return $this->_apiService[$key];
54
+ }
55
+
56
+ /**
57
+ * Send Email with given template.
58
+ *
59
+ * @param string $encrypt
60
+ * @param string $notificationId
61
+ * @param string $random
62
+ * @param string $email
63
+ * @param array $content
64
+ * @param array $variable
65
+ * @param string $sendDate - need to be in a format YYYY-MM-DDThh:mm:ss - 2013-01-01T00:00:00
66
+ * @return boolean | string
67
+ * @throws EmailVision_Api_Exception
68
+ */
69
+ public function sendTemplate(
70
+ $encrypt, $notificationId, $random,
71
+ $email, $content = array(), $variable = array(),
72
+ Emv_Core_Model_Account $account = null,
73
+ $storeId = null,
74
+ $sendDate = '2013-01-01T00:00:00'
75
+ )
76
+ {
77
+ // get api service
78
+ $apiService = $this->getApiService($storeId, $account);
79
+
80
+ $result = '';
81
+ $proxyPort = null;
82
+ $proxyHost = null;
83
+ if ($account != null && $account->getUseProxy()) {
84
+ $proxyPort = $account->getData('proxy_port');
85
+ $proxyHost = $account->getData('proxy_host');
86
+ }
87
+
88
+ return $apiService->sendRest(
89
+ $encrypt,
90
+ $notificationId,
91
+ $random,
92
+ $email,
93
+ $content,
94
+ $variable,
95
+ $sendDate,
96
+ $proxyHost,
97
+ $proxyPort
98
+ );
99
+ }
100
+ }
app/code/community/Emv/Core/Model/Service/Soap/Api.php DELETED
@@ -1,367 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- * @category Emv_Core
5
- * @package Model_Service
6
- * @subpackage Soap
7
- * @copyright
8
- * @author Xi ingenierie <info@x2i.fr>
9
- *
10
- */
11
- class Emv_Core_Model_Service_Soap_Api
12
- {
13
- /**
14
- * Soap service web for transaction (template management)
15
- *
16
- * @var $_transactionalService Emv_Core_Model_Service_Soap_SoapClient
17
- */
18
- private $_transactionalService = null;
19
- /**
20
- * Soap service web for notification (send objects)
21
- *
22
- * @var $_notificationService Emv_Core_Model_Service_Soap_SoapClient
23
- */
24
- private $_notificationService = null;
25
- /**
26
- * current Session id.
27
- *
28
- * @var string
29
- */
30
- private $_sessionId = null;
31
- /**
32
- * class with account interface
33
- *
34
- * @var Emv_Core_Model_Account
35
- */
36
- private $_account = null;
37
-
38
- const EMV_SEND_TEMPLATE_NAME = 'magento_emv_send_temporary_template';
39
-
40
- /**
41
- * Constructor
42
- * @param Emv_Core_Model_Account $account
43
- */
44
- public function __construct ($account)
45
- {
46
- $this->_account = $account;
47
-
48
- /* @var $config Emv_Core_Model_Service_Soap_Config*/
49
- $config = Mage::getModel('emvcore/service_soap_config');
50
-
51
- $this->_transactionalService = Mage::getModel('emvcore/service_soap_soapClient', $config->getTransactionalServiceWsdl());
52
- $this->_notificationService = Mage::getModel('emvcore/service_soap_soapClient', $config->getNotificationServiceWsdl());
53
- $this->_init($account);
54
- }
55
-
56
- /**
57
- * API Initialisation
58
- * @param Emv_Core_Model_Account $account
59
- */
60
- private function _init($account)
61
- {
62
- $this->_transactionalService->setConnection($account);
63
- $this->_notificationService->setConnection($account);
64
- }
65
-
66
- /**
67
- * Returns this soap client accounts
68
- *
69
- * @return Emv_Core_Model_Account
70
- */
71
- public function getAccount()
72
- {
73
- return $this->_account;
74
- }
75
-
76
- /**
77
- * Login action.
78
- *
79
- * @return string session id
80
- * @throws Emv_Core_Exception
81
- */
82
- public function openApiConnection ()
83
- {
84
- if (null != $this->_sessionId) {
85
- return $this->_sessionId;
86
- }
87
- try {
88
- $params = array('login' => $this->getAccount()->getAccountLogin(),
89
- 'pwd' => $this->getAccount()->getAccountPassword(),
90
- 'key' => $this->getAccount()->getManagerKey());
91
- $wsResult = $this->_transactionalService->openApiConnection($params);
92
- $this->_sessionId = $wsResult->return;
93
- } catch (Exception $e) {
94
- Mage::log($e->getMessage(), null, Mage::helper('emvcore')->LOG_FILE);
95
- if($e->getMessage() === 'Could not connect to host' ||
96
- $e->getMessage() === 'Service Temporarily Unavailable' )
97
- {
98
- throw Mage::exception('Emv_Core',
99
- Mage::helper('emvcore')->__('Cound not connect to Campaign Commander WebService.'), 2);
100
- }
101
- else
102
- {
103
- throw Mage::exception('Emv_Core', $e->getMessage(), 1);
104
- }
105
- }
106
-
107
- return $this->_sessionId;
108
- }
109
-
110
- /**
111
- *
112
- * @param $from string date with format 'YYYY-MM-DD HH:MM:SS'
113
- * @param $to string date with format 'YYYY-MM-DD HH:MM:SS'
114
- */
115
- public function getTemplatesByPeriod($from, $to)
116
- {
117
- try {
118
- $params = array('token' => $this->openApiConnection(),
119
- 'type' => 'TRANSACTIONAL',
120
- 'dateBegin' => $from,
121
- 'dateEnd' => $to,
122
- );
123
-
124
- $wsResult = $this->_transactionalService->getTemplatesByPeriod($params);
125
-
126
- $this->closeApiConnection();
127
-
128
- } catch ( Exception $e) {
129
- Mage::log($e->getMessage(), null, Mage::helper('emvcore')->LOG_FILE, true);
130
- throw Mage::exception('Emv_Core', $e->getMessage());
131
- }
132
-
133
- if(isset($wsResult->return))
134
- {
135
- return $wsResult->return;
136
- }
137
- else
138
- {
139
- return null;
140
- }
141
- }
142
-
143
- public function getTemplateById($id)
144
- {
145
- try {
146
- $params = array('token' => $this->openApiConnection(),
147
- 'id' => $id,
148
- );
149
-
150
- $wsResult = $this->_transactionalService->getTemplate($params);
151
-
152
- } catch ( Exception $e) {
153
- Mage::log($e->getMessage(), null, Mage::helper('emvcore')->LOG_FILE, true);
154
- throw Mage::exception('Emv_Core', $e->getMessage());
155
- }
156
-
157
- if(isset($wsResult->return))
158
- {
159
- return $wsResult->return;
160
- }
161
- else
162
- {
163
- return null;
164
- }
165
- }
166
-
167
- /**
168
- * This function is used to create a template in campaign commander that will be used to send
169
- * "emv send" mails
170
- */
171
- public function createEmvSendTemplate()
172
- {
173
- try {
174
- $params = array('token' => $this->openApiConnection(),
175
- 'name' => Emv_Core_Model_Service_Soap_Api::EMV_SEND_TEMPLATE_NAME,
176
- 'subject' => '[EMV DYN]SUBJECT[EMV /DYN]',
177
- 'description' => 'DO NOT DELETE',
178
- 'from' => '[EMV DYN]FROM[EMV /DYN]',
179
- 'fromEmail' => '[EMV DYN]FROM_EMAIL[EMV /DYN]',
180
- 'to' => '[EMV DYN]TO[EMV /DYN]',
181
- 'body' => '[EMV HTMLPART]
182
- <html>
183
- <body>
184
- [EMV CONTENT]1[EMV /CONTENT]
185
- </body>
186
- </html>
187
- [EMV TEXTPART]
188
- [EMV CONTENT]2[EMV /CONTENT]',
189
- 'encoding' => 'UTF-8',
190
- 'replyTo' => '[EMV DYN]REPLY[EMV /DYN]',
191
- 'replyToEmail' => '[EMV DYN]REPLY_EMAIL[EMV /DYN]',
192
- 'type' => 'TRANSACTIONAL',
193
- );
194
-
195
- //Create the email
196
- $wsResult = $this->_transactionalService->createTemplate($params);
197
- $templateId = $wsResult->return;
198
- } catch ( Exception $e) {
199
- Mage::log($e->getMessage(), null, Mage::helper('emvcore')->LOG_FILE, true);
200
- throw Mage::exception('Emv_Core', $e->getMessage());
201
- }
202
-
203
- return $templateId;
204
- }
205
-
206
- public function getEmvSendTemplate()
207
- {
208
- try {
209
- $params = array('token' => $this->openApiConnection(),
210
- 'type' => 'TRANSACTIONAL',
211
- 'field' => 'name',
212
- 'value' => Emv_Core_Model_Service_Soap_Api::EMV_SEND_TEMPLATE_NAME,
213
- 'limit' => 1,
214
- );
215
-
216
- $wsResult = $this->_transactionalService->getTemplatesByField($params);
217
-
218
- // create the template if it not exists
219
- if(!property_exists($wsResult, 'return'))
220
- {
221
- $this->createEmvSendTemplate();
222
- $wsResult = $this->_transactionalService->getTemplatesByField($params);
223
- }
224
-
225
- $emvTemplate = $this->getTemplateById($wsResult->return);
226
-
227
- } catch ( Exception $e) {
228
- Mage::log($e->getMessage(), null, Mage::helper('emvcore')->LOG_FILE, true);
229
- throw Mage::exception('Emv_Core', $e->getMessage());
230
- }
231
-
232
- return $emvTemplate;
233
- }
234
-
235
- /**
236
- * Return template info (id and name) in array to put in a select
237
- * @param $templateId int
238
- */
239
- public function getTemplateInfoInArray($templateId)
240
- {
241
- //get template name with id
242
- $name = $this->getTemplateById($templateId)->name;
243
-
244
- return array('value' => $templateId, 'label' => $name);
245
- }
246
-
247
- /**
248
- * Send an email with 'emv send' mode
249
- * It just send email via campaign commander instead of magento.
250
- * @param $emailTemplate Emv_Emt_Model_Mage_Core_Email_Template
251
- */
252
- public function sendEmvEmt($emailTemplate, $name, $email)
253
- {
254
- try {
255
-
256
- $emvTemplate = $this->getEmvSendTemplate();
257
-
258
- if(is_array($name))
259
- {
260
- $nameOne = $name[0];
261
- }
262
- else
263
- {
264
- $nameOne = $name;
265
- }
266
-
267
- $varDyn = array (
268
- 'SUBJECT' => $emailTemplate->getTemplateSubject(),
269
- 'FROM' => $emailTemplate->getSenderName(),
270
- 'FROM_EMAIL' => $emailTemplate->getSenderEmail(),
271
- 'TO' => $nameOne,
272
- 'REPLY' => $emailTemplate->getSenderName(),
273
- 'REPLY_EMAIL' => $emailTemplate->getSenderEmail(),
274
- );
275
-
276
- $varDynWS = Mage::helper('emvemt/emvtemplate')->_attributesToWebServiceRequest($varDyn);
277
-
278
- if($emailTemplate->getTemplateType() == Mage_Newsletter_Model_Template::TYPE_HTML)
279
- {
280
- $varContent = array('1' => $emailTemplate->getTemplateText());
281
- }
282
- else
283
- {
284
- $varContent = array('2' => $emailTemplate->getTemplateText());
285
- }
286
-
287
- $varContentWS = Mage::helper('emvemt/emvtemplate')->_attributesToWebServiceRequest($varContent);
288
-
289
- $returnString = $this->sendEmv($emvTemplate, $varDynWS, $email, $varContentWS);
290
-
291
- } catch ( Exception $e) {
292
- Mage::log($e->getMessage(), null, Mage::helper('emvcore')->LOG_FILE, true);
293
- throw Mage::exception('Emv_Core', $e->getMessage());
294
- }
295
-
296
- return $returnString;
297
- }
298
-
299
- /**
300
- * Send an email with 'emv create / Campaign Commander Template' mode
301
- * This function use an Campaign Commander template take attribute mapping.
302
- * @param Emv_Emt_Model_Mage_Core_Email_Template $emailTemplate
303
- * @param unknown_type $emvTemplate
304
- * @param array $variable
305
- * @param string $name
306
- * @param string $mail
307
- * @return unknown
308
- */
309
- public function sendEmv($emvTemplate, $variable, $mail, $content = '')
310
- {
311
-
312
- try {
313
- if(!is_array($mail))
314
- {
315
- $mail = array($mail);
316
- }
317
-
318
- $returnString = '';
319
- foreach($mail as $oneMail)
320
- {
321
- //send mail
322
- $params = array( 'arg0' => array(
323
- 'content' => $content,
324
- 'dyn' => $variable,
325
- 'email' => $oneMail,
326
- 'encrypt' => $emvTemplate->encrypt,
327
- 'notificationId' => $emvTemplate->id,
328
- 'random' => $emvTemplate->random,
329
- 'senddate' => '1980-01-01T00:00:00',
330
- 'synchrotype' => 'NOTHING',
331
- 'uidkey' => 'EMAIL',
332
- ));
333
-
334
- $wsResult = $this->_notificationService->sendObject($params);
335
-
336
- $returnString .= $oneMail . ' : ' . $wsResult->return . ' / ';
337
- }
338
-
339
- $this->closeApiConnection();
340
-
341
- } catch ( Exception $e) {
342
- Mage::log($e->getMessage(), null, Mage::helper('emvcore')->LOG_FILE, true);
343
- throw Mage::exception('Emv_Core', $e->getMessage());
344
- }
345
-
346
- return $returnString;
347
- }
348
-
349
-
350
- /**
351
- * Close the Api connection
352
- *
353
- * @param string $sessionId
354
- * @throws Emv_Core_Exception
355
- */
356
- public function closeApiConnection()
357
- {
358
- try {
359
- $wsResult = $this->_transactionalService->closeApiConnection(array( 'token' => $this->_sessionId));
360
- $this->_sessionId = null;
361
- } catch (Exception $e) {
362
- Mage::log($e->getMessage(), null, Mage::helper('emvcore')->LOG_FILE, true);
363
- throw Mage::exception('Emv_Core', $e->getMessage());
364
- }
365
- return $wsResult->return === 'connection closed';
366
- }
367
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Core/Model/Service/Soap/Config.php DELETED
@@ -1,59 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- * @category Emv_Core
5
- * @package Model_Service
6
- * @subpackage Soap
7
- * @copyright
8
- * @author Xi ingenierie <info@x2i.fr>
9
- *
10
- */
11
- class Emv_Core_Model_Service_Soap_Config
12
- {
13
- /**
14
- * list of wsdl adress used in the API
15
- * @var xml
16
- */
17
- const XML_PATH_EMV_WSDL_LIST_TRANSACTIONNAL = 'global/emv/wsdl_list';
18
-
19
- private $_wsdl = null;
20
-
21
- /**
22
- * Initialize resource model
23
- *
24
- */
25
- public function __construct()
26
- {
27
- $this->_wsdl = Mage::getConfig()->getNode(self::XML_PATH_EMV_WSDL_LIST_TRANSACTIONNAL);
28
- }
29
-
30
- /**
31
- * @return String
32
- */
33
- public function getTransactionalServiceWsdl()
34
- {
35
- $wsdl = Mage::getStoreConfig('emvcore/emv_services/transactional');
36
-
37
- if($wsdl == null || $wsdl == '')
38
- {
39
- $node = $this->_wsdl->transactional_service;
40
- $wsdl = $node ? $node->asArray():null;
41
- }
42
- return $wsdl;
43
- }
44
-
45
- /**
46
- * @return String
47
- */
48
- public function getNotificationServiceWsdl()
49
- {
50
- $wsdl = Mage::getStoreConfig('emvcore/emv_services/notification');
51
-
52
- if($wsdl == null || $wsdl == '')
53
- {
54
- $node = $this->_wsdl->notification_service;
55
- $wsdl = $node ? $node->asArray():null;
56
- }
57
- return $wsdl;
58
- }
59
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Core/Model/Service/Soap/SoapClient.php DELETED
@@ -1,47 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- * @category Emv_Core
5
- * @package Model_Service
6
- * @subpackage Soap
7
- * @copyright
8
- * @author Xi ingenierie <info@x2i.fr>
9
- *
10
- */
11
- class Emv_Core_Model_Service_Soap_SoapClient extends Zend_Soap_Client
12
- {
13
- /**
14
- * Magento Encoding for wsdl service
15
- *
16
- * @var string
17
- */
18
- const WSDL_ENCODING = 'UTF-8';
19
-
20
- /**
21
- * Constructor
22
- *
23
- * @param string $wsdl
24
- */
25
- public function __construct($wsdl)
26
- {
27
- parent::__construct($wsdl);
28
- use_soap_error_handler(true);
29
- }
30
-
31
- /**
32
- * set the soap connection options
33
- * @param Emv_Core_Model_Account $account
34
- */
35
- public function setConnection($account)
36
- {
37
- if (null !== $account){
38
- $this->setEncoding(self::WSDL_ENCODING);
39
- $this->setSoapVersion(SOAP_1_1);
40
- if ($account->getUseProxy() == true){
41
- $this->setProxyHost($account->getProxyHost());
42
- $this->setProxyPort($account->getProxyPort());
43
- }
44
- }
45
- }
46
- }
47
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Core/Model/Service/Transactional.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Transactional service - Handle EmailVision transactional email template content
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Core_Model_Service_Transactional extends Emv_Core_Model_Service_Abstract
11
+ {
12
+ /**
13
+ * Url type
14
+ * @var string
15
+ */
16
+ protected $_urlType = Emv_Core_Model_Account::URL_TRANSACTIONAL_SERVICE_TYPE;
17
+
18
+ const PAGE_SIZE = 50;
19
+
20
+ /**
21
+ * (non-PHPdoc)
22
+ * @see Emv_Core_Model_Service_Abstract::createNewService()
23
+ * @return EmailVision_Api_TransactionalService
24
+ */
25
+ public function createNewService(Emv_Core_Model_Account $account, $options = array()){
26
+ // create api object
27
+ $api = new EmailVision_Api_TransactionalService($options);
28
+ $api->setApiCredentials(array(
29
+ 'login' => $account->getAccountLogin(),
30
+ 'pwd' => $account->getAccountPassword(),
31
+ 'key' => $account->getManagerKey()
32
+ ));
33
+
34
+ return $api;
35
+ }
36
+ /**
37
+ * Get SmartFocus template by Id
38
+ *
39
+ * @param string $templateId
40
+ * @return stdClass
41
+ */
42
+ public function getTemplateById($templateId)
43
+ {
44
+ $emvTemplate = null;
45
+ $serivce = $this->getApiService();
46
+ try {
47
+ $emvTemplate = $serivce->getTemplateById($templateId);
48
+ } catch (Exception $e) {
49
+ // log errors
50
+ Mage::logException($e);
51
+ $this->throwException($e);
52
+ }
53
+
54
+ return $emvTemplate;
55
+ }
56
+
57
+ /**
58
+ * @param string $from date with format 'YYYY-MM-DDTHH:MM:SS'
59
+ * @param string $to date with format 'YYYY-MM-DDTHH:MM:SS'
60
+ * @return array
61
+ */
62
+ public function getTemplatesByPeriod($from, $to)
63
+ {
64
+ $list = array();
65
+ $service = $this->getApiService();
66
+ try {
67
+ $cpt = 1;
68
+ $next = true;
69
+ while($next) {
70
+ $return = $service->getTemplateSummmaryList(
71
+ $cpt,
72
+ self::PAGE_SIZE,
73
+ array('from' => $from, 'to' => $to),
74
+ true
75
+ );
76
+
77
+ if ($return && is_array($return) && $return['list_retreived'] >0) {
78
+ $list = array_merge($list, $return['list_retreived']);
79
+ if ($return['next_page'] == 0) {
80
+ $next = false;
81
+ } else {
82
+ $cpt++;
83
+ }
84
+ } else {
85
+ $next = false;
86
+ }
87
+ }
88
+ } catch (Exception $e) {
89
+ // log errors
90
+ Mage::logException($e);
91
+ $this->throwException($e);
92
+ }
93
+
94
+ return $list;
95
+ }
96
+
97
+ /**
98
+ * Check if a default send template exist,
99
+ * - if so return it
100
+ * - else create a new one and then return the created one
101
+ *
102
+ * @return NULL | stdClass
103
+ */
104
+ public function checkOrCreateEmvDefaultSendTemplate($closeApi = true)
105
+ {
106
+ $defaultTemplate = null;
107
+ try {
108
+ $service = $this->getApiService();
109
+
110
+ $defaultTemplate = $service->getDefaultTemplateSend(
111
+ EmailVision_Api_TransactionalService::DEFAULT_TEMPLATE_SEND, false
112
+ );
113
+
114
+ if (!$defaultTemplate) {
115
+ $defaultId = $service->createDefaultEmvSendTemplate(
116
+ EmailVision_Api_TransactionalService::DEFAULT_TEMPLATE_SEND,
117
+ false
118
+ );
119
+ if ($defaultId) {
120
+ $defaultTemplate = $serivce->getTemplateById($templateId, false);
121
+ }
122
+ }
123
+
124
+ if ($closeApi) {
125
+ $service->closeApiConnection();
126
+ }
127
+
128
+ } catch(Exception $e) {
129
+ // log errors
130
+ Mage::logException($e);
131
+ $this->throwException($e);
132
+ }
133
+
134
+ if (!$defaultTemplate) {
135
+ Mage::throwException(Mage::helper('emvcore')->__('Can not create SmartFocus default sending template'));
136
+ }
137
+ return $defaultTemplate;
138
+ }
139
+
140
+ /**
141
+ * @param string $templateId
142
+ * @param array $attributes('EMV_DYN' or 'EMV_CONTENT')
143
+ * @return false | string
144
+ */
145
+ public function getPreviewTemplate($templateId, $attributes = array())
146
+ {
147
+ $preview = false;
148
+ try {
149
+ $service = $this->getApiService();
150
+ $preview = $service->getTemplatePreviewWithDynContent($templateId, $attributes);
151
+ } catch(Exception $e) {
152
+ // log errors
153
+ Mage::logException($e);
154
+ $this->throwException($e);
155
+ }
156
+ return $preview;
157
+ }
158
+ }
app/code/community/Emv/Core/Model/System/Config/Source/Account.php CHANGED
@@ -1,4 +1,12 @@
1
  <?php
 
 
 
 
 
 
 
 
2
  class Emv_Core_Model_System_Config_Source_Account
3
  {
4
  public function toOptionArray()
1
  <?php
2
+ /**
3
+ * Account system config source
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
  class Emv_Core_Model_System_Config_Source_Account
11
  {
12
  public function toOptionArray()
app/code/community/Emv/Core/controllers/Adminhtml/AccountController.php CHANGED
@@ -1,22 +1,41 @@
1
  <?php
2
  /**
3
  * This controller is used to manage all account view (grid list, edit/new form)
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{89E9F5B5-59B4-4cbe-9FCE-8C9EF47AC254}
 
8
  */
9
  class Emv_Core_Adminhtml_AccountController extends Mage_Adminhtml_Controller_Action
10
  {
11
 
 
 
 
 
 
12
  protected function _initAction()
13
  {
14
  $this->loadLayout();
15
- $this->_setActiveMenu('system/emvcore');
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  }
17
 
18
  /**
19
- * Initialise the account model.
20
  *
21
  * @return Emv_Core_Model_Account
22
  */
@@ -30,34 +49,44 @@ class Emv_Core_Adminhtml_AccountController extends Mage_Adminhtml_Controller_Act
30
  }
31
 
32
  /**
33
- * opGUID{B807832C-83B7-41c2-9134-AA6F62E38F9E}
34
  */
35
  public function indexAction()
36
  {
 
 
 
 
 
37
  $this->_initAction();
38
  $this->_addContent($this->getLayout()->createBlock('emvcore/adminhtml_accounts'));
39
  $this->renderLayout();
40
  }
41
 
42
  /**
43
- * opGUID{D8589471-4051-4ea6-ACA1-EAA717478B58}
44
  */
45
  public function editAction()
46
  {
47
  $accountModel = $this->_initAccount();
 
 
48
  $data = $this->_getSession()->getEmvAccountFormData(true);
49
- if(isset($data))
50
- {
51
  // set entered data if was error when we do save
52
  $accountModel->addData($data);
53
  }
 
54
  $this->_initAction();
 
 
 
55
  $this->_addContent($this->getLayout()->createBlock('emvcore/adminhtml_account_edit'));
56
  $this->renderLayout();
57
  }
58
 
59
  /**
60
- * opGUID{642E5425-D84D-4c6c-9BDF-AD8EB34958B9}
61
  */
62
  public function newAction()
63
  {
@@ -65,79 +94,91 @@ class Emv_Core_Adminhtml_AccountController extends Mage_Adminhtml_Controller_Act
65
  }
66
 
67
  /**
68
- * opGUID{69925605-3736-487f-A753-DBCDE9E3471F}
69
  */
70
  public function deleteAction()
71
  {
72
- if ($id = $this->getRequest()->getParam('id'))
73
- {
74
  try {
75
  $model = Mage::getModel('emvcore/account')->load($id);
76
- $model->delete();
77
- $this->_getSession()->addSuccess(
78
- Mage::helper('emvcore')->__('Campaign Commander account deleted.'));
79
- $this->_redirect('*/*/');
80
- return;
81
- }
82
- catch (Exception $e) {
 
 
83
  $this->_getSession()->addError($e->getMessage());
84
  $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getPost('id')));
85
  return;
86
  }
87
  }
88
- Mage::getSingleton('adminhtml/session')->addError(Mage::helper('emvcore')->__('Unable to find an account to delete.'));
 
 
 
89
  $this->_redirect('*/*/');
90
  }
91
 
 
 
 
92
  public function saveAction()
93
  {
94
- if ($data = $this->getRequest()->getPost())
95
- {
96
  $accountId = $this->getRequest()->getParam('id', null);
97
 
98
- // set empty data to null for the database
99
- foreach ($data as $key => $value)
100
- {
101
- if('' === $data[$key])
102
- {
103
  $data[$key] = null;
 
 
 
 
 
 
 
 
104
  }
105
  }
106
 
107
  $accountModel = Mage::getModel('emvcore/account')->load($accountId);
108
  $accountModel->setData($data);
109
 
110
- $result = $accountModel->validate();
111
- if (is_array($result))
112
- {
 
113
  $this->_getSession()->setEmvAccountFormData($data);
114
  foreach ($result as $message)
115
  {
116
  $this->_getSession()->addError($message);
117
  }
118
- $this->_redirect('*/*/edit', array('id'=>$accountModel->getId()));
119
- return $this;
120
- }
121
 
122
- try {
123
  $accountModel->save();
124
  $this->_getSession()->addSuccess(
125
- Mage::helper('emvcore')->__('The Campaign Commander account has been saved.'));
126
 
127
  // check if 'Save and Continue'
128
  if ($this->getRequest()->getParam('back')) {
129
- $this->_redirect('*/*/edit', array('id'=>$accountModel->getId()));
130
  return;
131
  }
132
- $this->_redirect('*/*/');
133
- return;
134
  } catch (Exception $e) {
135
  $this->_getSession()->addError($e->getMessage());
136
  $this->_getSession()->setEmvAccountFormData($data);
 
137
  $this->_redirect('*/*/edit', array('id'=>$accountModel->getId()));
138
  return;
139
  }
140
  }
141
  $this->_redirect('*/*/');
 
142
  }
143
  }
1
  <?php
2
  /**
3
  * This controller is used to manage all account view (grid list, edit/new form)
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
  */
10
  class Emv_Core_Adminhtml_AccountController extends Mage_Adminhtml_Controller_Action
11
  {
12
 
13
+ /**
14
+ * Initialise action
15
+ * - load all layout
16
+ * - set active menu SmartFocus
17
+ */
18
  protected function _initAction()
19
  {
20
  $this->loadLayout();
21
+ $this->_setActiveMenu('emailvision/emvcore');
22
+ $this->_title(Mage::helper('emvcore')->__('SmartFocus'))
23
+ ->_title(Mage::helper('emvcore')->__('Accounts'));
24
+ }
25
+
26
+ /**
27
+ * Check menu access
28
+ *
29
+ * (non-PHPdoc)
30
+ * @see Mage_Adminhtml_Controller_Action::_isAllowed()
31
+ */
32
+ protected function _isAllowed()
33
+ {
34
+ return Mage::getSingleton('admin/session')->isAllowed('emailvision/emvcore');
35
  }
36
 
37
  /**
38
+ * Initialise the account model with the given account id in the parameter
39
  *
40
  * @return Emv_Core_Model_Account
41
  */
49
  }
50
 
51
  /**
52
+ * Action to display account grid
53
  */
54
  public function indexAction()
55
  {
56
+ // save all messages from session
57
+ $this->getLayout()->getMessagesBlock()->setMessages(
58
+ $this->_getSession()->getMessages()
59
+ );
60
+
61
  $this->_initAction();
62
  $this->_addContent($this->getLayout()->createBlock('emvcore/adminhtml_accounts'));
63
  $this->renderLayout();
64
  }
65
 
66
  /**
67
+ * Account Edit Action
68
  */
69
  public function editAction()
70
  {
71
  $accountModel = $this->_initAccount();
72
+
73
+ // get emv account form data from session
74
  $data = $this->_getSession()->getEmvAccountFormData(true);
75
+ if (isset($data)) {
 
76
  // set entered data if was error when we do save
77
  $accountModel->addData($data);
78
  }
79
+
80
  $this->_initAction();
81
+ $this->_title(
82
+ $accountModel->getId() ? $accountModel->getName() : Mage::helper('emvcore')->__('New Account')
83
+ );
84
  $this->_addContent($this->getLayout()->createBlock('emvcore/adminhtml_account_edit'));
85
  $this->renderLayout();
86
  }
87
 
88
  /**
89
+ * Account New Action
90
  */
91
  public function newAction()
92
  {
94
  }
95
 
96
  /**
97
+ * Account Delete Action
98
  */
99
  public function deleteAction()
100
  {
101
+ if ($id = $this->getRequest()->getParam('id')) {
 
102
  try {
103
  $model = Mage::getModel('emvcore/account')->load($id);
104
+ if ($model->getId()) {
105
+ $model->delete();
106
+ $this->_getSession()->addSuccess(
107
+ Mage::helper('emvcore')->__('SmartFocus account deleted.'));
108
+ $this->_redirect('*/*/');
109
+
110
+ return;
111
+ }
112
+ } catch (Exception $e) {
113
  $this->_getSession()->addError($e->getMessage());
114
  $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getPost('id')));
115
  return;
116
  }
117
  }
118
+
119
+ Mage::getSingleton('adminhtml/session')->addError(
120
+ Mage::helper('emvcore')->__('Unable to find an account to delete.')
121
+ );
122
  $this->_redirect('*/*/');
123
  }
124
 
125
+ /**
126
+ * Save action
127
+ */
128
  public function saveAction()
129
  {
130
+ if ($data = $this->getRequest()->getPost()) {
 
131
  $accountId = $this->getRequest()->getParam('id', null);
132
 
133
+ // set empty data to null for the database and trim all input
134
+ foreach ($data as $key => $value) {
135
+ if ('' === $data[$key]) {
 
 
136
  $data[$key] = null;
137
+ } elseif (is_string($data[$key])) {
138
+ $data[$key] = trim($data[$key]);
139
+ }
140
+ }
141
+
142
+ if (isset($data['emv_urls'])) {
143
+ foreach($data['emv_urls'] as $nameService => $serviceData) {
144
+ $data['emv_urls'][$nameService]['url'] = trim($serviceData['url']);
145
  }
146
  }
147
 
148
  $accountModel = Mage::getModel('emvcore/account')->load($accountId);
149
  $accountModel->setData($data);
150
 
151
+ try {
152
+ $result = $accountModel->validate();
153
+
154
+ if (is_array($result)) {
155
  $this->_getSession()->setEmvAccountFormData($data);
156
  foreach ($result as $message)
157
  {
158
  $this->_getSession()->addError($message);
159
  }
160
+ $this->_redirect('*/*/edit', array('id' => $accountModel->getId()));
161
+ return;
162
+ }
163
 
 
164
  $accountModel->save();
165
  $this->_getSession()->addSuccess(
166
+ Mage::helper('emvcore')->__('The SmartFocus account has been saved.'));
167
 
168
  // check if 'Save and Continue'
169
  if ($this->getRequest()->getParam('back')) {
170
+ $this->_redirect('*/*/edit', array('id' => $accountModel->getId()));
171
  return;
172
  }
 
 
173
  } catch (Exception $e) {
174
  $this->_getSession()->addError($e->getMessage());
175
  $this->_getSession()->setEmvAccountFormData($data);
176
+
177
  $this->_redirect('*/*/edit', array('id'=>$accountModel->getId()));
178
  return;
179
  }
180
  }
181
  $this->_redirect('*/*/');
182
+ return;
183
  }
184
  }
app/code/community/Emv/Core/etc/adminhtml.xml CHANGED
@@ -1,35 +1,35 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <config>
3
  <menu>
4
- <system>
 
 
 
5
  <children>
6
- <emvcore translate="title" module="emvcore">
7
- <title>Campaign Commander Account</title>
8
- <sort_order>1000</sort_order>
9
- <action>emailvision/account</action>
10
  </emvcore>
11
  </children>
12
- </system>
13
  </menu>
 
14
  <acl>
15
  <resources>
16
  <admin>
17
  <children>
18
- <system>
 
 
 
19
  <children>
20
  <emvcore translate="title" module="emvcore">
21
- <title>Campaign Commander Account</title>
22
  <sort_order>1000</sort_order>
23
  </emvcore>
24
- <config>
25
- <children>
26
- <emvcore translate="title" module="emvcore">
27
- <title>Campaign Commander Section</title>
28
- </emvcore>
29
- </children>
30
- </config>
31
  </children>
32
- </system>
33
  </children>
34
  </admin>
35
  </resources>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <config>
3
  <menu>
4
+ <!-- EmailVision menu in the back office -->
5
+ <emailvision translate="title" module="adminhtml">
6
+ <title>SmartFocus</title>
7
+ <sort_order>999</sort_order>
8
  <children>
9
+ <emvcore translate="title">
10
+ <title>Accounts</title>
11
+ <sort_order>10</sort_order>
12
+ <action>emv_core/account</action>
13
  </emvcore>
14
  </children>
15
+ </emailvision>
16
  </menu>
17
+
18
  <acl>
19
  <resources>
20
  <admin>
21
  <children>
22
+ <!-- EmailVision acl -->
23
+ <emailvision translate="title" module="emvcore">
24
+ <title>SmartFocus</title>
25
+ <sort_order>90</sort_order>
26
  <children>
27
  <emvcore translate="title" module="emvcore">
28
+ <title>Accounts</title>
29
  <sort_order>1000</sort_order>
30
  </emvcore>
 
 
 
 
 
 
 
31
  </children>
32
+ </emailvision>
33
  </children>
34
  </admin>
35
  </resources>
app/code/community/Emv/Core/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <Emv_Core>
5
- <version>0.1.0</version>
6
  </Emv_Core>
7
  </modules>
8
  <global>
@@ -40,8 +40,7 @@
40
  </resources>
41
  <emv>
42
  <wsdl_list>
43
- <transactional_service>https://p5apic.emv2.com/apitransactional/services/TransactionalService?wsdl</transactional_service>
44
- <notification_service>http://api.notificationmessaging.com/NMSOAP/NotificationService?wsdl</notification_service>
45
  </wsdl_list>
46
  </emv>
47
  </global>
@@ -62,7 +61,7 @@
62
  <use>admin</use>
63
  <args>
64
  <module>Emv_Core_Adminhtml</module>
65
- <frontName>emailvision</frontName>
66
  </args>
67
  </emvcore>
68
  </routers>
2
  <config>
3
  <modules>
4
  <Emv_Core>
5
+ <version>0.2.0</version>
6
  </Emv_Core>
7
  </modules>
8
  <global>
40
  </resources>
41
  <emv>
42
  <wsdl_list>
43
+ <rest_notification_service>http://api.notificationmessaging.com/NMSXML</rest_notification_service>
 
44
  </wsdl_list>
45
  </emv>
46
  </global>
61
  <use>admin</use>
62
  <args>
63
  <module>Emv_Core_Adminhtml</module>
64
+ <frontName>emv_core</frontName>
65
  </args>
66
  </emvcore>
67
  </routers>
app/code/community/Emv/Core/etc/system.xml CHANGED
@@ -2,69 +2,9 @@
2
  <config>
3
  <tabs>
4
  <emailvision translate="label" module="emvcore">
5
- <label>Emailvision</label>
6
  <sort_order>150</sort_order>
7
  </emailvision>
8
  </tabs>
9
- <sections>
10
- <emvcore translate="label" module="emvcore">
11
- <label>Campaign Commander</label>
12
- <tab>emailvision</tab>
13
- <frontend_type>text</frontend_type>
14
- <sort_order>100</sort_order>
15
- <show_in_default>1</show_in_default>
16
- <show_in_website>1</show_in_website>
17
- <show_in_store>1</show_in_store>
18
- <groups>
19
- <emv_account translate="label">
20
- <label>Campaign Commander Account</label>
21
- <expanded>1</expanded>
22
- <frontend_type>text</frontend_type>
23
- <sort_order>10</sort_order>
24
- <show_in_default>1</show_in_default>
25
- <show_in_website>1</show_in_website>
26
- <show_in_store>1</show_in_store>
27
- <fields>
28
- <account translate="label" module="emvcore">
29
- <label>Campaign Commander Account</label>
30
- <frontend_type>select</frontend_type>
31
- <source_model>emvcore/system_config_source_account</source_model>
32
- <sort_order>1</sort_order>
33
- <show_in_default>1</show_in_default>
34
- <show_in_website>1</show_in_website>
35
- <show_in_store>1</show_in_store>
36
- </account>
37
- </fields>
38
- </emv_account>
39
- <emv_services translate="label">
40
- <label>Campaign Commander Services</label>
41
- <expanded>1</expanded>
42
- <frontend_type>text</frontend_type>
43
- <sort_order>0</sort_order>
44
- <show_in_default>1</show_in_default>
45
- <show_in_website>1</show_in_website>
46
- <show_in_store>1</show_in_store>
47
- <fields>
48
- <transactional translate="label" module="emvcore">
49
- <label>Transactional Service Adress</label>
50
- <frontend_type>text</frontend_type>
51
- <sort_order>1</sort_order>
52
- <show_in_default>1</show_in_default>
53
- <show_in_website>1</show_in_website>
54
- <show_in_store>1</show_in_store>
55
- </transactional>
56
- <notification translate="label" module="emvcore">
57
- <label>Notification Service Adress</label>
58
- <frontend_type>text</frontend_type>
59
- <sort_order>1</sort_order>
60
- <show_in_default>1</show_in_default>
61
- <show_in_website>1</show_in_website>
62
- <show_in_store>1</show_in_store>
63
- </notification>
64
- </fields>
65
- </emv_services>
66
- </groups>
67
- </emvcore>
68
- </sections>
69
  </config>
70
 
2
  <config>
3
  <tabs>
4
  <emailvision translate="label" module="emvcore">
5
+ <label>SmartFocus</label>
6
  <sort_order>150</sort_order>
7
  </emailvision>
8
  </tabs>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  </config>
10
 
app/code/community/Emv/Core/sql/emvcore_setup/mysql4-install-0.1.0.php CHANGED
@@ -19,7 +19,7 @@ CREATE TABLE {$installer->getTable('emvcore/account')}(
19
  UNIQUE UQ_Account_manager_key(`manager_key`),
20
  UNIQUE UQ_Account_name(`name`)
21
  )
22
- ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Campaign Commander account';
23
  ");
24
 
25
  $installer->endSetup();
19
  UNIQUE UQ_Account_manager_key(`manager_key`),
20
  UNIQUE UQ_Account_name(`name`)
21
  )
22
+ ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='SmartFocus account';
23
  ");
24
 
25
  $installer->endSetup();
app/code/community/Emv/Core/sql/emvcore_setup/mysql4-upgrade-0.1.0-0.2.0.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Emv_Emt_Model_Resource_Setup */
3
+ $this->startSetup();
4
+
5
+ $this->run("
6
+ ALTER TABLE {$this->getTable('emvcore/account')}
7
+ ADD COLUMN `created_at` TIMESTAMP NULL,
8
+ ADD COLUMN `updated_at` TIMESTAMP NULL,
9
+ ADD COLUMN `emv_urls` TEXT NOT NULL
10
+ ");
11
+
12
+ $gmtDate = Mage::getModel('core/date')->gmtDate();
13
+ $this->run("
14
+ UPDATE {$this->getTable('emvcore/account')} SET created_at = '{$gmtDate}', updated_at = '{$gmtDate}';
15
+ ");
16
+
17
+ $this->endSetup();
app/code/community/Emv/DataSync/Block/Adminhtml/Form/Field/CustomerAttributes.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Block to manage the customer attributes form in back office configuration
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Block_Adminhtml_Form_Field_CustomerAttributes extends Mage_Core_Block_Html_Select
10
+ {
11
+ /**
12
+ * @var array
13
+ */
14
+ protected $_customerAttributes;
15
+
16
+ /**
17
+ * Get customer attributes array
18
+ * @param string $attributeId
19
+ * @return NULL|Ambigous <multitype:, string>
20
+ */
21
+ protected function _getCustomerAttributes($attributeId = null)
22
+ {
23
+ if (is_null($this->_customerAttributes)) {
24
+ $this->_customerAttributes = array();
25
+ $customerEntityTypeId = Mage::getModel('eav/entity')->setType('customer')->getTypeId();
26
+ $customerAddressEntityTypeId = Mage::getModel('eav/entity')->setType('customer_address')->getTypeId();
27
+ $collection = Mage::getResourceModel('eav/entity_attribute_collection')
28
+ ->addFieldToFilter(
29
+ 'entity_type_id',
30
+ array(
31
+ 'in' => array($customerEntityTypeId, $customerAddressEntityTypeId)
32
+ )
33
+ );
34
+
35
+ if ($collection && $collection->count()>0) {
36
+ foreach ($collection as $item) {
37
+ if ($item->getEntityTypeId() == $customerAddressEntityTypeId) {
38
+ $this->_customerAttributes[$item->getAttributeId()] = 'customer_address_'
39
+ . $item->getAttributeCode();
40
+ }
41
+ else {
42
+ $this->_customerAttributes[$item->getAttributeId()] = $item->getAttributeCode();
43
+ }
44
+ }
45
+ asort($this->_customerAttributes);
46
+ }
47
+ }
48
+
49
+ if (!is_null($attributeId)) {
50
+ return isset($this->_customerAttributes[$attributeId]) ? $this->_customerAttributes[$attributeId] : null;
51
+ }
52
+
53
+ return $this->_customerAttributes;
54
+ }
55
+
56
+ /**
57
+ * Setter for input fields names
58
+ * @param unknown $value
59
+ */
60
+ public function setInputName($value)
61
+ {
62
+ return $this->setName($value);
63
+ }
64
+
65
+ /**
66
+ * (non-PHPdoc)
67
+ * @see Mage_Core_Block_Html_Select::_toHtml()
68
+ */
69
+ public function _toHtml()
70
+ {
71
+ if (!$this->getOptions()) {
72
+ foreach ($this->_getCustomerAttributes() as $attributeId => $attributeCode) {
73
+ $this->addOption($attributeId, addslashes($attributeCode));
74
+ }
75
+ }
76
+
77
+ return parent::_toHtml();
78
+ }
79
+ }
app/code/community/Emv/DataSync/Block/Adminhtml/Form/Field/EmailVisionFields.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Used to manage EmailVision fields' block in back-office configuration
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Block_Adminhtml_Form_Field_EmailVisionFields extends Mage_Core_Block_Html_Select
10
+ {
11
+ /**
12
+ * @var array
13
+ */
14
+ protected $_emailVisionFields;
15
+
16
+ /**
17
+ * Prepare options attribute to render from EmailVision fields stored in conf
18
+ * If conf is empty, will call the member webservice to get members description (fields array)
19
+ *
20
+ * @return Array $this->_emailVisionFields An array containing lowered attributes names as keys, and their not lowered counterparts as values
21
+ */
22
+ protected function _getEmailVisionFields($fieldId = null)
23
+ {
24
+ if (is_null($this->_emailVisionFields)) {
25
+ $this->_emailVisionFields = array();
26
+ $savedFields = Mage::helper('emvdatasync')->getEmailVisionFieldsFromConfig();
27
+ if (!empty($savedFields)) {
28
+ foreach ($savedFields as $field) {
29
+ $this->_emailVisionFields[strtolower($field['name'])] = $field['name'];
30
+ }
31
+ } else {
32
+ $this->_emailVisionFields['empty'] = Mage::helper('emvdatasync')
33
+ ->__('Please synchronize with SmartFocus webservice (see above)');
34
+ }
35
+ }
36
+
37
+ if (!is_null($fieldId)) {
38
+ return isset($this->_emailVisionFields[$fieldId]) ? $this->_emailVisionFields[$fieldId] : null;
39
+ }
40
+ return $this->_emailVisionFields;
41
+ }
42
+
43
+ /**
44
+ * Setter for fields input name
45
+ *
46
+ * @param unknown $value
47
+ */
48
+ public function setInputName($value)
49
+ {
50
+ return $this->setName($value);
51
+ }
52
+
53
+ /**
54
+ * (non-PHPdoc)
55
+ * @see Mage_Core_Block_Html_Select::_toHtml()
56
+ */
57
+ public function _toHtml()
58
+ {
59
+ if (!$this->getOptions()) {
60
+ foreach ($this->_getEmailVisionFields() as $attributeId => $attributeCode) {
61
+ $this->addOption($attributeId, addslashes($attributeCode));
62
+ }
63
+ }
64
+ $this->setClass('emailvision_select');
65
+
66
+ return parent::_toHtml();
67
+ }
68
+ }
app/code/community/Emv/DataSync/Block/Adminhtml/System/Config/CustomerAttributes.php ADDED
@@ -0,0 +1,101 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Block to display customer attributes in back-office configuration selects
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Block_Adminhtml_System_Config_CustomerAttributes
10
+ extends Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract
11
+ {
12
+ /**
13
+ * @var Emv_DataSync_Block_Adminhtml_Form_Field_CustomerAttributes
14
+ */
15
+ protected $_magentoFieldsRenderer;
16
+
17
+ /**
18
+ * @var Emv_DataSync_Block_Adminhtml_Form_Field_EmailVisionFields
19
+ */
20
+ protected $_emailVisionFieldsRenderer;
21
+
22
+ public function __construct()
23
+ {
24
+ $this->setTemplate('emailvision/datasync/system/config/form/field/array.phtml');
25
+ parent::__construct();
26
+ }
27
+
28
+ /**
29
+ * Retrieve group column renderer
30
+ *
31
+ * @return Emv_DataSync_Block_Adminhtml_Form_Field_CustomerAttributes
32
+ */
33
+ protected function _getMagentoFieldsRenderer()
34
+ {
35
+ if (!$this->_magentoFieldsRenderer) {
36
+ $this->_magentoFieldsRenderer = $this->getLayout()->createBlock(
37
+ 'emvdatasync/adminhtml_form_field_customerAttributes', '',
38
+ array('is_render_to_js_template' => true)
39
+ );
40
+ $this->_magentoFieldsRenderer->setClass('customer_group_select');
41
+ $this->_magentoFieldsRenderer->setExtraParams('style="width:200px"');
42
+ }
43
+ return $this->_magentoFieldsRenderer;
44
+ }
45
+
46
+ /**
47
+ * Retrieve EmailVision fields column renderer
48
+ *
49
+ * @return Emv_DataSync_Block_Adminhtml_Form_Field_EmailVisionFields
50
+ */
51
+ protected function _getEmailVisionFieldsRenderer()
52
+ {
53
+ if (!$this->_emailVisionFieldsRenderer) {
54
+ $this->_emailVisionFieldsRenderer = $this->getLayout()->createBlock(
55
+ 'emvdatasync/adminhtml_form_field_emailVisionFields', '',
56
+ array('is_render_to_js_template' => true)
57
+ );
58
+ $this->_magentoFieldsRenderer->setClass('customer_group_select');
59
+ $this->_magentoFieldsRenderer->setExtraParams('style="width:200px"');
60
+ }
61
+ return $this->_emailVisionFieldsRenderer;
62
+ }
63
+
64
+ /**
65
+ * (non-PHPdoc)
66
+ * @see Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract::_prepareToRender()
67
+ */
68
+ protected function _prepareToRender()
69
+ {
70
+ $this->addColumn('magento_fields', array(
71
+ 'label' => Mage::helper('adminhtml')->__('Magento Fields'),
72
+ 'style' => 'width:200px',
73
+ 'renderer' => $this->_getMagentoFieldsRenderer(),
74
+ ));
75
+ $this->addColumn('emailvision_fields', array(
76
+ 'label' => Mage::helper('adminhtml')->__('SmartFocus Member Fields'),
77
+ 'style' => 'width:200px',
78
+ 'renderer' => $this->_getEmailVisionFieldsRenderer(),
79
+ ));
80
+ $this->_addAfter = false;
81
+ $this->_addButtonLabel = Mage::helper('adminhtml')->__('Add Field');
82
+ }
83
+
84
+ /**
85
+ * (non-PHPdoc)
86
+ * @see Mage_Adminhtml_Block_System_Config_Form_Field_Array_Abstract::_prepareArrayRow()
87
+ */
88
+ protected function _prepareArrayRow(Varien_Object $row)
89
+ {
90
+ $row->setData(
91
+ 'option_extra_attr_'
92
+ . $this->_getMagentoFieldsRenderer()->calcOptionHash($row->getData('magento_fields')),
93
+ 'selected="selected"'
94
+ );
95
+ $row->setData(
96
+ 'option_extra_attr_'
97
+ . $this->_getEmailVisionFieldsRenderer()->calcOptionHash($row->getData('emailvision_fields')),
98
+ 'selected="selected"'
99
+ );
100
+ }
101
+ }
app/code/community/Emv/DataSync/Block/Adminhtml/System/Config/Date.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Date block for back-office configuration
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Block_Adminhtml_System_Config_Date extends Mage_Adminhtml_Block_System_Config_Form_Field
10
+ {
11
+ /**
12
+ * (non-PHPdoc)
13
+ * @see Mage_Adminhtml_Block_System_Config_Form_Field::_getElementHtml()
14
+ */
15
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
16
+ {
17
+ $value = $element->getValue();
18
+
19
+ $date = Mage::helper('emvdatasync')->__('Not scheduled yet');
20
+ if ((string)$value) {
21
+ $date = Mage::app()->getLocale()->date(
22
+ $value,
23
+ Varien_Date::DATETIME_INTERNAL_FORMAT,
24
+ null,
25
+ true
26
+ );
27
+ }
28
+
29
+ return '<strong>' . $date . '</strong>';
30
+ }
31
+
32
+ }
app/code/community/Emv/DataSync/Block/Adminhtml/System/Config/GetFields.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Block for the get fields button in back-office configuration
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Block_Adminhtml_System_Config_GetFields extends Mage_Adminhtml_Block_System_Config_Form_Field
10
+ {
11
+ /**
12
+ * Set template to itself
13
+ *
14
+ * @return Auguria_EmailVision_Block_Adminhtml_System_Config_GetFields
15
+ */
16
+ protected function _prepareLayout()
17
+ {
18
+ parent::_prepareLayout();
19
+ if (!$this->getTemplate()) {
20
+ $this->setTemplate('emailvision/datasync/system/config/getfields.phtml');
21
+ }
22
+ return $this;
23
+ }
24
+
25
+ /**
26
+ * Get the button and scripts contents
27
+ *
28
+ * @param Varien_Data_Form_Element_Abstract $element
29
+ *
30
+ * @return string
31
+ */
32
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
33
+ {
34
+ return $this->_toHtml();
35
+ }
36
+ }
app/code/community/Emv/DataSync/Helper/Data.php ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Data helper for Data Sync module
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Helper_Data extends Mage_Core_Helper_Abstract
10
+ {
11
+ const XML_PATH_EMAILVISION_FIELDS = 'emvdatasync/customer_mapping/emailvision_fields';
12
+ const XML_PATH_MAPPED_ENTITY_ID = 'emvdatasync/customer_mapping/emailvision_entity_id';
13
+ const XML_PATH_EMAIL_SYNC = 'emvdatasync/customer_mapping/email_enabled';
14
+
15
+ const XML_PATH_ACCOUNT_FOR_MEMBER = 'emvdatasync/apimember/account';
16
+ const XML_PATH_ACCOUNT_FOR_BATCH_MEMBER = 'emvdatasync/batchmember/account';
17
+ const XML_PATH_CUSTOMER_MAPPING_ATTRIBUTES = 'emvdatasync/customer_mapping/attributes';
18
+
19
+ /**
20
+ * Is created folder for export data
21
+ * @var Boolean
22
+ */
23
+ protected $_createdFolder = false;
24
+
25
+ /**
26
+ * Lock file name pattern
27
+ */
28
+ const LOCK_FILE_NAME_PATTERN = 'cron_process.lock';
29
+
30
+ /**
31
+ * Check and create need folders
32
+ *
33
+ * @return boolean
34
+ */
35
+ public function checkAndCreatFolder()
36
+ {
37
+ if ($this->_createdFolder == false) {
38
+ $mageFile = new Varien_Io_File();
39
+ $mageFile->checkAndCreateFolder(Mage::getBaseDir('export'));
40
+ $mageFile->checkAndCreateFolder(Mage::getBaseDir('export'). DS . 'emailvision');
41
+ $mageFile->checkAndCreateFolder(Mage::getBaseDir('export'). DS . 'emailvision' . DS . 'uploaded');
42
+ $this->_createdFolder = true;
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Check if lock file exists
48
+ *
49
+ * @return boolean
50
+ */
51
+ public function checkLockFile()
52
+ {
53
+ return Mage::helper('emvcore')->checkLockFile(self::LOCK_FILE_NAME_PATTERN);
54
+ }
55
+
56
+ /**
57
+ * Create a lock file
58
+ *
59
+ * @param string $content
60
+ * @return mutilple <number, boolean>
61
+ */
62
+ public function createLockFile($content = '')
63
+ {
64
+ return Mage::helper('emvcore')->createLockFile(self::LOCK_FILE_NAME_PATTERN, $content);
65
+ }
66
+
67
+ /**
68
+ * Remove a lock file
69
+ *
70
+ * @param string $content
71
+ * @return boolean
72
+ */
73
+ public function removeLockFile($content = '')
74
+ {
75
+ return Mage::helper('emvcore')->removeLockFile(self::LOCK_FILE_NAME_PATTERN);
76
+ }
77
+
78
+ /**
79
+ * Get formatted date time in the same store timezone
80
+ * in the following format : Y-m-d H:i:s (such as 2013-09-10 14:31:24)
81
+ *
82
+ * @param string
83
+ */
84
+ public function getDateTime($timestamp = null, $storeId = null)
85
+ {
86
+ if ($storeId !== null) {
87
+ $date = Mage::app()->getLocale()->storeDate($storeId, null, true);
88
+ $formatedDate = $date->toString('Y-M-d HH:mm:ss');
89
+
90
+ return $formatedDate;
91
+ }
92
+
93
+ return Mage::getModel('core/date')->date('Y-m-d H:i:s', $timestamp);
94
+ }
95
+
96
+ /**
97
+ * Get GMT date time in the following format : Y-m-d H:i:s (such as 2013-09-10 14:31:24)
98
+ *
99
+ * @param string
100
+ */
101
+ public function getFormattedGmtDateTime($timestamp = null)
102
+ {
103
+ return Mage::getModel('core/date')->gmtDate('Y-m-d H:i:s', $timestamp);
104
+ }
105
+
106
+ /**
107
+ * @param array $fields
108
+ * @return Emv_DataSync_Helper_Data
109
+ */
110
+ public function saveEmailVisionFieldsInConfig($fields = array())
111
+ {
112
+ $config = Mage::getModel('core/config');
113
+ $config->saveConfig(
114
+ self::XML_PATH_EMAILVISION_FIELDS, Mage::helper('core')->jsonEncode($fields)
115
+ );
116
+ return $this;
117
+ }
118
+
119
+ /**
120
+ * @return array
121
+ */
122
+ public function getEmailVisionFieldsFromConfig()
123
+ {
124
+ $fields = array();
125
+ $encodedString = Mage::getStoreConfig(self::XML_PATH_EMAILVISION_FIELDS);
126
+ if ($encodedString) {
127
+ $fields = Mage::helper('core')->jsonDecode($encodedString);
128
+ }
129
+ return $fields;
130
+ }
131
+
132
+ /**
133
+ * Save mapped EmailVision Entity Id
134
+ *
135
+ * @param string $field
136
+ * @return Emv_DataSync_Helper_Data
137
+ */
138
+ public function saveMappedEntityId($field)
139
+ {
140
+ $config = Mage::getModel('core/config');
141
+ $config->saveConfig(self::XML_PATH_MAPPED_ENTITY_ID, $field);
142
+ return $this;
143
+ }
144
+
145
+ /**
146
+ * @return string
147
+ */
148
+ public function getMappedEntityId()
149
+ {
150
+ return Mage::getStoreConfig(self::XML_PATH_MAPPED_ENTITY_ID);
151
+ }
152
+
153
+ /**
154
+ * @param string $type
155
+ * @param string $storeId
156
+ * @return Emv_Core_Model_Account
157
+ */
158
+ public function getEmvAccountForStore($type = "member", $storeId = null)
159
+ {
160
+ $path = self::XML_PATH_ACCOUNT_FOR_MEMBER;
161
+ if ($type == 'batch') {
162
+ $path = self::XML_PATH_ACCOUNT_FOR_BATCH_MEMBER;
163
+ }
164
+
165
+ $accountId = Mage::getStoreConfig($path, $storeId);
166
+ $account = Mage::getModel('emvcore/account');
167
+ $account->load($accountId);
168
+
169
+ return $account;
170
+ }
171
+
172
+ /**
173
+ * Get mapped attributes from config
174
+ *
175
+ * @param string $storeId
176
+ * @return array
177
+ */
178
+ public function getEmvMappedCustomerAttributes($storeId = null)
179
+ {
180
+ return unserialize(Mage::getStoreConfig(self::XML_PATH_CUSTOMER_MAPPING_ATTRIBUTES, $storeId));
181
+ }
182
+
183
+ /**
184
+ * Is email used to sync subscribers?
185
+ *
186
+ * @param string $storeId
187
+ * @return boolean
188
+ */
189
+ public function getEmailEnabled($storeId = null)
190
+ {
191
+ return (bool)Mage::getStoreConfig(self::XML_PATH_EMAIL_SYNC, $storeId);
192
+ }
193
+ }
app/code/community/Emv/DataSync/Helper/Service.php ADDED
@@ -0,0 +1,318 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Data helper for Sync Services
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Helper_Service extends Mage_Core_Helper_Abstract
10
+ {
11
+ /**
12
+ * @var Varien_Data_Collection_Db
13
+ */
14
+ protected $_entityFieldsToSelect;
15
+
16
+ /**
17
+ * Attribute Join list
18
+ * @var array
19
+ */
20
+ protected $_joinFactory = null;
21
+
22
+ /**
23
+ * @var string
24
+ */
25
+ protected $_customerTypeId = null;
26
+
27
+ /**
28
+ * @var string
29
+ */
30
+ protected $_customerAddressTypeId = null;
31
+
32
+ const FIELD_MEMBER_LAST_UPDATE = 'member_last_update_date';
33
+ const FIELD_DATA_LAST_UPDATE = 'data_last_update_date';
34
+ const FIELD_DATE_UNJOIN = 'date_unjoin';
35
+
36
+ /**
37
+ * Get magento attribute for the given attribute ids
38
+ *
39
+ * @param array $attributeIds
40
+ * @return Mage_Eav_Model_Resource_Entity_Attribute_Collection
41
+ */
42
+ public function getMagentoAttributes($attributeIds = array())
43
+ {
44
+ $magentoAttributes = array();
45
+ $customerTypeId = $this->getCustomerTypeId();
46
+ $customerAddressEntityTypeId = $this->getCustomerAddressTypeId();
47
+
48
+ $collection = Mage::getResourceModel('eav/entity_attribute_collection')
49
+ ->addFieldToFilter(
50
+ 'entity_type_id',
51
+ array('in' => array($customerTypeId, $customerAddressEntityTypeId))
52
+ )
53
+ ->addFieldToFilter(
54
+ 'attribute_id',
55
+ array('in' => $attributeIds)
56
+ )
57
+ ;
58
+
59
+ return $collection;
60
+ }
61
+
62
+ /**
63
+ * Prepare and get mapped customer attributes
64
+ *
65
+ * @return Varien_Data_Collection_Db
66
+ */
67
+ public function prepareAndGetMappedCustomerAttributes()
68
+ {
69
+ if ($this->_entityFieldsToSelect == null) {
70
+ // init $this->_entityFieldsToSelect
71
+ $this->_entityFieldsToSelect = new Varien_Data_Collection_Db();
72
+
73
+ $mappedFields = Mage::helper('emvdatasync')->getEmvMappedCustomerAttributes();
74
+ if (count($mappedFields)) {
75
+ // retreive magento attribute ids
76
+ $attributeIds = array();
77
+ foreach ($mappedFields as $field) {
78
+ $attributeIds[] = $field['magento_fields'] ;
79
+ }
80
+
81
+ if (count($attributeIds)) {
82
+ $collection = $this->getMagentoAttributes($attributeIds);
83
+ if ($collection && $collection->count() > 0) {
84
+ foreach($mappedFields as $field) {
85
+ $attribute = $collection->getItemById($field['magento_fields']);
86
+ if ($attribute) {
87
+ // need to know which SmartFocus attribute has been mapped to magento one
88
+ $attribute->setEmailVisionKey($field['emailvision_fields']);
89
+ }
90
+ }
91
+
92
+ $this->_entityFieldsToSelect = $collection;
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ return $this->_entityFieldsToSelect;
99
+ }
100
+
101
+ /**
102
+ * Add customer and address attributes into subscriber select
103
+ *
104
+ * @param Mage_Newsletter_Model_Resource_Subscriber_Collection $collection
105
+ * @return Mage_Newsletter_Model_Resource_Subscriber_Collection
106
+ */
107
+ public function addCustomerAndAddressAttributes(Varien_Data_Collection_Db $collection)
108
+ {
109
+ /* @var $customerModel Mage_Customer_Model_Customer */
110
+ /* @var $addressModel Mage_Customer_Model_Address */
111
+ // Get connection from collection
112
+ $adapter = $collection->getConnection();
113
+
114
+ // Prepare required table data (id, etc...)
115
+ $tablePrefix = (string)Mage::getConfig()->getTablePrefix();
116
+ $customerEntityTable = $tablePrefix . 'customer_entity';
117
+ $customerEavIntTable = $tablePrefix . 'customer_entity_int';
118
+ $addressEntityTable = $tablePrefix . 'customer_address_entity';
119
+
120
+ // Prepare Default billing attribute (customer eav, required to get only one address)
121
+ $defaultBillingAttribute = Mage::getModel('customer/customer')->getAttribute('default_billing');
122
+
123
+ // Get address entity type
124
+ $customerAddressEntityTypeId = $this->getCustomerAddressTypeId();
125
+
126
+ if (!isset($this->_joinFactory)) {
127
+ // Prepare empty joinBuilder array
128
+ // (customer entity must be joined in order to be able of getting address)
129
+ $this->_joinFactory = array(
130
+ 'entity_table' => array(
131
+ $customerEntityTable => array($customerEntityTable . '.entity_id'),
132
+ $addressEntityTable => array($addressEntityTable . '.entity_id')
133
+ ),
134
+ 'eav_tables' => array()
135
+ );
136
+
137
+ // Prepare a join builder array (to avoid to do a join per attribute, even on a unique table)
138
+ foreach ($this->prepareAndGetMappedCustomerAttributes() as $attribute) {
139
+ $tableName = $attribute->getBackend()->getTable();
140
+ $tableType = 'eav_tables';
141
+ $fieldPrefix = '';
142
+ $preparedAttributeCode = $attribute->getAttributeCode();
143
+
144
+ if ($attribute->getEntityTypeId() == $customerAddressEntityTypeId) {
145
+ if (strpos($tableName, $addressEntityTable) !== false) {
146
+ $preparedAttributeCode = 'customer_address_' . $preparedAttributeCode;
147
+ }
148
+ } else {
149
+ // Check table type (entity or eav)
150
+ if ($tableName == $customerEntityTable) {
151
+ $tableType = 'entity_table';
152
+ $fieldPrefix = $tableName . '.';
153
+ }
154
+
155
+ // only get store_id from newsletter subscriber table
156
+ if ($attribute->getAttributeCode() == 'store_id') {
157
+ continue;
158
+ }
159
+ }
160
+
161
+ // Add current attribute as field to join
162
+ $this->_joinFactory[$tableType][$tableName][$attribute->getId()]
163
+ = $fieldPrefix . $attribute->getAttributeCode();
164
+
165
+ // !!! use final_attribute_code to get value
166
+ $attribute->setFinalAttributeCode($preparedAttributeCode);
167
+ }
168
+ }
169
+
170
+ // Manage entities fields
171
+ $collection->getSelect()
172
+ // Add customer_entity fields (no aliases, an only call for all customer entity fields)
173
+ ->joinLeft(
174
+ $customerEntityTable,
175
+ $customerEntityTable . '.entity_id = main_table.customer_id',
176
+ $this->_joinFactory['entity_table'][$customerEntityTable]
177
+ )
178
+ // Join default billing attributes (limit address results to 1)
179
+ ->joinLeft(
180
+ array('default_billing_id_table' => $customerEavIntTable),
181
+ $adapter->quoteInto(
182
+ 'default_billing_id_table.entity_id = main_table.customer_id'
183
+ . ' AND default_billing_id_table.attribute_id = ?',
184
+ (int)$defaultBillingAttribute->getAttributeId()
185
+ ),
186
+ array('default_billing_id' => 'default_billing_id_table.value')
187
+ )
188
+ // Add customer address entity fields
189
+ ->joinLeft(
190
+ $addressEntityTable,
191
+ $adapter->quoteInto(
192
+ $customerEntityTable . '.entity_id = '. $addressEntityTable . '.parent_id'
193
+ . ' AND '. $addressEntityTable . '.entity_id = default_billing_id_table.value'
194
+ . ' AND default_billing_id_table.attribute_id = ?',
195
+ (int)$defaultBillingAttribute->getAttributeId()
196
+ ),
197
+ $this->_joinFactory['entity_table'][$addressEntityTable]
198
+ );
199
+
200
+ // Join a table foreach eav attributes. Two ways, customer eav or address eav
201
+ foreach ($this->_joinFactory['eav_tables'] as $tableName => $fields) {
202
+ // Address eav attributes
203
+ if (strpos($tableName, 'customer_address') !== false) {
204
+ foreach ($fields as $fieldId => $fieldSql) {
205
+ $collection->getSelect()
206
+ ->joinLeft(
207
+ array('customer_address_' . $fieldSql . '_table' => $tableName),
208
+ $adapter->quoteInto(
209
+ 'customer_address_' . $fieldSql . '_table' . '.entity_id = ' . $addressEntityTable . '.entity_id'
210
+ . ' AND customer_address_' . $fieldSql . '_table' . '.attribute_id = ?',
211
+ $fieldId
212
+ ),
213
+ array('customer_address_' . $fieldSql => 'customer_address_' . $fieldSql . '_table' . '.value')
214
+ );
215
+ }
216
+ } else {// Customer eav attributes
217
+ foreach ($fields as $fieldId => $fieldSql) {
218
+ $collection->getSelect()
219
+ ->joinLeft(
220
+ array($fieldSql . '_table' => $tableName),
221
+ $adapter->quoteInto(
222
+ $fieldSql . '_table' . '.entity_id = main_table.customer_id'
223
+ . ' AND ' . $fieldSql . '_table' . '.attribute_id = ?',
224
+ $fieldId
225
+ ),
226
+ array($fieldSql => $fieldSql . '_table' . '.value')
227
+ );
228
+ }
229
+ }
230
+ }
231
+
232
+ // dispatch a new event in order to add additional data if needed
233
+ Mage::dispatchEvent('member_collection_load_after', array('members' => $collection));
234
+
235
+ return $collection;
236
+ }
237
+
238
+ /**
239
+ * Get date in EmailVison format in the following format : m/d/Y H:i:s (such as 10/09/2013 14:31:24)
240
+ *
241
+ * @param string $date in GMT timezone
242
+ * @return string
243
+ */
244
+ public function getEmailVisionDate($date)
245
+ {
246
+ $dateModel = Mage::getSingleton('core/date');
247
+ return $dateModel->date(
248
+ 'm/d/Y H:i:s',
249
+ $date
250
+ );
251
+ }
252
+
253
+ /**
254
+ * @return string
255
+ */
256
+ public function getCustomerTypeId()
257
+ {
258
+ if ($this->_customerTypeId == null) {
259
+ $this->_customerTypeId = Mage::getModel('eav/entity')->setType('customer')->getTypeId();
260
+ }
261
+ return $this->_customerTypeId;
262
+ }
263
+
264
+ /**
265
+ * @return string
266
+ */
267
+ public function getCustomerAddressTypeId()
268
+ {
269
+ if ($this->_customerAddressTypeId == null) {
270
+ $this->_customerAddressTypeId = Mage::getModel('eav/entity')->setType('customer_address')->getTypeId();
271
+ }
272
+ return $this->_customerAddressTypeId;
273
+ }
274
+
275
+ /**
276
+ * @param array $updatedSubscribers
277
+ * @param array $rejoinedSubscribers
278
+ * @param string $time
279
+ * @return boolean
280
+ */
281
+ public function massSetMemberLastUpdateDate($updatedSubscribers = array(), $rejoinedSubscribers = array(), $time = null)
282
+ {
283
+ $error = true;
284
+
285
+ if (!empty($updatedSubscribers)) {
286
+ /* @var $write Varien_Db_Adapter_Pdo_Mysql */
287
+ $write = Mage::getSingleton('core/resource')->getConnection('core_write');
288
+ $subscriberTable = Mage::getResourceModel('newsletter/subscriber')->getMainTable();
289
+ // date should be store ind GMT timezone
290
+ $now = Mage::helper('emvdatasync')->getFormattedGmtDateTime();
291
+ if ($time == null) {
292
+ $time = $now;
293
+ }
294
+
295
+ try {
296
+ // Update memberLastUpdateDate
297
+ $fieldMemberLastUpdate = self::FIELD_MEMBER_LAST_UPDATE;
298
+ $sqlQuery = "UPDATE $subscriberTable SET {$fieldMemberLastUpdate} = '$time'
299
+ WHERE subscriber_id IN(" . implode(',', $updatedSubscribers) . ');';
300
+ $write->query($sqlQuery);
301
+
302
+ if (!empty($rejoinedSubscribers)) {
303
+ // Reset UnjoinDate for Rejoined subscribers
304
+ $fieldUnjoinDate = self::FIELD_DATE_UNJOIN;
305
+ $sqlQuery = "UPDATE $subscriberTable SET $fieldUnjoinDate = null
306
+ WHERE subscriber_id IN(" . implode(',', $rejoinedSubscribers) . ');';
307
+ $write->query($sqlQuery);
308
+ }
309
+ } catch (Exception $e) {
310
+ Mage::logException($e);
311
+ $error = 'Exception while processing massSetMemberLastUpdateDate with exceptionMessage:\n ' . $e->getMessage();
312
+ $error .= '\n Subscribers ids detail: ' . implode(', ', $updatedSubscribers);
313
+ }
314
+ }
315
+
316
+ return $error;
317
+ }
318
+ }
app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/ApiMember/Account.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Account Backend model for Triggered Exports
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Model_Adminhtml_System_Config_Backend_ApiMember_Account
10
+ extends Emv_Core_Model_Adminhtml_System_Config_Backend_Account_Abstract
11
+ {
12
+ /**
13
+ * @var string
14
+ */
15
+ protected $_urlType = Emv_Core_Model_Account::URL_MEMBER_SERVICE_TYPE;
16
+
17
+ /**
18
+ * (non-PHPdoc)
19
+ * @see Emv_Core_Model_Adminhtml_System_Config_Backend_Account_Abstract::_getService()
20
+ */
21
+ protected function _getService()
22
+ {
23
+ return Mage::getModel('emvcore/service_member');
24
+ }
25
+ }
app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/ApiMember/Cron.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Cron Expression for Triggered Export
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Model_Adminhtml_System_Config_Backend_ApiMember_Cron extends Mage_Core_Model_Config_Data
10
+ {
11
+ /**
12
+ * @var string
13
+ */
14
+ protected $_crontabPath = 'crontab/jobs/emailvision_member_export/schedule/cron_expr';
15
+
16
+ /**
17
+ * Save a formated crontime in core_config_data
18
+ *
19
+ * @see Mage_Core_Model_Abstract::_afterSave()
20
+ */
21
+ protected function _afterSave()
22
+ {
23
+ $cronConfigModel = Mage::getModel('core/config_data')
24
+ ->load($this->_crontabPath, 'path');
25
+
26
+ // if the cron is disabled, we remove the cron expression to avoid launching it again
27
+ $enabled = $this->getFieldsetDataValue('enabled');
28
+ if (!$enabled) {
29
+ if ($cronConfigModel->getConfigId()) {
30
+ $cronConfigModel->delete();
31
+ }
32
+ return;
33
+ }
34
+
35
+ $cronExprArray = array(
36
+ 'quarter_hour' => '*/15 * * * *',
37
+ 'half_hour' => '*/30 * * * *',
38
+ 'hour' => '0 * * * *',
39
+ 'two_hours' => '0 */2 * * *',
40
+ 'four_hours' => '0 */4 * * *',
41
+ 'six_hours' => '0 */6 * * *',
42
+ 'twelve_hours' => '0 */12 * * *',
43
+ 'daily' => '0 0 * * *',
44
+ );
45
+
46
+ $cronExprString = $cronExprArray[$this->getValue()];
47
+ try {
48
+ $cronConfigModel
49
+ ->setValue($cronExprString)
50
+ ->setPath($this->_crontabPath)
51
+ ->save();
52
+ } catch (Exception $e) {
53
+ Mage::throwException(Mage::helper('emvdatasync')->__('Unable to save the cron expression for triggered exports'));
54
+ }
55
+
56
+ parent::_afterSave();
57
+ }
58
+
59
+ }
app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/ApiMember/Enabled.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Enabled Backend Model for Triggered Exports
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Model_Adminhtml_System_Config_Backend_ApiMember_Enabled
10
+ extends Emv_Core_Model_Adminhtml_System_Config_Backend_Enabled
11
+ {
12
+ /**
13
+ * @var string
14
+ */
15
+ protected $_processName = 'Triggered Exports';
16
+ }
app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/BatchMember/Account.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Account Backend model for Scheduled Exports
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Model_Adminhtml_System_Config_Backend_BatchMember_Account
10
+ extends Emv_Core_Model_Adminhtml_System_Config_Backend_Account_Abstract
11
+ {
12
+ /**
13
+ * @var string
14
+ */
15
+ protected $_urlType = Emv_Core_Model_Account::URL_BATCH_MEMBER_SERVICE_TYPE;
16
+
17
+ /**
18
+ * (non-PHPdoc)
19
+ * @see Emv_Core_Model_Adminhtml_System_Config_Backend_Account_Abstract::_getService()
20
+ */
21
+ protected function _getService()
22
+ {
23
+ return Mage::getModel('emvcore/service_batchMember');
24
+ }
25
+ }
app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/BatchMember/Cron.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Cron Expression for Scheduled Exports
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Model_Adminhtml_System_Config_Backend_BatchMember_Cron extends Mage_Core_Model_Config_Data
10
+ {
11
+ /**
12
+ * @var string
13
+ */
14
+ protected $_crontabPath = 'crontab/jobs/emailvision_batchmember_export/schedule/cron_expr';
15
+
16
+ /**
17
+ * Save a formated crontime in core_config_data
18
+ *
19
+ * @see Mage_Core_Model_Abstract::_afterSave()
20
+ */
21
+ protected function _afterSave()
22
+ {
23
+ $cronConfigModel = Mage::getModel('core/config_data')
24
+ ->load($this->_crontabPath, 'path');
25
+
26
+ // if the cron is disabled, we remove the cron expression to avoid launching it again
27
+ $enabled = $this->getFieldsetDataValue('enabled');
28
+ if (!$enabled) {
29
+ if ($cronConfigModel->getConfigId()) {
30
+ $cronConfigModel->delete();
31
+ }
32
+ return;
33
+ }
34
+
35
+ $frequencyDaily = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_DAILY;
36
+ $frequencyWeekly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_WEEKLY;
37
+ $frequencyMonthly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_MONTHLY;
38
+
39
+ // get time and frequency
40
+ $time = $this->getFieldsetDataValue('time');
41
+ $frequency = $this->getFieldsetDataValue('frequency');
42
+
43
+ // build cron expression string
44
+ $cronExprArray = array(
45
+ intval($time[1]), // Minute
46
+ intval($time[0]), // Hour
47
+ ($frequency == $frequencyMonthly) ? '1' : '*', // Day of the Month
48
+ '*', // Month of the Year
49
+ ($frequency == $frequencyWeekly) ? '1' : '*', // Day of the Week
50
+ );
51
+ $cronExprString = join(' ', $cronExprArray);
52
+
53
+ try {
54
+ $cronConfigModel
55
+ ->setValue($cronExprString)
56
+ ->setPath($this->_crontabPath)
57
+ ->save();
58
+ } catch (Exception $e) {
59
+ Mage::throwException(Mage::helper('emvdatasync')->__('Unable to save the cron expression for scheduled exports'));
60
+ }
61
+ }
62
+ }
app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/BatchMember/Enabled.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Enabled Backend Model for Scheduled Exports
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Model_Adminhtml_System_Config_Backend_BatchMember_Enabled
10
+ extends Emv_Core_Model_Adminhtml_System_Config_Backend_Enabled
11
+ {
12
+ /**
13
+ * @var string
14
+ */
15
+ protected $_processName = 'Scheduled Exports';
16
+ }
app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/Clean/Cron.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Cron Expression for Exported File Cleanning process
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Model_Adminhtml_System_Config_Backend_Clean_Cron extends Emv_DataSync_Model_Adminhtml_System_Config_Backend_BatchMember_Cron
10
+ {
11
+ /**
12
+ * @var string
13
+ */
14
+ protected $_crontabPath = 'crontab/jobs/emailvision_clean/schedule/cron_expr';
15
+ }
app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Source/Fields.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Source model for customer mapping fields in back office configuration
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Model_Adminhtml_System_Config_Source_Fields
10
+ {
11
+ /**
12
+ * Return EmailVision customer mapping fields
13
+ *
14
+ * @return Array $emailVisionFields An array where keys are codes and values are labels
15
+ */
16
+ public function toOptionArray()
17
+ {
18
+ $emailVisionFields = array();
19
+ $savedFields = Mage::helper('emvdatasync')->getEmailVisionFieldsFromConfig();
20
+ if (!empty($savedFields)) {
21
+ foreach ($savedFields as $field) {
22
+ $emailVisionFields[strtolower($field['name'])] = $field['name'];
23
+ }
24
+ } else {
25
+ $emailVisionFields['empty'] = Mage::helper('emvdatasync')->__('Please synchronize with SmartFocus webservice (see above)');
26
+ }
27
+
28
+ return $emailVisionFields;
29
+ }
30
+ }
app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Source/MemberCronTime.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Source Cron Time Triggered Exports
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Model_Adminhtml_System_Config_Source_MemberCronTime
10
+ {
11
+ /**
12
+ *
13
+ * @return Array An array where keys are keys and values are labels
14
+ */
15
+ public function toOptionArray()
16
+ {
17
+ return array(
18
+ 'quarter_hour' => Mage::helper('emvdatasync')->__('Every 15 minutes'),
19
+ 'half_hour' => Mage::helper('emvdatasync')->__('Every 30 minutes'),
20
+ 'hour' => Mage::helper('emvdatasync')->__('Hourly'),
21
+ 'two_hours' => Mage::helper('emvdatasync')->__('Every 2 hours'),
22
+ 'four_hours' => Mage::helper('emvdatasync')->__('Every 4 hours'),
23
+ 'six_hours' => Mage::helper('emvdatasync')->__('Every 6 hours'),
24
+ 'twelve_hours' => Mage::helper('emvdatasync')->__('Every 12 hours'),
25
+ 'daily' => Mage::helper('emvdatasync')->__('Daily'),
26
+ );
27
+ }
28
+ }
app/code/community/Emv/DataSync/Model/Cron.php ADDED
@@ -0,0 +1,254 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Local cron model to call massUpdate method
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
10
+ {
11
+ const XML_PATH_EMAIL_EMAILVISION_TEMPLATE = 'emvdatasync/general/error_email_template';
12
+ const XML_PATH_EMAIL_EMAILVISION_SENDER = 'emvdatasync/general/error_email_sender';
13
+ const XML_PATH_EMAIL_EMAILVISION_RECIPIENT = 'emvdatasync/general/error_email_recipient';
14
+
15
+ const XML_PATH_EMAILVISION_BATCH_ENABLED = 'emvdatasync/batchmember/enabled';
16
+ const XML_PATH_EMAILVISION_APIMEMBER_ENABLED = 'emvdatasync/apimember/enabled';
17
+ const XML_PATH_EMAILVISION_CLEAN_ENABLED = 'emvdatasync/export_file_cleaning/enabled';
18
+
19
+ /**
20
+ * Error messages
21
+ *
22
+ * @var array
23
+ */
24
+ protected $_errors = array();
25
+
26
+ /**
27
+ * Send customer export errors
28
+ *
29
+ * @return Emv_DataSync_Model_Cron
30
+ */
31
+ public function _sendCustomerExportErrors()
32
+ {
33
+ if (!$this->_errors) {
34
+ return $this;
35
+ }
36
+ if (!Mage::getStoreConfig(self::XML_PATH_EMAIL_EMAILVISION_RECIPIENT)) {
37
+ return $this;
38
+ }
39
+
40
+ try {
41
+ $translate = Mage::getSingleton('core/translate');
42
+ /* @var $translate Mage_Core_Model_Translate */
43
+ $translate->setTranslateInline(false);
44
+
45
+ /* @var $emailTemplate Emv_Emt_Model_Mage_Core_Email_Template */
46
+ $emailTemplate = Mage::getModel('core/email_template');
47
+
48
+ /* @var $emailTemplate Mage_Core_Model_Email_Template */
49
+ $emailTemplate->setDesignConfig(array('area' => 'backend'))
50
+ ->sendTransactional(
51
+ Mage::getStoreConfig(self::XML_PATH_EMAIL_EMAILVISION_TEMPLATE),
52
+ Mage::getStoreConfig(self::XML_PATH_EMAIL_EMAILVISION_SENDER),
53
+ Mage::getStoreConfig(self::XML_PATH_EMAIL_EMAILVISION_RECIPIENT),
54
+ null,
55
+ array('errors' => implode("<br>", $this->_errors))
56
+ );
57
+
58
+ $translate->setTranslateInline(true);
59
+ } catch (Exception $e) {
60
+ Mage::logException($e);
61
+ }
62
+
63
+ return $this;
64
+ }
65
+
66
+ /**
67
+ * Cron method to call a mass customers export with apiBatchMember
68
+ *
69
+ * @return Emv_DataSync_Model_Cron
70
+ */
71
+ public function batchMemberExport()
72
+ {
73
+ $helper = Mage::helper('emvdatasync');
74
+ $exportDone = false;
75
+
76
+ if (!Mage::getStoreConfigFlag(self::XML_PATH_EMAILVISION_BATCH_ENABLED)) {
77
+ return $this;
78
+ }
79
+
80
+ $this->_errors = array();
81
+
82
+ $startRunTime = $helper->getFormattedGmtDateTime();
83
+
84
+ $processErrors = array();
85
+ $createdLock = false;
86
+ try {
87
+ // check and create lock
88
+ if (!$helper->checkLockFile()) {
89
+ $service = Mage::getModel('emvdatasync/service_batchMember');
90
+ $account = Mage::helper('emvdatasync')->getEmvAccountForStore('batch');
91
+ $service->setAccount($account);
92
+
93
+ // create lock file => do not allow several process at the same time
94
+ $helper->createLockFile('Batch member synchronization cron process running at GMT timezone ' . $startRunTime);
95
+ $createdLock = true;
96
+
97
+ $exportDone = $service->massExportCustomers();
98
+
99
+ // If non-blocking errors occurs
100
+ $processErrors = $service->getErrors();
101
+ if (!empty($processErrors)) {
102
+ throw(new Exception('Some non-blocking errors occured, check below for more details:'));
103
+ }
104
+ }
105
+ } catch (Exception $e) {
106
+ $this->_errors[] = 'Errors occured while running Scheduled Member Export (batchmemberApi cron), at GMT timezone '
107
+ . $startRunTime;
108
+ $this->_errors[] = $e->getMessage();
109
+
110
+ foreach ($processErrors as $apiError) {
111
+ $this->_errors[] = $apiError;
112
+ }
113
+ }
114
+
115
+ // if lock is created, need to delete it
116
+ if ($createdLock) {
117
+ try {
118
+ $helper->removeLockFile();
119
+ } catch (Exception $e) {
120
+ $this->_errors[] = $e->getMessage();
121
+ }
122
+ }
123
+
124
+ // if some errors occur, we should inform the client
125
+ if (count($this->_errors)) {
126
+ $this->_sendCustomerExportErrors();
127
+ }
128
+
129
+ if ($exportDone) {
130
+ $config = Mage::getModel('core/config');
131
+ $config->saveConfig(
132
+ 'emvdatasync/last_successful_synchronization/customers',
133
+ Mage::helper('emvdatasync')->getFormattedGmtDateTime()
134
+ );
135
+ $config->removeCache();
136
+ }
137
+
138
+ return $this;
139
+ }
140
+
141
+ /**
142
+ * Cron method to call a memberApi export. Uses some collection and added fields to export the observer updated
143
+ *
144
+ * @return Emv_DataSync_Model_Cron
145
+ */
146
+ public function memberExport()
147
+ {
148
+ $helper = Mage::helper('emvdatasync');
149
+ if (!Mage::getStoreConfigFlag(self::XML_PATH_EMAILVISION_APIMEMBER_ENABLED)) {
150
+ return $this;
151
+ }
152
+
153
+ $this->_errors = array();
154
+
155
+ // gmt date time
156
+ $startRunTime = $helper->getFormattedGmtDateTime();
157
+
158
+ $processErrors = array();
159
+ $createdLock = false;
160
+ try {
161
+ // check and create lock
162
+ if (!$helper->checkLockFile()) {
163
+ $service = Mage::getModel('emvdatasync/service_member');
164
+ $account = Mage::helper('emvdatasync')->getEmvAccountForStore();
165
+ $service->setAccount($account);
166
+
167
+ // create lock file => do not allow several process at the same time
168
+ $helper->createLockFile('Member synchronization cron process running at GMT timezone ' . $startRunTime);
169
+ $createdLock = true;
170
+
171
+ // Api calls
172
+ $service->triggerExport();
173
+
174
+ // If non-blocking errors occurs
175
+ $processErrors = $service->getErrors();
176
+ if (!empty($processErrors)) {
177
+ throw (new Exception('Some non-blocking errors occured, check below for more details:'));
178
+ }
179
+ }
180
+ } catch (Exception $e) {
181
+ $this->_errors[] = 'Errors occured while running memberExport (memberApi cron), at GMT timezone ' . $startRunTime;
182
+ $this->_errors[] = $e->getMessage();
183
+ foreach ($processErrors as $error) {
184
+ $this->_errors[] = $error;
185
+ }
186
+ }
187
+
188
+ // if lock is created, need to delete it
189
+ if ($createdLock) {
190
+ try {
191
+ $helper->removeLockFile();
192
+ } catch (Exception $e) {
193
+ $this->_errors[] = $e->getMessage();
194
+ }
195
+ }
196
+
197
+ // if some errors occur, we should inform the client
198
+ if (count($this->_errors)) {
199
+ $this->_sendCustomerExportErrors();
200
+ }
201
+
202
+ return $this;
203
+ }
204
+
205
+ /**
206
+ * Cron method to clean files moved in uploaded folder after exporting customers
207
+ *
208
+ * @return Emv_DataSync_Model_Cron
209
+ */
210
+ public function cleanEmailVisionFiles()
211
+ {
212
+ if (!Mage::getStoreConfigFlag(self::XML_PATH_EMAILVISION_CLEAN_ENABLED)) {
213
+ return $this;
214
+ }
215
+
216
+ // everything is in GMT date time
217
+ $startRunTime = Mage::helper('emvdatasync')->getFormattedGmtDateTime();
218
+
219
+ $this->_errors = array();
220
+
221
+ try {
222
+ // Check folders in case this method is called before any export
223
+ Mage::helper('emvdatasync')->checkAndCreatFolder();
224
+
225
+ // remove uploaded file
226
+ $dirHandler = @opendir(Mage::getBaseDir('export'). DS . 'emailvision' . DS . 'uploaded');
227
+ while($filename = readdir($dirHandler)) {
228
+ // Delete any file in uploaded folder
229
+ if ($filename != '.' && $filename != '..') {
230
+ unlink(Mage::getBaseDir('export'). DS . 'emailvision' . DS . 'uploaded'. DS . $filename);
231
+ }
232
+ }
233
+ @closedir($dirHandler);
234
+
235
+ // remove emailvision export folder
236
+ $dirHandler = @opendir(Mage::getBaseDir('export'). DS . 'emailvision' );
237
+ while($filename = readdir($dirHandler)) {
238
+ $path = Mage::getBaseDir('export'). DS . 'emailvision' . DS . $filename;
239
+ // Delete any file in uploaded folder
240
+ if ($filename != '.' && $filename != '..' && is_file($path)) {
241
+ unlink($path);
242
+ }
243
+ }
244
+ @closedir($dirHandler);
245
+ } catch (Exception $e) {
246
+ $this->_errors[] = 'Errors occured while removing exported files (cleanEmailVisionFiles cron), at GMT timezone '
247
+ . $startRunTime;
248
+ $this->_errors[] = $e->getMessage();
249
+ $this->_sendCustomerExportErrors();
250
+ }
251
+
252
+ return $this;
253
+ }
254
+ }
app/code/community/Emv/DataSync/Model/Observer.php ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Observe subscriber save to set its last update date and call the api method to update it's changes
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ /* @var $customer Mage_Customer_Model_Customer */
10
+ /* @var $customerAddress Mage_Customer_Model_Address */
11
+ /* @var $subscriber Mage_Newsletter_Model_Subscriber */
12
+ /* @var $emailVisionApi Auguria_EmailVision_Model_Emailvision_Api */
13
+ /* @var $dateModel Mage_Core_Model_Date */
14
+ class Emv_DataSync_Model_Observer
15
+ {
16
+ const DEFAULT_STORE_CODE = 'admin';
17
+ const XML_PATH_EMAILVISION_OBSERVER_ENABLED = 'emvdatasync/apimember/enabled';
18
+
19
+ protected $_instanciationTime;
20
+
21
+ protected $_customerHasDataChanged = array();
22
+ protected $_subscriberSaved = array();
23
+
24
+ /**
25
+ * Customer newsletter subscriber
26
+ *
27
+ * @var array
28
+ */
29
+ protected $_customerNewsletter = array();
30
+
31
+ /**
32
+ * Constructor, register $this instanciation datetime
33
+ */
34
+ public function __construct()
35
+ {
36
+ // date time will be in GMT timezone
37
+ $this->_instanciationTime = Mage::helper('emvdatasync')->getFormattedGmtDateTime(null);
38
+ }
39
+
40
+ /**
41
+ * Method triggered on subscriber delete. Will always unjoin customer
42
+ *
43
+ * @param Varien_Event_Observer $observer
44
+ */
45
+ public function onSubscriberDelete(Varien_Event_Observer $observer)
46
+ {
47
+ if (Mage::getStoreConfigFlag(self::XML_PATH_EMAILVISION_OBSERVER_ENABLED)) {
48
+ $subscriber = $observer->getSubscriber();
49
+ // Direct unjoin (subscriber will be deleted on customer delete)
50
+ if ($subscriber->getId()) {
51
+ try {
52
+ $account = Mage::helper('emvdatasync')->getEmvAccountForStore();
53
+ $service = Mage::getModel('emvdatasync/service_member');
54
+ $service->setAccount($account);
55
+ $service->unjoinOneSubscriber($subscriber);
56
+ } catch (Exception $e) {
57
+ Mage::logException($e);
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+ /**
64
+ * Method triggered on customer_address save. Reset the data last update date to now if hasDataChanges and
65
+ * if a corresponding subscriber exists
66
+ *
67
+ * @param Varien_Event_Observer $observer
68
+ */
69
+ public function onCustomerAddressSave(Varien_Event_Observer $observer)
70
+ {
71
+ // If address is a billing one and has data changes, else nothing to do (avoid loading customer and subscriber)
72
+ $customerAddress = $observer->getCustomerAddress();
73
+ if ($customerAddress->getIsDefaultBilling() && $customerAddress->hasDataChanges()) {
74
+ $customer = $customerAddress->getCustomer();
75
+ $subscriber = $this->getSubscriberFromCustomer($customer);
76
+
77
+ // If a subscriber is linked to this address' customer, update last data changes date
78
+ if (
79
+ $subscriber && $subscriber->getId()
80
+ && $subscriber->getStatus() == Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED
81
+ ) {
82
+ $this->setCustomerHasDataChanged($subscriber->getId());
83
+ }
84
+ }
85
+ }
86
+
87
+ /**
88
+ * @param string $subscriberId
89
+ * @return Emv_DataSync_Model_Observer
90
+ */
91
+ public function setCustomerHasDataChanged($subscriberId)
92
+ {
93
+ $this->_customerHasDataChanged[$subscriberId] = true;
94
+ return $this;
95
+ }
96
+
97
+ /**
98
+ * @param string $subscriberId
99
+ * @return boolean
100
+ */
101
+ public function customerHasDataChanged($subscriberId)
102
+ {
103
+ return isset($this->_customerHasDataChanged[$subscriberId])
104
+ ? $this->_customerHasDataChanged[$subscriberId] : false;
105
+ }
106
+
107
+ /**
108
+ * Get subscriber from customer
109
+ *
110
+ * @param Mage_Customer_Model_Customer $customer
111
+ * @return Mage_Newsletter_Model_Subscriber | boolean
112
+ */
113
+ public function getSubscriberFromCustomer(Mage_Customer_Model_Customer $customer)
114
+ {
115
+ $customerId = $customer->getId();
116
+
117
+ if ($customerId) {
118
+ if (!isset($this->_customerNewsletter[$customerId])) {
119
+ $this->_customerNewsletter[$customerId] =
120
+ Mage::getModel('newsletter/subscriber')->loadByCustomer($customer);
121
+ }
122
+
123
+ return $this->_customerNewsletter[$customerId];
124
+ }
125
+
126
+ return false;
127
+ }
128
+
129
+ /**
130
+ * Method triggered on customer save. Reset the data last update date to now if hasDataChanges and if a
131
+ * corresponding subscriber exists
132
+ *
133
+ * @param Varien_Event_Observer $observer
134
+ */
135
+ public function onCustomerSave(Varien_Event_Observer $observer)
136
+ {
137
+ $customer = $observer->getCustomer();
138
+ $subscriber = $this->getSubscriberFromCustomer($customer);
139
+
140
+ if ($subscriber && $subscriber->getId()) {
141
+ // Prevent multiple calls on a Mage::app instance
142
+ if (!$this->subscriberSaved($subscriber->getId())) {
143
+ if (
144
+ $subscriber->getStatus() == Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED
145
+ && $customer->hasDataChanges()
146
+ ) {
147
+ $this->setCustomerHasDataChanged($subscriber->getId());
148
+ }
149
+ }
150
+ }
151
+ }
152
+
153
+ /**
154
+ * @param string $subscriberId
155
+ * @return Emv_DataSync_Model_Observer
156
+ */
157
+ public function setSubscriberSaved($subscriberId)
158
+ {
159
+ $this->_subscriberSaved[$subscriberId] = true;
160
+ return $this;
161
+ }
162
+
163
+ /**
164
+ * @param string $subscriberId
165
+ * @return boolean
166
+ */
167
+ public function subscriberSaved($subscriberId)
168
+ {
169
+ return isset($this->_subscriberSaved[$subscriberId]) ? $this->_subscriberSaved[$subscriberId] : false;
170
+ }
171
+
172
+ /**
173
+ * Method called on subscriber save. Call submethods if required. New subscribers will
174
+ * always have the return of getIsStatusChanged method setted to 1.
175
+ *
176
+ * @param Varien_Event_Observer $observer
177
+ */
178
+ public function onSubscriberSave(Varien_Event_Observer $observer)
179
+ {
180
+ $subscriber = $observer->getSubscriber();
181
+ if (!$subscriber->getId()) {
182
+ return false;
183
+ }
184
+
185
+ // Prevent multiple calls on a Mage::app instance
186
+ if (!$this->subscriberSaved($subscriber->getId())) {
187
+ if (
188
+ $subscriber->getStatus() == Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED
189
+ && ($this->customerHasDataChanged($subscriber->getId()) || $this->isSubscriberStatusChanged($subscriber))
190
+ ) {
191
+ $this->_updateDataLastUpdateDate($subscriber);
192
+ } elseif (
193
+ $subscriber->getStatus() == Mage_Newsletter_Model_Subscriber::STATUS_UNSUBSCRIBED
194
+ && $this->isSubscriberStatusChanged($subscriber)
195
+ ) {
196
+ $this->updateUnjoinDate($subscriber, false);
197
+
198
+ // A rare case: when unsubscribing a customer in back office with updates
199
+ if ($this->customerHasDataChanged($subscriber->getId())) {
200
+ $this->_updateDataLastUpdateDate($subscriber);
201
+ }
202
+ }
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Check whether newsletter subscriber status has been changed
208
+ *
209
+ * @param Mage_Newsletter_Model_Subscriber $subscriber
210
+ * @return boolean
211
+ */
212
+ public function isSubscriberStatusChanged(Mage_Newsletter_Model_Subscriber $subscriber)
213
+ {
214
+ $changed = false;
215
+ if ($subscriber->getSubscriberStatus() != $subscriber->getOrigData('subscriber_status')) {
216
+ $changed = true;
217
+ }
218
+
219
+ return $changed;
220
+ }
221
+
222
+ /**
223
+ * Update date_unjoin to able filtering on subscribers collections
224
+ *
225
+ * @param Mage_Newsletter_Model_Subscriber $subscriber
226
+ * @param boolean $isRejoining
227
+ */
228
+ protected function updateUnjoinDate(Mage_Newsletter_Model_Subscriber $subscriber, $isRejoining = false)
229
+ {
230
+ // Prevent infinite loops and multiple calls on a Mage::app instance
231
+ $this->setSubscriberSaved($subscriber->getId());
232
+
233
+ $dateUnjoin = $this->_instanciationTime;
234
+ if ($isRejoining) {
235
+ $dateUnjoin = null;
236
+ }
237
+
238
+ $subscriber->setData('date_unjoin', $dateUnjoin);
239
+ $subscriber->save();
240
+ }
241
+
242
+ /**
243
+ * Update data_last_update_date to able filtering on subscribers collections
244
+ *
245
+ * @param Mage_Newsletter_Model_Subscriber $subscriber
246
+ */
247
+ protected function _updateDataLastUpdateDate(Mage_Newsletter_Model_Subscriber $subscriber)
248
+ {
249
+ // Prevent infinite loops and multiple calls on a Mage::app instance
250
+ $this->setSubscriberSaved($subscriber->getId());
251
+
252
+ $subscriber->setData('data_last_update_date', $this->_instanciationTime);
253
+ $subscriber->save();
254
+ }
255
+ }
256
+
app/code/community/Emv/DataSync/Model/Service/BatchMember.php ADDED
@@ -0,0 +1,443 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Batch Member service - Handle Member Data
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_DataSync_Model_Service_BatchMember extends Emv_Core_Model_Service_BatchMember
11
+ {
12
+ /**
13
+ * XML config path for performance config
14
+ */
15
+ const XML_PATH_PERFORMANCE = 'emvcore/batchmember/performance';
16
+
17
+ /**
18
+ * The default limit of subscribers to get
19
+ */
20
+ const PAGE_SIZE = 10000;
21
+
22
+ /**
23
+ * Waiting time between each status checking call
24
+ */
25
+ const WAITING_TIME = 60;
26
+
27
+ /**
28
+ * @var boolean
29
+ */
30
+ protected $_foldersAreChecked = false;
31
+
32
+ /**
33
+ * @var string
34
+ */
35
+ protected $_currentTime = null;
36
+
37
+ // Subscribers collection management vars
38
+ protected $_pageSize;
39
+ protected $_pageCount;
40
+ protected $_curPage;
41
+
42
+ // Files and upload data
43
+ protected $_uploadId;
44
+ protected $_errors = array();
45
+ protected $_fileNamesToUpload = array();
46
+ protected $_fileNamesUploaded = array();
47
+
48
+ /**
49
+ * Mapped headers
50
+ * @var array
51
+ */
52
+ protected $_mappedHeaders = array();
53
+
54
+ /**
55
+ * Subscriber data list
56
+ * @var array
57
+ */
58
+ protected $_subscriberDataList = array();
59
+
60
+ /**
61
+ * List of subscriber ids per file
62
+ * @var array
63
+ */
64
+ protected $_writtenSubscribersIds = array();
65
+
66
+ /**
67
+ * (non-PHPdoc)
68
+ * @see Varien_Object::_construct()
69
+ */
70
+ public function _construct()
71
+ {
72
+ $this->_pageSize = Mage::getStoreConfig(self::XML_PATH_PERFORMANCE);
73
+ // avoid division by zero
74
+ if (!$this->_pageSize) {
75
+ $this->_pageSize = self::PAGE_SIZE;
76
+ }
77
+
78
+ // everything should be in GMT
79
+ $this->_currentTime = Mage::getModel('core/date')->gmtDate('Ymd_H-i-s');
80
+
81
+ return parent::_construct();
82
+ }
83
+
84
+ /**
85
+ * Prepare customer csv files for upload
86
+ */
87
+ public function prepareCustomerCsvFiles()
88
+ {
89
+ $mappedHeaders = $this->prepareAndGetMappedHeaders();
90
+
91
+ $subscribers = $this->getSubscriberCollection();
92
+ $totalSubscribersCount = $subscribers->getSize();
93
+ $this->_pageCount = ceil($subscribers->getSize() / $this->_pageSize);
94
+
95
+ if ($subscribers->getSize() > 0) {
96
+ // Add all customer and address attributes that have been mapped into collection
97
+ Mage::helper('emvdatasync/service')->addCustomerAndAddressAttributes($subscribers);
98
+
99
+ // Get all stores
100
+ $stores = Mage::app()->getStores(true);
101
+
102
+ // Get mapped EmailVision entity id
103
+ $entityId = strtoupper(Mage::helper('emvdatasync')->getMappedEntityId());
104
+
105
+ // Get api service corresponding to current account
106
+ $service = $this->getApiService($this->getAccount());
107
+
108
+ for ($this->_curPage = 1; $this->_curPage <= $this->_pageCount; $this->_curPage++) {
109
+ // Define current page
110
+ $subscribers->clear()
111
+ ->setPageSize($this->_pageSize)
112
+ ->setCurPage($this->_curPage);
113
+
114
+ // Add a row foreach customer
115
+ $preparedData = array();
116
+ foreach ($subscribers as $subscriber) {
117
+ // Replace customer email by suscriber one
118
+ $subscriber->setData('email', $subscriber->getSubscriberEmail());
119
+
120
+ // Prepare and add a customer's data row
121
+ $subscriberData = array();
122
+
123
+ // retreive all maped attribute values from subscriber, build them into array
124
+ $entityFieldsToSelect = Mage::helper('emvdatasync/service')->prepareAndGetMappedCustomerAttributes();
125
+ foreach ($entityFieldsToSelect as $attribute) {
126
+ $emailVisionKey = strtoupper($attribute->getEmailVisionKey());
127
+
128
+ $fieldCode = ($attribute->getFinalAttributeCode())
129
+ ? $attribute->getFinalAttributeCode() : $attribute->getAttributeCode();
130
+ $fieldValue = '';
131
+
132
+ if ($attribute->getFrontendInput() == 'date') {
133
+ if ($subscriber->getData($fieldCode)) {
134
+ // date time should be in EmailVision format
135
+ $fieldValue = Mage::helper('emvdatasync/service')
136
+ ->getEmailVisionDate($subscriber->getData($fieldCode));
137
+ }
138
+ } else {
139
+ $fieldValue = $subscriber->getData($fieldCode);
140
+ if ($fieldCode == 'store_id' && isset($stores[$fieldValue])) {
141
+ $fieldValue = $stores[$fieldValue]->getName();
142
+ }
143
+ }
144
+
145
+ $subscriberData[$emailVisionKey] = $fieldValue;
146
+ }
147
+
148
+ // entity id field
149
+ $subscriberData[$entityId] = $subscriber->getId();
150
+
151
+ // If is unjoined
152
+ $unjoinedDate = '';
153
+ if ($subscriber->getData('subscriber_status') == Mage_Newsletter_Model_Subscriber::STATUS_UNSUBSCRIBED) {
154
+ if ($subscriber->getData('date_unjoin')) {
155
+ // date time should be in EmailVision format
156
+ $unjoinedDate = Mage::helper('emvdatasync/service')
157
+ ->getEmailVisionDate($subscriber->getData('date_unjoin'));
158
+ }
159
+ }
160
+ $subscriberData[strtoupper(Emv_Core_Model_Service_Member::FIELD_UNJOIN)] = $unjoinedDate;
161
+ $preparedData[] = array(
162
+ 'id' => $subscriber->getId(),
163
+ 'fields' => $subscriberData
164
+ );
165
+
166
+ // add subscriber data into array
167
+ $tempSubscriber = array(
168
+ 'id' => $subscriber->getId(),
169
+ 'rejoined' => false
170
+ );
171
+ if ($subscriber->getData('subscriber_status') == Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED) {
172
+ if ($subscriber->getData('date_unjoin') != '' && $subscriber->getData('date_unjoin') != null) {
173
+ $tempSubscriber['rejoined'] = true;
174
+ }
175
+ }
176
+ $this->_subscriberDataList[$subscriber->getId()] = $tempSubscriber;
177
+ }// end foreach subscribers
178
+
179
+ try {
180
+ $csvFileData = $service->createCsvFiles(
181
+ $this,
182
+ array_keys($mappedHeaders),
183
+ $preparedData
184
+ );
185
+
186
+ foreach ($csvFileData as $data) {
187
+ // member list for each file
188
+ $this->_writtenSubscribersIds[$data['file']['filename']] = $data['list_member'];
189
+ $this->_fileNamesToUpload[] = $data['file'];
190
+ }
191
+ } catch (Exception $e) {
192
+ Mage::logException($e);
193
+
194
+ $this->_errors[] = 'Exception while building csv file, with message: ' . $e->getMessage();
195
+ }
196
+ } // end foreach page
197
+ }
198
+ }
199
+
200
+ /**
201
+ * Get merge criteria for batch member api requests
202
+ *
203
+ * @return array
204
+ */
205
+ public function getMergeCriteriaForBatchMember()
206
+ {
207
+ if (Mage::helper('emvdatasync')->getEmailEnabled()) {
208
+ $mergeCriteria = array(strtoupper(Emv_Core_Model_Service_Member::FIELD_EMAIL));
209
+ } else {
210
+ $mergeCriteria = array(strtoupper(Mage::helper('emvdatasync')->getMappedEntityId()));
211
+ }
212
+ return $mergeCriteria;
213
+ }
214
+
215
+ /**
216
+ * Mass export customers using Batch member api
217
+ * @return boolean
218
+ */
219
+ public function massExportCustomers()
220
+ {
221
+ // create csv files
222
+ $this->prepareCustomerCsvFiles();
223
+
224
+ $mergeCriteria = $this->getMergeCriteriaForBatchMember();
225
+
226
+ // return
227
+ $uploadDone = true;
228
+
229
+ $exportedFileTime = Mage::helper('emvdatasync')->getFormattedGmtDateTime();
230
+
231
+ try {
232
+ // Get api service corresponding to current account
233
+ $service = $this->getApiService($this->getAccount());
234
+ foreach ($this->_fileNamesToUpload as $data) {
235
+ $mappedHeaders = $this->prepareAndGetMappedHeaders();
236
+
237
+ $this->_uploadId = $service->sendFileToWebservice(
238
+ $data,
239
+ $mappedHeaders,
240
+ $mergeCriteria,
241
+ false
242
+ );
243
+
244
+ // only checking upload status if we can have upload id
245
+ if ($this->_uploadId != false) {
246
+ $uploadProcessing = true;
247
+ // wait until SmartFocus platform completes processing uploaded file
248
+ // check status's upload for an interval self::WAITING_TIME
249
+ do {
250
+ sleep(self::WAITING_TIME);
251
+ // get status's upload
252
+ $uploadStatus = $service->getUploadStatus($this->_uploadId, false);
253
+
254
+ if (
255
+ in_array(
256
+ $uploadStatus['status'],
257
+ EmailVision_Api_BatchMemberService::getAccomplishedStatuses()
258
+ )
259
+ ) {
260
+ $uploadProcessing = false;
261
+ if (
262
+ $uploadStatus['status'] == EmailVision_Api_BatchMemberService::getStatusOkWithoutError()
263
+ ) {
264
+ $this->_fileNamesUploaded[] = $data['filename'];
265
+ } else {
266
+ $uploadDone = false;
267
+ $this->_errors[] = 'Error on while calling mass_export, uploading file '
268
+ . $data['filename'] . ", details returned from EmailVision: " . $uploadStatus['details'];
269
+ }
270
+ }
271
+ } while ($uploadProcessing);
272
+
273
+ // move uploaded file
274
+ $this->moveUploadedFile($data);
275
+ }
276
+ }
277
+ } catch (Exception $e) {
278
+ $uploadDone = false;
279
+ Mage::logException($e);
280
+
281
+ $this->_errors[] = "Exception while calling mass_export in file uploading process, with message: "
282
+ . $e->getMessage();
283
+ }
284
+
285
+ // Update all subscribersUpdateDate for files uploaded with success
286
+ $this->massSetMemberLastUpdateDate($exportedFileTime);
287
+
288
+ if ($service) {
289
+ try {
290
+ $service->closeApiConnection();
291
+ } catch (Exception $e) {
292
+ Mage::logException($e);
293
+ $this->_errors[] = "Exception while closing SmartFocus service with message : "
294
+ . $e->getMessage();
295
+ }
296
+ }
297
+
298
+ return $uploadDone;
299
+ }
300
+
301
+ /**
302
+ * @param string $index
303
+ * @param array $memberData
304
+ * @return array
305
+ * - filename
306
+ * - path => the absolute path to the file
307
+ * - time => time is used to create file name
308
+ */
309
+ public function prepareFileName($index, $memberData = array())
310
+ {
311
+ // If flag is setted to false, check have not been done for current action
312
+ if (!$this->_foldersAreChecked) {
313
+ // Check whether dirs exist, if not create them
314
+ $helper = Mage::helper('emvdatasync');
315
+ $helper->checkAndCreatFolder();
316
+
317
+ $this->_foldersAreChecked = true;
318
+ }
319
+
320
+ // Preparing filename
321
+ $filename = 'customers' . $this->_currentTime . '_part' . $index . '.csv';
322
+
323
+ // Preparing file path
324
+ $path = Mage::getBaseDir('export') . DS . 'emailvision' . DS . $filename;
325
+ return array('filename' => $filename, 'path' => $path, 'time' => $this->_currentTime);
326
+ }
327
+
328
+ /**
329
+ * Set member last update date for all updated subscribers
330
+ */
331
+ public function massSetMemberLastUpdateDate()
332
+ {
333
+ $subscribersIds = array();
334
+ $rejoinedIds = array();
335
+
336
+ // Cases: mass export will have a _fileNamesUploaded set, member export will have _subsciberIds
337
+ if (!empty($this->_fileNamesUploaded)) {
338
+ foreach ($this->_fileNamesUploaded as $fileName) {
339
+ if (isset($this->_writtenSubscribersIds[$fileName])) {
340
+ foreach ($this->_writtenSubscribersIds[$fileName] as $subscriberId) {
341
+ $subscribersIds[] = $subscriberId;
342
+ if (
343
+ isset($this->_subscriberDataList[$subscriberId])
344
+ && $this->_subscriberDataList[$subscriberId]['rejoined'] == true
345
+ ) {
346
+ $rejoinedIds[] = $subscriberId;
347
+ }
348
+
349
+ }
350
+ }
351
+ }
352
+
353
+ try {
354
+ $errorMessage = Mage::helper('emvdatasync/service')->massSetMemberLastUpdateDate($subscribersIds, $rejoinedIds);
355
+ if ($errorMessage !== true) {
356
+ $this->_errors[] = $errorMessage;
357
+ }
358
+ } catch (Exception $e) {
359
+ Mage::logException($e);
360
+ }
361
+ }
362
+ }
363
+
364
+ /**
365
+ * @param array $file
366
+ * @return boolean
367
+ */
368
+ public function moveUploadedFile($file)
369
+ {
370
+ return @rename(
371
+ $file['path'],
372
+ Mage::getBaseDir('export'). DS . 'emailvision' . DS . 'uploaded' . DS . $file['filename']
373
+ );
374
+ }
375
+
376
+ /**
377
+ * @return Mage_Newsletter_Model_Resource_Subscriber_Collection
378
+ */
379
+ public function getSubscriberCollection()
380
+ {
381
+ /* @var $subscribers Mage_Newsletter_Model_Resource_Subscriber_Collection */
382
+ // Get all subscribers that have data modifed since the last sync as well as the unsubscribed ones
383
+ $subscribers = Mage::getModel('newsletter/subscriber')->getCollection();
384
+
385
+ $fieldMemberLastUpdate = Emv_DataSync_Helper_Service::FIELD_MEMBER_LAST_UPDATE;
386
+ $fieldUnjoin = Emv_DataSync_Helper_Service::FIELD_DATE_UNJOIN;
387
+ $fieldDataLastUpdate = Emv_DataSync_Helper_Service::FIELD_DATA_LAST_UPDATE;
388
+
389
+ $select = $subscribers->getSelect();
390
+ // in the case of member_last_update is not null
391
+ // - data_last_update_date > member_last_update => member data has been changed
392
+ // - main_table.date_unjoin > member_last_update => member has just unjoined
393
+ $notNullMemberCond = "main_table.{$fieldMemberLastUpdate} IS NOT NULL"
394
+ . " AND ( main_table.{$fieldDataLastUpdate} > main_table.{$fieldMemberLastUpdate}"
395
+ . " OR main_table.{$fieldUnjoin} > main_table.{$fieldMemberLastUpdate}"
396
+ . ' )';
397
+ $select->where($notNullMemberCond);
398
+ $select->orWhere("main_table.{$fieldMemberLastUpdate} IS NULL");
399
+
400
+ return $subscribers;
401
+ }
402
+
403
+ /**
404
+ * @return array
405
+ */
406
+ public function prepareAndGetMappedHeaders()
407
+ {
408
+ if ($this->_mappedHeaders == null) {
409
+ $this->_mappedHeaders = array();
410
+
411
+ // retreive all maped attribute values from subscriber, build them into array
412
+ $entityFieldsToSelect = Mage::helper('emvdatasync/service')->prepareAndGetMappedCustomerAttributes();
413
+ foreach ($entityFieldsToSelect as $attribute) {
414
+ $emailVisionKey = $attribute->getEmailVisionKey();
415
+ $emailVisionKey = strtoupper($emailVisionKey);
416
+
417
+ $this->_mappedHeaders[strtoupper($emailVisionKey)] = array(
418
+ 'to_replace' => true
419
+ );
420
+ }
421
+
422
+ // the entity id can not be replaced
423
+ $entityIdField = Mage::helper('emvdatasync')->getMappedEntityId();
424
+ $this->_mappedHeaders[strtoupper($entityIdField)] = array(
425
+ 'to_replace' => false
426
+ );
427
+
428
+ $this->_mappedHeaders[strtoupper(Emv_Core_Model_Service_Member::FIELD_UNJOIN)] = array(
429
+ 'to_replace' => true
430
+ );
431
+ }
432
+
433
+ return $this->_mappedHeaders;
434
+ }
435
+
436
+ /**
437
+ * @return array
438
+ */
439
+ public function getErrors()
440
+ {
441
+ return $this->_errors;
442
+ }
443
+ }
app/code/community/Emv/DataSync/Model/Service/Member.php ADDED
@@ -0,0 +1,337 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Member service - Handle Member Data
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Core
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
11
+ {
12
+ protected $_subscribersIdsUpdated = array();
13
+ protected $_subscribersIdsUnjoined = array();
14
+ protected $_subscribersIdsRejoined = array();
15
+
16
+ protected $_errors = array();
17
+
18
+ /**
19
+ * This method will get subscribers that require data update to EmailVision platform
20
+ * and manage the api calls in order to insert or update the data
21
+ *
22
+ * @return Array $_subscribersIdsUpdated An array contains the subscribers ids updated with success
23
+ */
24
+ public function exportSubscribers()
25
+ {
26
+ $size = false;
27
+ try {
28
+ // Subscribers that never have been sync || that have been update more recently than their last sync
29
+ $subscribers = Mage::getModel('newsletter/subscriber')->getCollection()
30
+ ->addFieldToFilter('main_table.' . Emv_DataSync_Helper_Service::FIELD_MEMBER_LAST_UPDATE,
31
+ array(
32
+ array('null'=> true),
33
+ array('lt'=> new Zend_Db_Expr('main_table.' . Emv_DataSync_Helper_Service::FIELD_DATA_LAST_UPDATE))
34
+ )
35
+ )
36
+ ->addFieldToFilter(
37
+ 'main_table.subscriber_status',
38
+ array(
39
+ array('eq' => Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED)
40
+ )
41
+ );
42
+ $size = $subscribers->getSize();
43
+ if ($size) {
44
+ // Add all customer and address attributes that have been mapped into collection
45
+ Mage::helper('emvdatasync/service')->addCustomerAndAddressAttributes($subscribers);
46
+ }
47
+ } catch (Exception $e) {
48
+ Mage::logException($e);
49
+ $this->_errors[] = 'Exception while retreiving data for subscribers to insert or update with message: ' . $e->getMessage();
50
+ }
51
+
52
+ if ($size) {
53
+ foreach ($subscribers as $subscriber) {
54
+ try {
55
+ $this->_insertOrUpdateMember($subscriber);
56
+ } catch (Exception $e) {
57
+ Mage::logException($e);
58
+
59
+ $this->_errors[] = 'Exception while preparing data to call insertOrUpdateMemberByObj, for subscriber '
60
+ . $subscriber->getId() . ' with message: ' . $e->getMessage();
61
+ }
62
+ }
63
+ }
64
+
65
+ return $this->_subscribersIdsUpdated;
66
+ }
67
+
68
+ /**
69
+ * Get merge criteria for member api.
70
+ * It can be email or entity id
71
+ *
72
+ * @param Mage_Newsletter_Model_Subscriber $subscriber
73
+ * @return array
74
+ */
75
+ public function getMergeCriteriaForMember(Mage_Newsletter_Model_Subscriber $subscriber)
76
+ {
77
+ if (Mage::helper('emvdatasync')->getEmailEnabled()) {
78
+ $mergeCriteria = array(strtoupper(Emv_Core_Model_Service_Member::FIELD_EMAIL) => $subscriber->getEmail());
79
+ } else {
80
+ $mergeCriteria = array(
81
+ strtoupper(Mage::helper('emvdatasync')->getMappedEntityId()) => $subscriber->getId()
82
+ );
83
+ }
84
+ return $mergeCriteria;
85
+ }
86
+
87
+
88
+ /**
89
+ * Method to call insert or update on subscriber passed as param
90
+ *
91
+ * @param Mage_Newsletter_Model_Subscriber $subscriber Subscriber to insert
92
+ * @param boolean $closeApi
93
+ *
94
+ * @return string | boolean $result The soap call result
95
+ */
96
+ protected function _insertOrUpdateMember(Mage_Newsletter_Model_Subscriber $subscriber, $closeApi = false)
97
+ {
98
+ $params = array();
99
+
100
+ // Replace customer email by suscriber one
101
+ $subscriber->setData('email', $subscriber->getSubscriberEmail());
102
+
103
+ // retreive all maped attribute values from subscriber, build them into array
104
+ $entityFieldsToSelect = Mage::helper('emvdatasync/service')->prepareAndGetMappedCustomerAttributes();
105
+ if ($entityFieldsToSelect && $entityFieldsToSelect->count() > 0) {
106
+ // get list of all available stores
107
+ $stores = Mage::app()->getStores(true);
108
+
109
+ foreach($entityFieldsToSelect as $attribute) {
110
+ $emailVisionKey = $attribute->getEmailVisionKey();
111
+ $emailVisionKey = strtoupper($emailVisionKey);
112
+
113
+ $fieldCode = ($attribute->getFinalAttributeCode())
114
+ ? $attribute->getFinalAttributeCode() : $attribute->getAttributeCode();
115
+
116
+ $fieldValue = '';
117
+
118
+ if ($attribute->getFrontendInput() == 'date') {
119
+ if ($subscriber->getData($fieldCode)) {
120
+ // date time should be in EmailVision format
121
+ $fieldValue = Mage::helper('emvdatasync/service')
122
+ ->getEmailVisionDate($subscriber->getData($fieldCode));
123
+ }
124
+ } else {
125
+ $fieldValue = $subscriber->getData($fieldCode);
126
+ if ($fieldCode == 'store_id' && isset($stores[$fieldValue])) {
127
+ // get store code
128
+ $fieldValue = $stores[$fieldValue]->getCode();
129
+ }
130
+ }
131
+
132
+ $params[$emailVisionKey] = $fieldValue;
133
+ }
134
+
135
+ // entity id
136
+ $params[strtoupper(Mage::helper('emvdatasync')->getMappedEntityId())] = $subscriber->getId();
137
+ }
138
+
139
+ // make api call with all prepared array (mapped attributes and criteria)
140
+ try {
141
+ $uploadId = null;
142
+ $service = $this->getApiService($this->getAccount());
143
+ $uploadId = $service->insertOrUpdateMemberByObj(
144
+ $this->getMergeCriteriaForMember($subscriber),
145
+ $params,
146
+ $closeApi
147
+ );
148
+
149
+ $this->_subscribersIdsUpdated[] = $subscriber->getId();
150
+ } catch (Exception $e) {
151
+ Mage::logException($e);
152
+
153
+ $this->_errors[] = 'Exception while calling insertOrUpdateMemberByObj for subscriber '
154
+ . $subscriber->getId() . ' with message: ' . $e->getMessage();
155
+ }
156
+
157
+ return $uploadId;
158
+ }
159
+
160
+ /**
161
+ * Unjoin all unsubscribed members from EmailVision platform
162
+ *
163
+ * @param boolean $closeApi
164
+ * @return Array $_subscribersIdsUnjoined An array containing the subscribers ids unjoined with success
165
+ */
166
+ public function unjoinSubscribers()
167
+ {
168
+ try {
169
+ // Subscribers that have unjoined more recently than their last sync
170
+ $subscribers = Mage::getModel('newsletter/subscriber')->getCollection()
171
+ ->addFieldToFilter(
172
+ 'main_table.' . Emv_DataSync_Helper_Service::FIELD_DATE_UNJOIN,
173
+ array(
174
+ array('gt' => new Zend_Db_Expr('main_table.' . Emv_DataSync_Helper_Service::FIELD_MEMBER_LAST_UPDATE))
175
+ )
176
+ )
177
+ ->addFieldToFilter(
178
+ 'main_table.subscriber_status',
179
+ array(
180
+ array('eq' => Mage_Newsletter_Model_Subscriber::STATUS_UNSUBSCRIBED),
181
+ )
182
+ );
183
+ $subscribers->load();
184
+ } catch (Exception $e) {
185
+ Mage::logException($e);
186
+ $this->_errors[] = 'Exception while retreiving data for subscribers to unjoin with message: ' . $e->getMessage();
187
+ }
188
+
189
+ foreach ($subscribers as $subscriber) {
190
+ try {
191
+ $this->unjoinOneSubscriber($subscriber, false);
192
+
193
+ $this->_subscribersIdsUnjoined[] = $subscriber->getId();
194
+ } catch (Exception $e) {
195
+ Mage::logException($e);
196
+ $this->_errors[] = 'Exception while preparing data to call unjoin, for subscriber '
197
+ . $subscriber->getId() . " with message: " . $e->getMessage();
198
+ }
199
+ }
200
+
201
+ return $this->_subscribersIdsUnjoined;
202
+ }
203
+
204
+ /**
205
+ * Unjoin member from EmailVision platform
206
+ *
207
+ * @param Mage_Newsletter_Model_Subscriber $subscriber
208
+ * @param boolean $closeApi
209
+ * @return Emv_DataSync_Model_Service_Member
210
+ */
211
+ public function unjoinOneSubscriber(Mage_Newsletter_Model_Subscriber $subscriber, $closeApi = true)
212
+ {
213
+ if ($subscriber->getId()) {
214
+ $service = $this->getApiService($this->getAccount());
215
+ $service->unjoinMember('object', $this->getMergeCriteriaForMember($subscriber), $closeApi);
216
+ }
217
+
218
+ return $this;
219
+ }
220
+
221
+ /**
222
+ * Rejoin subscribers to EmailVision platform
223
+ * (subscribers that change their status from unsubscribed to subscribe)
224
+ *
225
+ * @param boolean $closeApi
226
+ * @return Array $_subscribersIdsRejoined An array containing the subscribers ids rejoined with success
227
+ */
228
+ public function rejoinSubscribers($closeApi = false)
229
+ {
230
+ try {
231
+ // Subscribers which have last sync more recently than unjoin && that are subscribed
232
+ $subscribers = Mage::getModel('newsletter/subscriber')->getCollection()
233
+ ->addFieldToFilter(
234
+ 'main_table.' . Emv_DataSync_Helper_Service::FIELD_DATE_UNJOIN, array(
235
+ array('lteq'=> new Zend_Db_Expr('main_table.' . Emv_DataSync_Helper_Service::FIELD_DATA_LAST_UPDATE)),
236
+ ))
237
+ ->addFieldToFilter(
238
+ 'main_table.subscriber_status', array(
239
+ array('eq'=> Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED),
240
+ ));
241
+
242
+ $subscribers->load();
243
+ } catch (Exception $e) {
244
+ Mage::logException($e);
245
+ $this->_errors[] = 'Exception while retreiving data for subscribers to rejoin with message: ' . $e->getMessage();
246
+ }
247
+
248
+ $service = $this->getApiService($this->getAccount());
249
+
250
+ foreach ($subscribers as $subscriber) {
251
+ try {
252
+ $memberId = false;
253
+
254
+ $list = $service->getListMembersByObj(
255
+ $this->getMergeCriteriaForMember($subscriber),
256
+ $closeApi
257
+ );
258
+ if (count($list) == 1) {
259
+ foreach ($list[0] as $key => $value) {
260
+ if ($key == Emv_Core_Model_Service_Member::FIELD_MEMBER_ID) {
261
+ $memberId = $value;
262
+ }
263
+ }
264
+ }
265
+ if ($memberId) {
266
+ $service->rejoinMember('id', $memberId, $closeApi);
267
+ $this->_subscribersIdsRejoined[] = $subscriber->getId();
268
+ }
269
+ } catch (Exception $e) {
270
+ Mage::logException($e);
271
+ $this->_errors[] = 'Exception while preparing data to call rejoin, for subscriber '
272
+ . $subscriber->getId() . ' with message: ' . $e->getMessage();
273
+ }
274
+ }
275
+
276
+ return $this->_subscribersIdsRejoined;
277
+ }
278
+
279
+ /**
280
+ * @return array
281
+ */
282
+ public function getErrors()
283
+ {
284
+ return $this->_errors;
285
+ }
286
+
287
+ /**
288
+ * Method to set massively the custom member_last_update_date after a member or a batchmember export
289
+ */
290
+ public function massSetMemberLastUpdateDate()
291
+ {
292
+ $subscribersIds = array();
293
+ foreach ($this->_subscribersIdsUpdated as $subscriberId) {
294
+ $subscribersIds[] = $subscriberId;
295
+ }
296
+ foreach ($this->_subscribersIdsUnjoined as $subscriberId) {
297
+ $subscribersIds[] = $subscriberId;
298
+ }
299
+ foreach ($this->_subscribersIdsRejoined as $subscriberId) {
300
+ $subscribersIds[] = $subscriberId;
301
+ }
302
+ $subscribersIds = array_unique($subscribersIds);
303
+
304
+ try {
305
+ $errorMessage = Mage::helper('emvdatasync/service')->massSetMemberLastUpdateDate(
306
+ $subscribersIds,
307
+ $this->_subscribersIdsRejoined
308
+ );
309
+ if ($errorMessage !== true) {
310
+ $this->_errors[] = $errorMessage;
311
+ }
312
+ } catch (Exception $e) {
313
+ Mage::logException($e);
314
+ }
315
+ }
316
+
317
+ /**
318
+ * Trigger all process to update subscriber data (insert update, unjoin and rejoin)
319
+ */
320
+ public function triggerExport()
321
+ {
322
+ $this->exportSubscribers();
323
+ $this->unjoinSubscribers();
324
+ $this->rejoinSubscribers();
325
+
326
+ // Update memberLastUpdateDate
327
+ $this->massSetMemberLastUpdateDate();
328
+
329
+ try {
330
+ $this->getApiService($this->getAccount())->closeApiConnection();
331
+ } catch (Exception $e) {
332
+ Mage::logException($e);
333
+ $this->_errors[] = "Exception while closing SmartFocus service with message : "
334
+ . $e->getMessage();
335
+ }
336
+ }
337
+ }
app/code/community/Emv/DataSync/controllers/Adminhtml/DataSyncController.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Data Sync Controller
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_DataSync_Adminhtml_DataSyncController extends Mage_Adminhtml_Controller_Action
10
+ {
11
+ /**
12
+ * (non-PHPdoc)
13
+ * @see Mage_Core_Controller_Varien_Action::_construct()
14
+ */
15
+ public function _construct()
16
+ {
17
+ // Define module dependent translate
18
+ $this->setUsedModuleName('Emv_DataSync');
19
+ }
20
+
21
+ /**
22
+ * Get EmailVision fields from api object
23
+ */
24
+ public function getMemberFieldsAction()
25
+ {
26
+ $accountId = $this->getRequest()->getParam('account_id', null);
27
+ $preparedFields = array();
28
+
29
+ $account = Mage::getModel('emvcore/account');
30
+ if (!$accountId) {
31
+ $account = Mage::helper('emvdatasync')->getEmvAccountForStore();
32
+ } else {
33
+ $account->load($accountId);
34
+ }
35
+
36
+ // get account id for
37
+ if ($account->getId()) {
38
+ try {
39
+ $service = Mage::getModel('emvcore/service_member');
40
+ $service->setAccount($account);
41
+ $fields = $service->getEmailVisionFields();
42
+
43
+ $notAllowed = array(
44
+ Emv_Core_Model_Service_Member::FIELD_CLIENT_ID,
45
+ Emv_Core_Model_Service_Member::FIELD_MEMBER_ID,
46
+ Emv_Core_Model_Service_Member::FIELD_UNJOIN
47
+ );
48
+ foreach ($fields as $data) {
49
+ if (!in_array($data['name'], $notAllowed)) {
50
+ $preparedFields[] = $data;
51
+ }
52
+ }
53
+ } catch (Exception $e) {
54
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('emvdatasync')->__($e->getMessage()));
55
+ }
56
+ } else {
57
+ Mage::getSingleton('adminhtml/session')->addError(
58
+ Mage::helper('emvdatasync')
59
+ ->__('Please select an account for "Triggered Exports". Access to Member service is required')
60
+ );
61
+ }
62
+
63
+ if (count($preparedFields)) {
64
+ Mage::helper('emvdatasync')->saveEmailVisionFieldsInConfig($preparedFields);
65
+ // SmartFocus fields need to be in lower case
66
+ Mage::helper('emvdatasync')->saveMappedEntityId(
67
+ strtolower(Emv_Core_Model_Service_Member::FIELD_SUBSCRIBER_ID)
68
+ );
69
+
70
+ $config = Mage::getModel('core/config');
71
+ $config->removeCache();
72
+
73
+ Mage::getSingleton('adminhtml/session')->addSuccess(
74
+ Mage::helper('emvdatasync')->__('Retrieved successfully SmartFocus member fields')
75
+ );
76
+ }
77
+
78
+ $this->_redirect('adminhtml/system_config/edit/section/emvdatasync/');
79
+ }
80
+ }
81
+
app/code/community/Emv/DataSync/etc/adminhtml.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <admin>
6
+ <children>
7
+ <system>
8
+ <children>
9
+ <config>
10
+ <children>
11
+ <emvdatasync translate="title" module="emvdatasync">
12
+ <title>SmartFocus - Member Export Setting</title>
13
+ </emvdatasync>
14
+ </children>
15
+ </config>
16
+ </children>
17
+ </system>
18
+ </children>
19
+ </admin>
20
+ </resources>
21
+ </acl>
22
+ </config>
app/code/community/Emv/DataSync/etc/config.xml ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <Emv_DataSync>
5
+ <version>0.1.0</version>
6
+ </Emv_DataSync>
7
+ </modules>
8
+
9
+ <admin>
10
+ <routers>
11
+ <emvdatasync>
12
+ <use>admin</use>
13
+ <args>
14
+ <module>Emv_DataSync_Adminhtml</module>
15
+ <frontName>emv_datasync</frontName>
16
+ </args>
17
+ </emvdatasync>
18
+ </routers>
19
+ </admin>
20
+
21
+ <adminhtml>
22
+ <translate>
23
+ <modules>
24
+ <Emv_DataSync>
25
+ <files>
26
+ <default>Emv_DataSync.csv</default>
27
+ </files>
28
+ </Emv_DataSync>
29
+ </modules>
30
+ </translate>
31
+ </adminhtml>
32
+
33
+ <global>
34
+ <blocks>
35
+ <emvdatasync>
36
+ <class>Emv_DataSync_Block</class>
37
+ </emvdatasync>
38
+ </blocks>
39
+ <models>
40
+ <emvdatasync>
41
+ <class>Emv_DataSync_Model</class>
42
+ </emvdatasync>
43
+ </models>
44
+ <helpers>
45
+ <emvdatasync>
46
+ <class>Emv_DataSync_Helper</class>
47
+ </emvdatasync>
48
+ </helpers>
49
+ <resources>
50
+ <emvdatasync_setup>
51
+ <setup>
52
+ <module>Emv_DataSync</module>
53
+ </setup>
54
+ <connection>
55
+ <use>core_setup</use>
56
+ </connection>
57
+ </emvdatasync_setup>
58
+ <emvdatasync_write>
59
+ <connection>
60
+ <use>core_write</use>
61
+ </connection>
62
+ </emvdatasync_write>
63
+ <emvdatasync_read>
64
+ <connection>
65
+ <use>core_read</use>
66
+ </connection>
67
+ </emvdatasync_read>
68
+ </resources>
69
+ <events>
70
+ <!-- customer/customer -->
71
+ <customer_save_after>
72
+ <observers>
73
+ <emailvision_on_customer_save>
74
+ <type>singleton</type>
75
+ <class>emvdatasync/observer</class>
76
+ <method>onCustomerSave</method>
77
+ </emailvision_on_customer_save>
78
+ </observers>
79
+ </customer_save_after>
80
+ <!-- customer/customer_address -->
81
+ <customer_address_save_after>
82
+ <observers>
83
+ <emailvision_on_customer_address_save>
84
+ <type>singleton</type>
85
+ <class>emvdatasync/observer</class>
86
+ <method>onCustomerAddressSave</method>
87
+ </emailvision_on_customer_address_save>
88
+ </observers>
89
+ </customer_address_save_after>
90
+ <!-- newsletter/subscriber -->
91
+ <newsletter_subscriber_delete_after>
92
+ <observers>
93
+ <emailvision_on_subscriber_delete>
94
+ <type>singleton</type>
95
+ <class>emvdatasync/observer</class>
96
+ <method>onSubscriberDelete</method>
97
+ </emailvision_on_subscriber_delete>
98
+ </observers>
99
+ </newsletter_subscriber_delete_after>
100
+ <newsletter_subscriber_save_after>
101
+ <observers>
102
+ <emailvision_on_subscriber_save>
103
+ <type>singleton</type>
104
+ <class>emvdatasync/observer</class>
105
+ <method>onSubscriberSave</method>
106
+ </emailvision_on_subscriber_save>
107
+ </observers>
108
+ </newsletter_subscriber_save_after>
109
+ </events>
110
+ <template>
111
+ <email>
112
+ <emvdatasync_general_error_email_template translate="label" module="directory">
113
+ <label>EmailVision cron errors</label>
114
+ <file>emailvision/datasync/cron_errors.html</file>
115
+ <type>html</type>
116
+ </emvdatasync_general_error_email_template>
117
+ </email>
118
+ </template>
119
+ </global>
120
+
121
+ <crontab>
122
+ <jobs>
123
+ <emailvision_member_export>
124
+ <run>
125
+ <model>emvdatasync/cron::memberExport</model>
126
+ </run>
127
+ </emailvision_member_export>
128
+ <emailvision_batchmember_export>
129
+ <run>
130
+ <model>emvdatasync/cron::batchMemberExport</model>
131
+ </run>
132
+ </emailvision_batchmember_export>
133
+ <emailvision_clean>
134
+ <run>
135
+ <model>emvdatasync/cron::cleanEmailVisionFiles</model>
136
+ </run>
137
+ </emailvision_clean>
138
+ </jobs>
139
+ </crontab>
140
+
141
+ <default>
142
+ <emvdatasync>
143
+ <general>
144
+ <error_email_recipient>contact@domain.com</error_email_recipient>
145
+ <error_email_sender>general</error_email_sender>
146
+ <error_email_template>emvdatasync_batchmember_error_email_template</error_email_template>
147
+ </general>
148
+
149
+ <batchmember>
150
+ <performance>10000</performance>
151
+ <enabled>0</enabled>
152
+ </batchmember>
153
+
154
+ <last_successful_synchronization>
155
+ <customers></customers>
156
+ </last_successful_synchronization>
157
+ <customer_mapping>
158
+ <emailvision_entity_id>clienturn</emailvision_entity_id>
159
+ </customer_mapping>
160
+ </emvdatasync>
161
+ </default>
162
+ </config>
app/code/community/Emv/DataSync/etc/system.xml ADDED
@@ -0,0 +1,210 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <config>
2
+ <sections>
3
+ <emvdatasync translate="label" module="emvdatasync">
4
+ <label>Subscriber Export</label>
5
+ <tab>emailvision</tab>
6
+ <frontend_type>text</frontend_type>
7
+ <sort_order>30</sort_order>
8
+ <show_in_default>1</show_in_default>
9
+ <show_in_website>1</show_in_website>
10
+ <show_in_store>1</show_in_store>
11
+ <groups>
12
+ <general translate="label comment" module="emvdatasync">
13
+ <label>General</label>
14
+ <sort_order>10</sort_order>
15
+ <show_in_default>1</show_in_default>
16
+ <fields>
17
+ <error_email_recipient translate="label">
18
+ <label>Error Email Recipient</label>
19
+ <frontend_type>text</frontend_type>
20
+ <sort_order>50</sort_order>
21
+ <show_in_default>1</show_in_default>
22
+ </error_email_recipient>
23
+ <error_email_sender translate="label">
24
+ <label>Error Email Sender</label>
25
+ <frontend_type>select</frontend_type>
26
+ <source_model>adminhtml/system_config_source_email_identity</source_model>
27
+ <sort_order>60</sort_order>
28
+ <show_in_default>1</show_in_default>
29
+ </error_email_sender>
30
+ <error_email_template translate="label">
31
+ <label>Error Email Template</label>
32
+ <frontend_type>select</frontend_type>
33
+ <source_model>adminhtml/system_config_source_email_template</source_model>
34
+ <sort_order>70</sort_order>
35
+ <show_in_default>1</show_in_default>
36
+ </error_email_template>
37
+ </fields>
38
+ </general>
39
+
40
+ <apimember translate="label comment" module="emvdatasync">
41
+ <label>Triggered Export Settings</label>
42
+ <comment>Enable the automatic update of your members data with apimember (Member Service)</comment>
43
+ <sort_order>20</sort_order>
44
+ <show_in_default>1</show_in_default>
45
+ <fields>
46
+ <enabled translate="label">
47
+ <label>Enabled</label>
48
+ <frontend_type>select</frontend_type>
49
+ <source_model>adminhtml/system_config_source_yesno</source_model>
50
+ <backend_model>emvdatasync/adminhtml_system_config_backend_apiMember_enabled</backend_model>
51
+ <sort_order>1</sort_order>
52
+ <show_in_default>1</show_in_default>
53
+ </enabled>
54
+ <account translate="label">
55
+ <label>SmartFocus Account</label>
56
+ <frontend_type>select</frontend_type>
57
+ <source_model>emvcore/system_config_source_account</source_model>
58
+ <backend_model>emvdatasync/adminhtml_system_config_backend_apiMember_account</backend_model>
59
+ <sort_order>10</sort_order>
60
+ <show_in_default>1</show_in_default>
61
+ </account>
62
+ <frequency translate="label">
63
+ <label>Frequency</label>
64
+ <frontend_type>select</frontend_type>
65
+ <source_model>emvdatasync/adminhtml_system_config_source_memberCronTime</source_model>
66
+ <backend_model>emvdatasync/adminhtml_system_config_backend_apiMember_cron</backend_model>
67
+ <sort_order>20</sort_order>
68
+ <show_in_default>1</show_in_default>
69
+ </frequency>
70
+ </fields>
71
+ </apimember>
72
+
73
+ <batchmember translate="label comment" module="emvdatasync">
74
+ <label>Scheduled Export Settings</label>
75
+ <comment>Enable the automatic update of your members data with apibatchmember (Batch Member Service)</comment>
76
+ <frontend_type>text</frontend_type>
77
+ <sort_order>30</sort_order>
78
+ <show_in_default>1</show_in_default>
79
+ <fields>
80
+ <enabled translate="label">
81
+ <label>Enabled</label>
82
+ <frontend_type>select</frontend_type>
83
+ <source_model>adminhtml/system_config_source_yesno</source_model>
84
+ <backend_model>emvdatasync/adminhtml_system_config_backend_batchMember_enabled</backend_model>
85
+ <sort_order>1</sort_order>
86
+ <show_in_default>1</show_in_default>
87
+ </enabled>
88
+ <account translate="label">
89
+ <label>SmartFocus Account</label>
90
+ <frontend_type>select</frontend_type>
91
+ <source_model>emvcore/system_config_source_account</source_model>
92
+ <backend_model>emvdatasync/adminhtml_system_config_backend_batchMember_account</backend_model>
93
+ <sort_order>10</sort_order>
94
+ <show_in_default>1</show_in_default>
95
+ </account>
96
+ <frequency translate="label">
97
+ <label>Frequency</label>
98
+ <frontend_type>select</frontend_type>
99
+ <source_model>adminhtml/system_config_source_cron_frequency</source_model>
100
+ <sort_order>20</sort_order>
101
+ <show_in_default>1</show_in_default>
102
+ </frequency>
103
+ <time translate="label">
104
+ <label>Start Time (in Admin timezone)</label>
105
+ <frontend_type>time</frontend_type>
106
+ <backend_model>emvdatasync/adminhtml_system_config_backend_batchMember_cron</backend_model>
107
+ <sort_order>30</sort_order>
108
+ <show_in_default>1</show_in_default>
109
+ </time>
110
+ <performance translate="label comment">
111
+ <label>Max number of fetched members per page</label>
112
+ <comment>Allows you to reduce the number of members loaded while building file. Default value should be quite balanced, if your server has limited RAM resources, you can lower it until encountering no more troubles</comment>
113
+ <frontend_type>text</frontend_type>
114
+ <sort_order>40</sort_order>
115
+ <show_in_default>1</show_in_default>
116
+ </performance>
117
+ </fields>
118
+ </batchmember>
119
+
120
+ <export_file_cleaning translate="label comment" module="emvdatasync">
121
+ <label>Cleaning of generated files</label>
122
+ <comment>Note: When using scheduled exports, the module will generate csv files. It's recommended to enable the file cleaning to delete them regularly</comment>
123
+ <frontend_type>text</frontend_type>
124
+ <sort_order>40</sort_order>
125
+ <show_in_default>1</show_in_default>
126
+ <fields>
127
+ <enabled translate="label">
128
+ <label>Enabled</label>
129
+ <frontend_type>select</frontend_type>
130
+ <source_model>adminhtml/system_config_source_yesno</source_model>
131
+ <sort_order>1</sort_order>
132
+ <show_in_default>1</show_in_default>
133
+ </enabled>
134
+ <time translate="label">
135
+ <label>Start Time (in Admin timezone)</label>
136
+ <frontend_type>time</frontend_type>
137
+ <backend_model>emvdatasync/adminhtml_system_config_backend_clean_cron</backend_model>
138
+ <sort_order>3</sort_order>
139
+ <show_in_default>1</show_in_default>
140
+ </time>
141
+ <frequency translate="label">
142
+ <label>Frequency</label>
143
+ <frontend_type>select</frontend_type>
144
+ <source_model>adminhtml/system_config_source_cron_frequency</source_model>
145
+ <sort_order>4</sort_order>
146
+ <show_in_default>1</show_in_default>
147
+ </frequency>
148
+ </fields>
149
+ </export_file_cleaning>
150
+
151
+ <last_successful_synchronization translate="label" module="emvdatasync">
152
+ <label>Last Successful Synchronization</label>
153
+ <frontend_type>text</frontend_type>
154
+ <sort_order>60</sort_order>
155
+ <show_in_default>1</show_in_default>
156
+ <fields>
157
+ <customers translate="label">
158
+ <label>Scheduled Customer Export (in Admin timezone)</label>
159
+ <frontend_type>text</frontend_type>
160
+ <frontend_model>emvdatasync/adminhtml_system_config_date</frontend_model>
161
+ <sort_order>1</sort_order>
162
+ <show_in_default>1</show_in_default>
163
+ </customers>
164
+ </fields>
165
+ </last_successful_synchronization>
166
+
167
+ <customer_mapping module="emvdatasync">
168
+ <label>Attribute Mapping</label>
169
+ <frontend_type>text</frontend_type>
170
+ <sort_order>70</sort_order>
171
+ <show_in_default>1</show_in_default>
172
+ <fields>
173
+ <get_emailvision_fields translate="label comment">
174
+ <label>Field Synchronization</label>
175
+ <button_label>Run export</button_label>
176
+ <frontend_model>emvdatasync/adminhtml_system_config_getFields</frontend_model>
177
+ <comment>Connect to SmartFocus apimember webservice and get the list of available fields</comment>
178
+ <sort_order>1</sort_order>
179
+ <show_in_default>1</show_in_default>
180
+ </get_emailvision_fields>
181
+ <email_enabled translate="label">
182
+ <label>Synchronize with email</label>
183
+ <frontend_type>select</frontend_type>
184
+ <source_model>adminhtml/system_config_source_yesno</source_model>
185
+ <comment>If enabled, Magento newsletter subscribers will be synced by their email address. By default, the SmartFocus Entity Id will be used.</comment>
186
+ <sort_order>3</sort_order>
187
+ <show_in_default>1</show_in_default>
188
+ </email_enabled>
189
+ <emailvision_entity_id translate="label comment">
190
+ <label>SmartFocus Entity Id</label>
191
+ <frontend_type>select</frontend_type>
192
+ <source_model>emvdatasync/adminhtml_system_config_source_fields</source_model>
193
+ <comment>Default field used to link a Magento newsletter subscriber to a SmartFocus member. CLIENTURN is selected by default.</comment>
194
+ <sort_order>5</sort_order>
195
+ <show_in_default>1</show_in_default>
196
+ </emailvision_entity_id>
197
+ <attributes translate="comment">
198
+ <label></label>
199
+ <comment>Warning: SmartFocus fields must not be mapped more than one time, including the entity field id. You can map any Magento field with as many disctinct SmartFocus ones as you want</comment>
200
+ <frontend_model>emvdatasync/adminhtml_system_config_customerAttributes</frontend_model>
201
+ <backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
202
+ <sort_order>10</sort_order>
203
+ <show_in_default>1</show_in_default>
204
+ </attributes>
205
+ </fields>
206
+ </customer_mapping>
207
+ </groups>
208
+ </emvdatasync>
209
+ </sections>
210
+ </config>
app/code/community/Emv/DataSync/sql/emvdatasync_setup/mysql4-install-0.0.1.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $this->startSetup();
3
+
4
+ /* @var Varien_Db_Adapter_Pdo_Mysql $connection*/
5
+ $connection = $this->getConnection();
6
+
7
+ $connection->addColumn($this->getTable('newsletter_subscriber'), 'date_unjoin', 'DATETIME default NULL');
8
+ $connection->addColumn($this->getTable('newsletter_subscriber'), 'data_last_update_date', 'DATETIME default NULL');
9
+ $connection->addColumn($this->getTable('newsletter_subscriber'), 'member_last_update_date', 'DATETIME default NULL');
10
+
11
+ $this->endSetup();
12
+ ?>
app/code/community/Emv/Emt/Block/Adminhtml/Emt/Edit.php DELETED
@@ -1,38 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{9A8DC590-314F-402c-A1B5-45669D8D3DA0}
8
- */
9
- class Emv_Emt_Block_Adminhtml_Emt_Edit extends Mage_Adminhtml_Block_Widget_Form_Container
10
- {
11
-
12
- /**
13
- * opGUID{E35B4FB9-C0A2-4362-8A9C-9F73B3A95889}
14
- */
15
- public function __construct()
16
- {
17
- parent::__construct();
18
- $this->_blockGroup = 'emvemt';
19
- $this->_controller = 'adminhtml_emt';
20
- $this->_headerText = Mage::helper('emvemt')->__('Configure Campaign Commander Account');
21
-
22
- if(!Mage::getSingleton('admin/session')->isAllowed('emvemt/emt/delete'))
23
- {
24
- $this->removeButton('delete');
25
- }
26
- }
27
-
28
- /**
29
- * Retrieve text for header element depending on loaded page
30
- *
31
- * @return string
32
- */
33
- public function getHeaderText()
34
- {
35
- return Mage::helper('emvemt')->__("Edit %s Email",
36
- $this->htmlEscape(Mage::registry('mage_template_name')));
37
- }
38
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Emt/Block/Adminhtml/Emt/Edit/Attributes.php DELETED
@@ -1,83 +0,0 @@
1
- <?php
2
- class Emv_Emt_Block_Adminhtml_Emt_Edit_Attributes extends Mage_Adminhtml_Block_Widget_Form_Renderer_Fieldset_Element
3
- {
4
- public function __construct()
5
- {
6
- $this->setTemplate('emt/attributes.phtml');
7
- }
8
-
9
- protected function _prepareLayout()
10
- {
11
- $this->setChild('add_button_emv_dyn',
12
- $this->getLayout()->createBlock('adminhtml/widget_button')
13
- ->setData(array(
14
- 'label' => Mage::helper('emvemt')->__('Add New EMV DYN Attribute'),
15
- 'class' => 'add',
16
- 'id' => 'add_new_attribute_emv_dyn',
17
- 'on_click' => 'emvAttribute.addEmvDyn();'
18
- ))
19
- );
20
- $this->setChild('add_button_emv_content',
21
- $this->getLayout()->createBlock('adminhtml/widget_button')
22
- ->setData(array(
23
- 'label' => Mage::helper('emvemt')->__('Add New EMV CONTENT Attribute'),
24
- 'class' => 'add',
25
- 'id' => 'add_new_attribute_emv_content',
26
- 'on_click' => 'emvAttribute.addEmvContent();'
27
- ))
28
- );
29
-
30
- $this->setChild('delete_button',
31
- $this->getLayout()->createBlock('adminhtml/widget_button')
32
- ->setData(array(
33
- 'label' => Mage::helper('emvemt')->__('Remove'),
34
- 'class' => 'delete delete-product-option',
35
- 'on_click' => 'emvAttribute.remove(event)'
36
- ))
37
- );
38
-
39
- parent::_prepareLayout();
40
- }
41
-
42
- public function getFieldId()
43
- {
44
- return 'emv_attribute';
45
- }
46
-
47
- public function getFieldName ()
48
- {
49
- return 'attributes';
50
- }
51
-
52
- /**
53
- * Build HTML select element of attribute set attributes
54
- *
55
- * @return string
56
- */
57
- public function getMageAttributesInputHtml()
58
- {
59
- $input = '<input type="text" id="'.$this->getFieldId().'_{{index}}_mage_attribute" name="'.
60
- $this->getFieldName().'[{{index}}][mage_attribute]" size="50" maxlength="200" />';
61
- return $input;
62
- }
63
-
64
- public function getAddButtonHtml()
65
- {
66
- return $this->getChildHtml('add_button_emv_dyn');
67
- }
68
-
69
- public function getAddEmvContentButtonHtml()
70
- {
71
- return $this->getChildHtml('add_button_emv_content');
72
- }
73
-
74
- public function getDeleteButtonHtml()
75
- {
76
- return $this->getChildHtml('delete_button');
77
- }
78
-
79
- protected function _toJson($data)
80
- {
81
- return Mage::helper('emvemt')->jsonEncode($data);
82
- }
83
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Emt/Block/Adminhtml/Emt/Edit/Form.php DELETED
@@ -1,240 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{F6ADA887-E2B8-4107-9915-B14420DCDFE7}
8
- */
9
- class Emv_Emt_Block_Adminhtml_Emt_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
10
- {
11
-
12
- /**
13
- * Prepare block children and data
14
- *
15
- */
16
- protected function _prepareLayout()
17
- {
18
- $onclick = "
19
- var url = '".$this->getUrl('emvemt/emt/getEmvTemplateSelectAjax')."';
20
- new Ajax.Updater(\$('emv_template_id').parentNode, url, {parameters:
21
- { accountId : $('emv_account_id').value,
22
- from: $('from_date').value ,
23
- to :$('to_date').value},
24
- method: 'post'}
25
- );";
26
-
27
- $this->setChild('get_emv_templates',
28
- $this->getLayout()->createBlock('adminhtml/widget_button')
29
- ->setData(array(
30
- 'label' => Mage::helper('emvemt')->__('Get Campaign Commander templates'),
31
- 'onclick' => $onclick,
32
- 'class' => 'save'
33
- ))
34
- );
35
-
36
- parent::_prepareLayout();
37
- }
38
-
39
- /**
40
- * opGUID{AB2272B3-0BEE-42bd-96EC-E2C54C40CB9B}
41
- */
42
- protected function _prepareForm()
43
- {
44
- $form = new Varien_Data_Form(
45
- array(
46
- 'id' => 'edit_form',
47
- 'action' => $this->getUrl('*/*/save'),
48
- 'method' => 'post',
49
- ));
50
-
51
- $emtModel = Mage::registry('current_emvemt');
52
-
53
- if(null === $emtModel)
54
- {
55
- $emtModel = new Varien_Object();
56
- }
57
-
58
- if ($emtModel->getId()) {
59
- $form->addField('id', 'hidden', array(
60
- 'name' => 'id',
61
- ));
62
- }
63
-
64
- $fieldset = $form->addFieldset('emt_info',
65
- array(
66
- 'legend' => Mage::helper('emvemt')->__('Campaign Commander EMT mode'),
67
- 'class' => 'fieldset-wide',
68
- ));
69
-
70
- $magentoTemplatesArray = Mage::registry('mage_templates')->toOptionArray();
71
-
72
- $fieldset->addField('mage_template_id', 'select', array(
73
- 'value' => $emtModel->getMageTemplateId(),
74
- 'label' => Mage::helper('emvemt')->__('Magento Template Name'),
75
- 'name' => 'mage_template_id',
76
- 'disabled' => 'true',
77
- 'required' => true,
78
- 'class' => 'validate-select',
79
- 'values' => $magentoTemplatesArray,
80
- ));
81
-
82
- $accountsArray = Mage::registry('emt_accounts')->toOptionArray();
83
-
84
- $fieldset->addField('emv_account_id', 'select', array(
85
- 'value' => $emtModel->getEmvAccountId(),
86
- 'label' => Mage::helper('emvemt')->__('Campaign Commander Account'),
87
- 'name' => 'emv_account_id',
88
- 'required' => true,
89
- 'disabled' => true,
90
- 'class' => 'validate-select',
91
- 'values' => $accountsArray,
92
- ));
93
-
94
- // javascript removing unused input according to selected send mail mode
95
- $mailModeOnClick = "var sendModeSelect = $('emv_send_mail_mode_id');
96
- sendModeValue = sendModeSelect.options[sendModeSelect.selectedIndex].value;
97
- hideField(sendModeValue);
98
- ";
99
-
100
- $mailModesArray = Mage::registry('mail_modes')->toOptionArray();
101
-
102
- // translate mail mode
103
- foreach($mailModesArray as $key => $value)
104
- {
105
- $mailModesArray[$key]['label'] = Mage::helper('emvemt')->__($mailModesArray[$key]['label']);
106
- }
107
-
108
- $fieldset->addField('emv_send_mail_mode_id', 'select', array(
109
- 'value' => $emtModel->getEmvSendMailModeId(),
110
- 'label' => Mage::helper('emvemt')->__('Send Mail Mode'),
111
- 'name' => 'emv_send_mail_mode_id',
112
- 'required' => true,
113
- 'class' => 'validate-select',
114
- 'onclick' => $mailModeOnClick,
115
- 'values' => $mailModesArray,
116
- ));
117
-
118
- $classicModeId = Mage::getModel('emvemt/mailmode')->getIdByName(Emv_Emt_Constants::CLASSIC_FLAG);
119
- $sendModeId = Mage::getModel('emvemt/mailmode')->getIdByName(Emv_Emt_Constants::EMV_SEND_FLAG);
120
-
121
- if(null === $emtModel->getEmvTemplateId() ||
122
- $emtModel->getEmvSendMailModeId() === $classicModeId)
123
- {
124
- $fieldset->addField('emv_template_id', 'note', array(
125
- 'label' => Mage::helper('emvemt')->__('Campaign Commander Template Name'),
126
- 'required' => true,
127
- 'class' => 'validate-select',
128
- ));
129
- }
130
- else
131
- {
132
- $fieldset->addField('emv_template_id', 'select', array(
133
- 'value' => $emtModel->getEmvTemplateId(),
134
- 'label' => Mage::helper('emvemt')->__('Campaign Commander Template Name'),
135
- 'name' => 'emv_template_id',
136
- 'required' => true,
137
- 'class' => 'validate-select',
138
- 'values' => array(
139
- Mage::registry('current_emv_template_array')
140
- ),
141
- ));
142
- }
143
-
144
- $displayAttributes = '';
145
- if($emtModel->getEmvSendMailModeId() === $classicModeId)
146
- {
147
- $displayAttributes = ' style="display :none;"';
148
- }
149
-
150
- $getEmvTemplateButtonParam = array(
151
- 'text' => '<span id="emtTemplateButtonContainer"'.$displayAttributes.'>'.
152
- $this->getChildHtml('get_emv_templates').'</span>',
153
- );
154
-
155
- $fieldset->addField('get_emv_templates', 'note', $getEmvTemplateButtonParam);
156
-
157
- $dateFormatIso = Mage::app()->getLocale()->getDateFormat(
158
- Mage_Core_Model_Locale::FORMAT_TYPE_SHORT
159
- );
160
-
161
- $dateFromParam = array(
162
- 'value' => '',
163
- 'label' => Mage::helper('emvemt')->__('from'),
164
- 'name' => 'from_date',
165
- 'image' => $this->getSkinUrl('images/grid-cal.gif'),
166
- 'format' => $dateFormatIso,
167
- );
168
-
169
- $fieldset->addField('from_date', 'date', $dateFromParam);
170
-
171
- $dateToParam = array(
172
- 'value' => '',
173
- 'label' => Mage::helper('emvemt')->__('to'),
174
- 'name' => 'to_date',
175
- 'image' => $this->getSkinUrl('images/grid-cal.gif'),
176
- 'format' => $dateFormatIso,
177
- );
178
-
179
- $fieldset->addField('to_date', 'date', $dateToParam);
180
-
181
- $fieldset = $form->addFieldset('attribute_mapping_info', array(
182
- 'legend' => Mage::helper('emvemt')->__('Attribute mapping'),
183
- 'class' => 'fieldset-wide',
184
- ));
185
-
186
- $attributesBlock = $this->getLayout()
187
- ->createBlock('emvemt/adminhtml_emt_edit_attributes');
188
-
189
- $attributes = Mage::registry('emt_attributes');
190
-
191
- if (is_array($attributes) && count($attributes) > 0) {
192
- $attributesBlock->setAttributesData($attributes);
193
- }
194
-
195
- $attributeBlockParam = array(
196
- 'label' => Mage::helper('emvemt')->__('Attributes Mapping'),
197
- 'text' => '<div id="attributes_details">' . $attributesBlock->toHtml() . '</div>',
198
-
199
- // Dirty but it's the only way i've found to hide field in this form
200
- 'note' => '<script type="text/javascript">
201
- function hideField(mailMode)
202
- {
203
- if(mailMode == '.Mage::getModel('emvemt/mailmode')->getIdByName(Emv_Emt_Constants::CLASSIC_FLAG).
204
- ' || mailMode == '.Mage::getModel('emvemt/mailmode')->getIdByName(Emv_Emt_Constants::EMV_SEND_FLAG).')
205
- {
206
- $("emv_template_id").parentNode.parentNode.style.display = "none";
207
- $("to_date").parentNode.parentNode.style.display = "none";
208
- $("from_date").parentNode.parentNode.style.display = "none";
209
- $("get_emv_templates").parentNode.parentNode.style.display = "none";
210
- $("attributes_details").style.display = "none";
211
- }
212
- else
213
- {
214
- if (mailMode == '.Mage::getModel('emvemt/mailmode')->getIdByName(Emv_Emt_Constants::EMV_CREATE_FLAG).')
215
- {
216
- $("emtTemplateButtonContainer").style.display = "";
217
- $("emv_template_id").parentNode.parentNode.style.display = "";
218
- $("get_emv_templates").parentNode.parentNode.style.display = "";
219
- $("to_date").style.display = "";
220
- $("from_date").style.display = "";
221
- $("to_date").parentNode.parentNode.style.display = "";
222
- $("from_date").parentNode.parentNode.style.display = "";
223
- $("attributes_details").style.display = "";
224
- }
225
- }
226
- }
227
- $("note_attributes_box").style.display = "none";
228
- hideField("'.Mage::getModel('emvemt/mailmode')->load($emtModel->getEmvSendMailModeId())->getId().'");
229
- </script>'
230
- );
231
-
232
- $fieldset->addField('attributes_box', 'note', $attributeBlockParam);
233
-
234
- $form->setUseContainer(true);
235
- $form->setValues($emtModel->getData());
236
- $this->setForm($form);
237
-
238
- return parent::_prepareForm();
239
- }
240
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Emt/Block/Adminhtml/Emt/Grid.php DELETED
@@ -1,97 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{C577B255-D27F-4f41-83AC-42EC479B65FD}
8
- */
9
- class Emv_Emt_Block_Adminhtml_Emt_Grid extends Mage_Adminhtml_Block_Widget_Grid
10
- {
11
-
12
- /**
13
- * opGUID{7424594D-9EF0-4882-9D74-3B97D7EFBF7E}
14
- */
15
- protected function _prepareCollection()
16
- {
17
- $collection = Mage::getResourceModel('emvemt/emt_collection');
18
- $collection->getMagentoEMTName();
19
- $this->setCollection($collection);
20
- parent::_prepareCollection();
21
- }
22
-
23
- /**
24
- * opGUID{78D0EB9B-29A9-4660-981E-60899AB408C4}
25
- */
26
- protected function _prepareColumns()
27
- {
28
- $this->addColumn('id', array(
29
- 'header' => Mage::helper('emvemt')->__('EMT ID'),
30
- 'index' => 'id',
31
- 'type' => 'number',
32
- ));
33
-
34
- $this->addColumn('template_code', array(
35
- 'header' => Mage::helper('emvemt')->__('Magento Template Name'),
36
- 'index' => 'template_code',
37
- 'type' => 'varchar',
38
- ));
39
-
40
- //list of all avaiable modes
41
- $sets = Mage::getModel('emvemt/mailmode')->getCollection()
42
- ->toOptionHash();
43
-
44
- // translate mail mode
45
- foreach($sets as $key => $value)
46
- {
47
- $sets[$key] = Mage::helper('emvemt')->__($value);
48
- }
49
-
50
- $this->addColumn('emv_send_mail_mode_id',
51
- array(
52
- 'header'=> Mage::helper('emvemt')->__('Mode'),
53
- 'width' => '100px',
54
- 'index' => 'emv_send_mail_mode_id',
55
- 'type' => 'options',
56
- 'options' => $sets,
57
- ));
58
-
59
- $this->addColumn('emv_template_id_and_name', array(
60
- 'header' => Mage::helper('emvemt')->__('Campaign Commander Template Id And Name'),
61
- 'index' => 'emv_template_id_and_name',
62
- 'type' => 'varchar',
63
- 'filter' => false,
64
- 'renderer' => 'emvemt/adminhtml_emt_grid_renderer_emvname',
65
- ));
66
-
67
- $this->addColumn('action', array(
68
- 'header' => Mage::helper('emvemt')->__('Action'),
69
- 'type' => 'action',
70
- 'width' => '100',
71
- 'getter' => 'getId',
72
- 'actions' => array(
73
- array(
74
- 'caption' => Mage::helper('emvemt')->__('Edit'),
75
- 'url' => array('base'=> '*/*/edit'),
76
- 'field' => 'id',
77
- )
78
- ),
79
- 'filter' => false,
80
- 'sortable' => false,
81
- 'is_system' => true,
82
- ));
83
-
84
- return parent::_prepareColumns();
85
- }
86
-
87
- /**
88
- * opGUID{725A831A-D817-4a84-ADE2-0D07AF6E43E7}
89
- *
90
- * @param var $row
91
- */
92
- public function getRowUrl($row)
93
- {
94
- return $this->getUrl('*/*/edit', array('id' => $row->getId()));
95
- }
96
-
97
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Emt/Block/Adminhtml/Emt/Grid/Renderer/Emvname.php DELETED
@@ -1,18 +0,0 @@
1
- <?php
2
-
3
- class Emv_Emt_Block_Adminhtml_Emt_Grid_Renderer_Emvname extends
4
- Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
5
- {
6
- /**
7
- * Render mode
8
- *
9
- * @param Varien_Object $row
10
- * @return string
11
- */
12
- public function render(Varien_Object $row)
13
- {
14
- $helper = Mage::helper('emvemt/emvtemplate');
15
- return $helper->getEMVTemplateName($row->getEmvTemplateId(), $row->getEmvAccountId());
16
- }
17
-
18
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Emt/Block/Adminhtml/Emt/New.php DELETED
@@ -1,29 +0,0 @@
1
- <?php
2
- class Emv_Emt_Block_Adminhtml_Emt_New extends Mage_Adminhtml_Block_Widget_Form_Container
3
- {
4
- /**
5
- * opGUID{E35B4FB9-C0A2-4362-8A9C-9F73B3A95889}
6
- */
7
- public function __construct()
8
- {
9
- parent::__construct();
10
-
11
- $this->_blockGroup = 'emvemt';
12
- $this->_controller = 'adminhtml_emt';
13
- $this->_mode = 'new';
14
- $this->_headerText = $this->getHeaderText();
15
-
16
- $this->removeButton('delete');
17
- $this->removeButton('save');
18
- }
19
-
20
- /**
21
- * Retrieve text for header element depending on loaded page
22
- *
23
- * @return string
24
- */
25
- public function getHeaderText()
26
- {
27
- return Mage::helper('emvemt')->__('New Campaign Commander Transactional Email');
28
- }
29
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Emt/Block/Adminhtml/Emt/New/Form.php DELETED
@@ -1,94 +0,0 @@
1
- <?php
2
- class Emv_Emt_Block_Adminhtml_Emt_New_Form extends Mage_Adminhtml_Block_Widget_Form
3
- {
4
-
5
- /**
6
- * Prepare block children and data
7
- *
8
- */
9
- protected function _prepareLayout()
10
- {
11
- $onclick = "document.getElementById('new_form').submit();";
12
- $this->setChild('continue_button',
13
- $this->getLayout()->createBlock('adminhtml/widget_button')
14
- ->setData(array(
15
- 'label' => Mage::helper('emvemt')->__('Continue'),
16
- 'onclick' => $onclick,
17
- 'class' => 'save'
18
- ))
19
- );
20
-
21
- parent::_prepareLayout();
22
- }
23
-
24
- /**
25
- * opGUID{AB2272B3-0BEE-42bd-96EC-E2C54C40CB9B}
26
- */
27
- protected function _prepareForm()
28
- {
29
- $form = new Varien_Data_Form(
30
- array(
31
- 'id' => 'new_form',
32
- 'action' => $this->getUrl('*/*/save'),
33
- 'method' => 'post',
34
- ));
35
-
36
- $fieldset = $form->addFieldset('emt_info',
37
- array(
38
- 'legend' => Mage::helper('emvemt')->__('Campaign Commander EMT mode'),
39
- 'class' => 'fieldset-wide',
40
- ));
41
-
42
- $emvAccount = Mage::getResourceModel('emvcore/account_collection');
43
-
44
- $onchange = "new Ajax.Updater(\$('mage_template_id').parentNode, '".$this->getUrl('emvemt/emt/getNotMappedMagentoTemplateSelectAjax').
45
- "', {parameters:
46
- { emvAccount : $('emv_account_id').value
47
- },
48
- method: 'post'});";
49
-
50
- $fieldset->addField('emv_account_id', 'select', array(
51
- 'value' => '',
52
- 'label' => Mage::helper('emvemt')->__('Campaign Commander Account'),
53
- 'name' => 'emv_account_id',
54
- 'required' => true,
55
- 'class' => 'validate-select',
56
- 'values' => $emvAccount->toOptionArray(),
57
- 'onchange' => $onchange,
58
- ));
59
-
60
- $accountId = $emvAccount->getFirstItem()->getId();
61
-
62
- $mageTemplate = Mage::getModel('emvemt/mageTemplate')->getNotMappedMageTemplateCollection($accountId);
63
-
64
- if($mageTemplate->getSize() == 0)
65
- {
66
- $fieldset->addField('mage_template_id', 'note', array(
67
- 'label' => Mage::helper('emvemt')->__('Magento Template Name'),
68
- 'required' => true,
69
- 'class' => 'validate-select',
70
- 'text' => '<strong>' . Mage::helper('emvemt')->__('There is no Magento templates not mapped with this account.') . '</strong>',
71
- ));
72
- }
73
- else
74
- {
75
- $fieldset->addField('mage_template_id', 'select', array(
76
- 'value' => '',
77
- 'label' => Mage::helper('emvemt')->__('Magento Template Name'),
78
- 'name' => 'mage_template_id',
79
- 'required' => true,
80
- 'class' => 'validate-select',
81
- 'values' => $mageTemplate->toOptionArray(),
82
- ));
83
- }
84
-
85
- $fieldset->addField('continue_button', 'note', array(
86
- 'text' => $this->getChildHtml('continue_button'),
87
- ));
88
-
89
- $form->setUseContainer(true);
90
- $this->setForm($form);
91
-
92
- return parent::_prepareForm();
93
- }
94
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Emt/Block/Adminhtml/Emts.php DELETED
@@ -1,32 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{B2448BA4-891E-4142-80B7-486CAD6C9033}
8
- */
9
- class Emv_Emt_Block_Adminhtml_Emts extends Mage_Adminhtml_Block_Widget_Grid_Container
10
- {
11
-
12
- /**
13
- * opGUID{2D94FA5D-18EE-4b9b-B71A-D7AAF0DCF89C}
14
- */
15
- public function __construct()
16
- {
17
- parent::__construct();
18
- $this->_blockGroup = 'emvemt';
19
- $this->_controller = 'adminhtml_emt';
20
- $this->_headerText = Mage::helper('emvemt')->__('Campaign Commander Transactional Emails');
21
- $this->_updateButton('add', 'label', Mage::helper('emvemt')->__('Add New Transactional Email'));
22
- }
23
-
24
- /**
25
- * opGUID{2CE48FD6-34B7-4dee-9223-333B43DAD129}
26
- */
27
- protected function _prepareLayout()
28
- {
29
- parent::_prepareLayout();
30
- }
31
-
32
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Emt/Block/Adminhtml/Log.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Email Sending Log grid wrapper
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Log extends Mage_Adminhtml_Block_Widget_Grid_Container
11
+ {
12
+
13
+ public function __construct()
14
+ {
15
+ parent::__construct();
16
+ $this->_blockGroup = 'emvemt';
17
+ $this->_controller = 'adminhtml_log';
18
+ $this->_headerText = Mage::helper('emvemt')->__('Email Sending Logs');
19
+ $this->removeButton('add');
20
+ }
21
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Log/Grid.php ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Email sending log grid
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Log_Grid extends Mage_Adminhtml_Block_Widget_Grid
11
+ {
12
+ /**
13
+ * Prepare collection for grid
14
+ *
15
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareCollection()
16
+ */
17
+ protected function _prepareCollection()
18
+ {
19
+ $collection = Mage::getResourceModel('emvemt/log_collection');
20
+ $this->setCollection($collection);
21
+
22
+ parent::_prepareCollection();
23
+ }
24
+
25
+ /**
26
+ * Prepare column for campaign commander templates grid
27
+ *
28
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareColumns()
29
+ */
30
+ protected function _prepareColumns()
31
+ {
32
+ // id
33
+ $this->addColumn('id', array(
34
+ 'header' => Mage::helper('emvemt')->__('ID'),
35
+ 'index' => 'id',
36
+ 'type' => 'number',
37
+ ));
38
+
39
+ $this->addColumn('email',
40
+ array(
41
+ 'header'=> Mage::helper('emvemt')->__('Email'),
42
+ 'index' => 'email',
43
+ 'type' => 'varchar',
44
+ )
45
+ );
46
+ // Created at
47
+ $this->addColumn('created_at', array(
48
+ 'header' => Mage::helper('sales')->__('Created At'),
49
+ 'type' => 'datetime',
50
+ 'width' => '100',
51
+ 'align' => 'center',
52
+ 'index' => 'created_at',
53
+ 'gmtoffset' => true
54
+ ));
55
+ // List of all avaiable modes
56
+ $this->addColumn('sending_mode',
57
+ array(
58
+ 'header' => Mage::helper('emvemt')->__('Sending Mode'),
59
+ 'index' => 'sending_mode',
60
+ 'type' => 'options',
61
+ 'width' => '100',
62
+ 'options' => Emv_Emt_Model_Mailmode::getMailModesAndLabels(),
63
+ )
64
+ );
65
+
66
+ $this->addColumn('sending_type',
67
+ array(
68
+ 'header' => Mage::helper('emvemt')->__('Type'),
69
+ 'index' => 'sending_type',
70
+ 'type' => 'options',
71
+ 'width' => '100',
72
+ 'options' => Emv_Emt_Model_Log::getAllWorkFlowOptions(),
73
+ ));
74
+
75
+ // Original Magento Template Name
76
+ $this->addColumn('original_magento_template_name',
77
+ array(
78
+ 'header'=> Mage::helper('emvemt')->__('Original Magento Template'),
79
+ 'index' => 'original_magento_template_name',
80
+ 'type' => 'varchar',
81
+ )
82
+ );
83
+
84
+ // Magento Template name
85
+ $this->addColumn('magento_template_name',
86
+ array(
87
+ 'header'=> Mage::helper('emvemt')->__('Magento Template'),
88
+ 'index' => 'magento_template_name',
89
+ 'type' => 'varchar',
90
+ )
91
+ );
92
+
93
+ // Account name
94
+ $this->addColumn('account_id',
95
+ array(
96
+ 'header'=> Mage::helper('emvemt')->__('Account Name'),
97
+ 'index' => 'account_id',
98
+ 'type' => 'options',
99
+ 'options' => Mage::getResourceModel('emvcore/account_collection')->toOptionHash()
100
+ )
101
+ );
102
+
103
+ // EmailVision Template name
104
+ $this->addColumn('emv_name',
105
+ array(
106
+ 'header'=> Mage::helper('emvemt')->__('SmartFocus Template'),
107
+ 'index' => 'emv_name',
108
+ 'type' => 'varchar',
109
+ )
110
+ );
111
+ // Error
112
+ $this->addColumn('error_code',
113
+ array(
114
+ 'header' => Mage::helper('emvemt')->__('Error'),
115
+ 'index' => 'error_code',
116
+ 'type' => 'options',
117
+ 'width' => '100',
118
+ 'options' => Emv_Emt_Model_Log::getErrorCodeOptions(),
119
+ ));
120
+
121
+ $this->addColumn('sent_sucess',
122
+ array(
123
+ 'header' => Mage::helper('emvemt')->__('Success'),
124
+ 'align' => 'center',
125
+ 'width' => 1,
126
+ 'index' => 'sent_sucess',
127
+ 'type' => 'options',
128
+ 'options' => array(
129
+ 1 => Mage::helper('core')->__('Yes'),
130
+ 0 => Mage::helper('core')->__('No'),
131
+ ),
132
+ ));
133
+
134
+ // Action column
135
+ $this->addColumn('action', array(
136
+ 'header' => Mage::helper('emvemt')->__('Action'),
137
+ 'type' => 'action',
138
+ 'getter' => 'getId',
139
+ 'renderer' => 'emvemt/adminhtml_log_grid_renderer_getError',
140
+ 'filter' => false,
141
+ 'sortable' => false,
142
+ 'is_system' => true,
143
+ ));
144
+
145
+ return parent::_prepareColumns();
146
+ }
147
+
148
+ /**
149
+ * (non-PHPdoc)
150
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareMassaction()
151
+ */
152
+ protected function _prepareMassaction()
153
+ {
154
+ $this->setMassactionIdField('entity_id');
155
+ $this->getMassactionBlock()->setFormFieldName('log');
156
+
157
+ $this->getMassactionBlock()->addItem('delete', array(
158
+ 'label' => Mage::helper('customer')->__('Delete'),
159
+ 'url' => $this->getUrl('*/*/massDelete'),
160
+ 'confirm' => Mage::helper('customer')->__('Are you sure?')
161
+ ));
162
+
163
+ return $this;
164
+ }
165
+
166
+ /**
167
+ * Get row class - determine the row class according to invalidity information
168
+ *
169
+ * @param Varien_Object $emvEmt
170
+ * @return string
171
+ */
172
+ public function getRowClass(Varien_Object $emvEmt)
173
+ {
174
+ $class = "";
175
+ if (!$emvEmt->getData('sent_sucess')) {
176
+ $class= "invalid";
177
+ }
178
+ return $class;
179
+ }
180
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Log/Grid/Renderer/GetError.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Get error for log renderer
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Log_Grid_Renderer_GetError extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
11
+ {
12
+ /**
13
+ * Render ship action
14
+ *
15
+ * @param Varien_Object $row
16
+ *
17
+ * @return string
18
+ */
19
+ public function render(Varien_Object $row)
20
+ {
21
+ $html = '';
22
+ if ($row->getError()) {
23
+ $url = $this->getUrl('*/*/getError', array('id' => $row->getId()));
24
+ $html = sprintf('<a href="%s">%s</a>', $url, Mage::helper('emvemt')->__('Get Error'));
25
+ }
26
+ return $html;
27
+ }
28
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Resending.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Email Resending grid wrapper
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Resending extends Mage_Adminhtml_Block_Widget_Grid_Container
11
+ {
12
+
13
+ public function __construct()
14
+ {
15
+ parent::__construct();
16
+ $this->_blockGroup = 'emvemt';
17
+ $this->_controller = 'adminhtml_resending';
18
+ $this->_headerText = Mage::helper('emvemt')->__('Rescheduled Emails');
19
+ $this->removeButton('add');
20
+ }
21
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Resending/Grid.php ADDED
@@ -0,0 +1,152 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Email sending log grid
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Resending_Grid extends Mage_Adminhtml_Block_Widget_Grid
11
+ {
12
+ /**
13
+ * Prepare collection for grid
14
+ *
15
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareCollection()
16
+ */
17
+ protected function _prepareCollection()
18
+ {
19
+ $collection = Mage::getResourceModel('emvemt/resending_queue_message_collection');
20
+ $this->setCollection($collection);
21
+
22
+ parent::_prepareCollection();
23
+ }
24
+
25
+ /**
26
+ * Prepare column for resending email grid
27
+ *
28
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareColumns()
29
+ */
30
+ protected function _prepareColumns()
31
+ {
32
+ // id
33
+ $this->addColumn('id', array(
34
+ 'header' => Mage::helper('emvemt')->__('ID'),
35
+ 'index' => 'id',
36
+ 'type' => 'number',
37
+ ));
38
+
39
+ $this->addColumn('email',
40
+ array(
41
+ 'header'=> Mage::helper('emvemt')->__('Email'),
42
+ 'index' => 'email',
43
+ 'type' => 'varchar',
44
+ )
45
+ );
46
+ // Created at
47
+ $this->addColumn('created_at', array(
48
+ 'header' => Mage::helper('sales')->__('Created At'),
49
+ 'type' => 'datetime',
50
+ 'width' => '100',
51
+ 'align' => 'center',
52
+ 'index' => 'created_at',
53
+ 'gmtoffset' => true
54
+ ));
55
+
56
+ $this->addColumn('number_attempts',
57
+ array(
58
+ 'header'=> Mage::helper('emvemt')->__('Number of Attempts'),
59
+ 'index' => 'number_attempts',
60
+ 'type' => 'varchar',
61
+ )
62
+ );
63
+ // First attempt
64
+ $this->addColumn('first_attempt', array(
65
+ 'header' => Mage::helper('customer')->__('First Attempt'),
66
+ 'type' => 'datetime',
67
+ 'width' => '100',
68
+ 'align' => 'center',
69
+ 'index' => 'first_attempt',
70
+ 'gmtoffset' => true
71
+ ));
72
+ // Last attempt
73
+ $this->addColumn('last_attempt', array(
74
+ 'header' => Mage::helper('customer')->__('Last Attempt'),
75
+ 'type' => 'datetime',
76
+ 'width' => '100',
77
+ 'align' => 'center',
78
+ 'index' => 'last_attempt',
79
+ 'gmtoffset' => true
80
+ ));
81
+
82
+ // Original Magento Template Name
83
+ $this->addColumn('original_magento_template_name',
84
+ array(
85
+ 'header'=> Mage::helper('emvemt')->__('Original Magento Template'),
86
+ 'index' => 'original_magento_template_name',
87
+ 'type' => 'varchar',
88
+ )
89
+ );
90
+
91
+ // Magento Template name
92
+ $this->addColumn('magento_template_name',
93
+ array(
94
+ 'header'=> Mage::helper('emvemt')->__('Magento Template'),
95
+ 'index' => 'magento_template_name',
96
+ 'type' => 'varchar',
97
+ )
98
+ );
99
+
100
+ // Account name
101
+ $this->addColumn('account_id',
102
+ array(
103
+ 'header'=> Mage::helper('emvemt')->__('Account Name'),
104
+ 'index' => 'account_id',
105
+ 'type' => 'options',
106
+ 'options' => Mage::getResourceModel('emvcore/account_collection')->toOptionHash()
107
+ )
108
+ );
109
+
110
+ // EmailVision Template name
111
+ $this->addColumn('emv_name',
112
+ array(
113
+ 'header'=> Mage::helper('emvemt')->__('SmartFocus Template'),
114
+ 'index' => 'emv_name',
115
+ 'type' => 'varchar',
116
+ )
117
+ );
118
+
119
+ $this->addColumn('sent_sucess',
120
+ array(
121
+ 'header' => Mage::helper('emvemt')->__('Success'),
122
+ 'align' => 'center',
123
+ 'width' => 1,
124
+ 'index' => 'sent_sucess',
125
+ 'type' => 'options',
126
+ 'options' => array(
127
+ 1 => Mage::helper('core')->__('Yes'),
128
+ 0 => Mage::helper('core')->__('No'),
129
+ ),
130
+ ));
131
+
132
+ return parent::_prepareColumns();
133
+ }
134
+
135
+ /**
136
+ * (non-PHPdoc)
137
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareMassaction()
138
+ */
139
+ protected function _prepareMassaction()
140
+ {
141
+ $this->setMassactionIdField('entity_id');
142
+ $this->getMassactionBlock()->setFormFieldName('resending_message');
143
+
144
+ $this->getMassactionBlock()->addItem('delete', array(
145
+ 'label' => Mage::helper('customer')->__('Delete'),
146
+ 'url' => $this->getUrl('*/*/massDelete'),
147
+ 'confirm' => Mage::helper('customer')->__('Are you sure?')
148
+ ));
149
+
150
+ return $this;
151
+ }
152
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit.php ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Tabs for "edit campaign commander template" menu
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Template_Edit extends Mage_Adminhtml_Block_Widget
11
+ {
12
+ public function __construct()
13
+ {
14
+ $this->setTemplate('emailvision/emt/template/edit.phtml');
15
+ $this->setId('emv_email_template');
16
+ }
17
+
18
+ /**
19
+ * Prepare all necessary buttons
20
+ *
21
+ * (non-PHPdoc)
22
+ * @see Mage_Core_Block_Abstract::_prepareLayout()
23
+ */
24
+ protected function _prepareLayout()
25
+ {
26
+ if ($head = $this->getLayout()->getBlock('head')) {
27
+ $head->addItem('js', 'prototype/window.js')
28
+ ->addItem('js_css', 'prototype/windows/themes/default.css')
29
+ ->addCss('lib/prototype/windows/themes/magento.css')
30
+ ->addCss('campaign-commander.css')
31
+ ->addItem('js', 'mage/adminhtml/variables.js');
32
+ }
33
+
34
+ // back button - get back to grid menu
35
+ $this->setChild('back_button',
36
+ $this->getLayout()->createBlock('adminhtml/widget_button')
37
+ ->setData(array(
38
+ 'label' => Mage::helper('catalog')->__('Back'),
39
+ 'onclick' => 'setLocation(\''.$this->getUrl('*/*/', array()).'\')',
40
+ 'class' => 'back'
41
+ ))
42
+ );
43
+
44
+ // reset button
45
+ $this->setChild('reset_button',
46
+ $this->getLayout()->createBlock('adminhtml/widget_button')
47
+ ->setData(array(
48
+ 'label' => Mage::helper('catalog')->__('Reset'),
49
+ 'onclick' => 'setLocation(\''.$this->getUrl('*/*/*', array('_current'=>true)).'\')'
50
+ ))
51
+ );
52
+
53
+ // get SmartFocus email template
54
+ $emtModel = $this->getEmt();
55
+ // only display the following buttons if a template has been created
56
+ if ($emtModel->getId()) {
57
+ // save and continue edit button
58
+ $this->setChild('save_and_edit_button',
59
+ $this->getLayout()->createBlock('adminhtml/widget_button')
60
+ ->setData(array(
61
+ 'label' => Mage::helper('catalog')->__('Save and Continue Edit'),
62
+ 'onclick' => 'saveAndContinueEdit(\''.$this->getSaveAndContinueUrl().'\')',
63
+ 'class' => 'save'
64
+ ))
65
+ );
66
+
67
+ // delete button
68
+ $this->setChild('delete_button',
69
+ $this->getLayout()->createBlock('adminhtml/widget_button')
70
+ ->setData(array(
71
+ 'label' => Mage::helper('catalog')->__('Delete'),
72
+ 'onclick' => 'confirmSetLocation(\''.Mage::helper('catalog')->__('Are you sure?').'\', \''.$this->getDeleteUrl().'\')',
73
+ 'class' => 'delete'
74
+ ))
75
+ );
76
+
77
+ // refresh SmartFocus Attributes
78
+ $this->setChild('refresh_button',
79
+ $this->getLayout()->createBlock('adminhtml/widget_button')
80
+ ->setData(array(
81
+ 'label' => Mage::helper('emvemt')->__('Refresh All Attributes'),
82
+ 'onclick' => "getEmvAttribute();"
83
+ ))
84
+ );
85
+ // insert Magento template
86
+ $this->setChild('insert_variable_button',
87
+ $this->getLayout()->createBlock('adminhtml/widget_button')
88
+ ->setData(array(
89
+ 'label' => Mage::helper('emvemt')->__('Insert Prepared Magento Variables'),
90
+ 'onclick' => "openVariableChooser();"
91
+ ))
92
+ );
93
+ // reset button
94
+ $this->setChild('preview_button',
95
+ $this->getLayout()->createBlock('adminhtml/widget_button')
96
+ ->setData(array(
97
+ 'label' => Mage::helper('emvemt')->__('Preview'),
98
+ 'onclick' => 'openPreview();'
99
+ ))
100
+ );
101
+ }
102
+
103
+ return parent::_prepareLayout();
104
+ }
105
+
106
+ /**
107
+ * Retrieve text for header element depending on loaded page
108
+ *
109
+ * @return string
110
+ */
111
+ public function getHeader()
112
+ {
113
+ if (Mage::registry('mage_template_name')) {
114
+ return Mage::helper('emvemt')->__("Edit '%s' Email Template",
115
+ $this->htmlEscape(Mage::registry('mage_template_name')));
116
+ } else {
117
+ return Mage::helper('emvemt')->__("New Email Template");
118
+ }
119
+ }
120
+
121
+ /**
122
+ * @return Emv_Emt_Model_Emt
123
+ */
124
+ public function getEmt()
125
+ {
126
+ // get template from registry
127
+ $emtModel = Mage::registry(Emv_Emt_Adminhtml_TemplateController::CURRENT_EMVEMT_TEMPLATE_REGISTRY);
128
+ if ($emtModel == null) {
129
+ $emtModel = Mage::getModel('emvemt/emt');
130
+ }
131
+ return $emtModel;
132
+ }
133
+
134
+ /**
135
+ * @return string
136
+ */
137
+ public function getBackButtonHtml()
138
+ {
139
+ return $this->getChildHtml('back_button');
140
+ }
141
+
142
+ /**
143
+ * @return string
144
+ */
145
+ public function getSaveAndEditButtonHtml()
146
+ {
147
+ return $this->getChildHtml('save_and_edit_button');
148
+ }
149
+
150
+ /**
151
+ * @return string
152
+ */
153
+ public function getDeleteButtonHtml()
154
+ {
155
+ return $this->getChildHtml('delete_button');
156
+ }
157
+
158
+ /**
159
+ * @return string
160
+ */
161
+ public function getCancelButtonHtml()
162
+ {
163
+ return $this->getChildHtml('reset_button');
164
+ }
165
+
166
+ /**
167
+ * @return string
168
+ */
169
+ public function getEmvAttributeButtonHtml()
170
+ {
171
+ return $this->getChildHtml('refresh_button');
172
+ }
173
+
174
+ /**
175
+ * @return string
176
+ */
177
+ public function getInsertMageVariableButtonHtml()
178
+ {
179
+ return $this->getChildHtml('insert_variable_button');
180
+ }
181
+
182
+ /**
183
+ * @return string
184
+ */
185
+ public function getPreviewButtonHtml()
186
+ {
187
+ return $this->getChildHtml('preview_button');
188
+ }
189
+
190
+ /**
191
+ * @return string
192
+ */
193
+ public function getSaveUrl()
194
+ {
195
+ return $this->getUrl('*/*/save', array('_current'=>true, 'back'=>null));
196
+ }
197
+
198
+ /**
199
+ * @return string
200
+ */
201
+ public function getSaveAndContinueUrl()
202
+ {
203
+ return $this->getUrl('*/*/save', array(
204
+ '_current' => true,
205
+ 'back' => 'edit',
206
+ 'tab' => '{{tab_id}}',
207
+ 'active_tab' => null
208
+ ));
209
+ }
210
+
211
+ /**
212
+ * @return string
213
+ */
214
+ public function getDeleteUrl()
215
+ {
216
+ return $this->getUrl('*/*/delete', array('_current'=>true));
217
+ }
218
+
219
+ /**
220
+ * @return string
221
+ */
222
+ public function getPreviewUrl()
223
+ {
224
+ return $this->getUrl('*/*/getPreview', array('_current'=>true));
225
+ }
226
+
227
+ /**
228
+ * @return string
229
+ */
230
+ public function getSelectedTabId()
231
+ {
232
+ return addslashes(htmlspecialchars($this->getRequest()->getParam('tab')));
233
+ }
234
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit/Tab/EmvContent.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EMV CONTENT attribute tab for SmartFocus email template
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Template_Edit_Tab_EmvContent extends Emv_Emt_Block_Adminhtml_Template_Edit_Tab_EmvDyn
11
+ {
12
+ /**
13
+ * Attribute type (EMV CONTENT)
14
+ * @var string
15
+ */
16
+ protected $_attributeType = Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_CONTENT;
17
+
18
+ /**
19
+ * Max rows for textarea
20
+ * @var int
21
+ */
22
+ protected $_maxRowsForTextarea = 10;
23
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit/Tab/EmvDyn.php ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EMV DYN attribute tab for SmartFocus email template
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Template_Edit_Tab_EmvDyn extends Mage_Adminhtml_Block_Widget
11
+ {
12
+ /**
13
+ * Max rows for textarea
14
+ * @var int
15
+ */
16
+ protected $_maxRowsForTextarea = 2;
17
+
18
+ /**
19
+ * PREFIX constants
20
+ */
21
+ const PREFIX_REFRESH_BUTTON = 'refresh_attributes_';
22
+ const PREFIX_ATTRIBUTE_TABLE = 'attributes_';
23
+ const PREFIX_INVALID_ATTRIBUTE_TABLE = 'attributes_';
24
+ const PREFIX_CONTENT_DIV = 'content_';
25
+
26
+ /**
27
+ * Index attribute Registry
28
+ */
29
+ const ATTRIBUTE_INDEX_REGISTRY = 'emv_attributes_index';
30
+
31
+ /**
32
+ * Invalid attributes
33
+ * @var array
34
+ */
35
+ protected $_invalidAttributes = array();
36
+
37
+ /**
38
+ * Available attributes
39
+ * @var array
40
+ */
41
+ protected $_availableAttributes = array();
42
+
43
+ /**
44
+ * Attribute type (EMV DYN)
45
+ * @var string
46
+ */
47
+ protected $_attributeType = Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_DYN;
48
+
49
+ /**
50
+ * Set a new template
51
+ */
52
+ public function __construct()
53
+ {
54
+ parent::__construct();
55
+ $this->setTemplate('emailvision/emt/template/mapped_attributes.phtml');
56
+ }
57
+
58
+ /**
59
+ * @return string
60
+ */
61
+ public function getAttributeType()
62
+ {
63
+ return $this->_attributeType;
64
+ }
65
+
66
+ /**
67
+ * @param string $type
68
+ * @return Emv_Emt_Block_Adminhtml_Template_Edit_Tab_EmvDyn
69
+ */
70
+ public function setAttributeType($type)
71
+ {
72
+ $this->_attributeType = $type;
73
+ return $this;
74
+ }
75
+
76
+ /**
77
+ * @return string
78
+ */
79
+ public function getRefreshButtonId()
80
+ {
81
+ return self::PREFIX_REFRESH_BUTTON . $this->getAttributeType();
82
+ }
83
+
84
+ /**
85
+ * @return string
86
+ */
87
+ public function getAttributesTableId()
88
+ {
89
+ return self::PREFIX_ATTRIBUTE_TABLE . $this->getAttributeType();
90
+ }
91
+
92
+ /**
93
+ * @return string
94
+ */
95
+ public function getInvalidAttributeTableId()
96
+ {
97
+ return self::PREFIX_INVALID_ATTRIBUTE_TABLE . $this->getAttributeType();
98
+ }
99
+
100
+ /**
101
+ * @return string
102
+ */
103
+ public function getDivContentId()
104
+ {
105
+ return self::PREFIX_CONTENT_DIV . $this->getAttributeType();
106
+ }
107
+
108
+ /**
109
+ * @return string
110
+ */
111
+ public function getRefreshButtonHtml()
112
+ {
113
+ return $this->getChildHtml('refresh_button');
114
+ }
115
+
116
+ /**
117
+ * Prepare attributes from registry
118
+ */
119
+ public function prepareAttributes()
120
+ {
121
+ $helper = Mage::helper('emvemt/emvtemplate');
122
+ $allAttributes = $helper->getAllEmvFieldsFromRegistry();
123
+ $mappedAttributes = $helper->getSortedMappedAttributesFromRegistry();
124
+
125
+ if (
126
+ $allAttributes
127
+ && is_array($allAttributes)
128
+ && isset($allAttributes[$this->getAttributeType()])
129
+ ) {
130
+ // prepare invalid attributes
131
+ // invalid attributes are mapped ones which are not in available attribute list
132
+ if (
133
+ $mappedAttributes
134
+ && is_array($mappedAttributes)
135
+ && isset($mappedAttributes[$this->getAttributeType()])
136
+ ) {
137
+ foreach ($mappedAttributes[$this->getAttributeType()] as $attribute) {
138
+ $preparedAttribute = $this->getAttribute($attribute['emv_attribute'], $attribute);
139
+ if (
140
+ !isset($allAttributes[$this->getAttributeType()][$attribute['emv_attribute']])
141
+ ) {
142
+ $preparedAttribute['invalid'] = true;
143
+ $this->_invalidAttributes[$attribute['emv_attribute']] = $preparedAttribute;
144
+ } else {
145
+ $this->_availableAttributes[$attribute['emv_attribute']] = $preparedAttribute;
146
+ }
147
+ }
148
+ }
149
+
150
+ foreach ($allAttributes[$this->getAttributeType()] as $attributeName) {
151
+ if (!isset($this->_availableAttributes[$attributeName])) {
152
+ $this->_availableAttributes[$attributeName] = $this->getAttribute($attributeName);
153
+ }
154
+ }
155
+ } elseif (
156
+ $mappedAttributes
157
+ && is_array($mappedAttributes)
158
+ && isset($mappedAttributes[$this->getAttributeType()])
159
+ ) {
160
+ foreach ($mappedAttributes[$this->getAttributeType()] as $attribute) {
161
+ $preparedAttribute = $this->getAttribute($attribute['emv_attribute'], $attribute);
162
+ $this->_availableAttributes[$attribute['emv_attribute']] = $preparedAttribute;
163
+ }
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Prepare an EMV attribute according to the given parameters.
169
+ *
170
+ * @param string $emvName
171
+ * @param array $mappedAttribute
172
+ * @return Ambigous <string, multitype:string unknown >
173
+ */
174
+ public function getAttribute($emvName, $mappedAttribute = null)
175
+ {
176
+ $preparedAttribute = array();
177
+ if ($mappedAttribute) {
178
+ $preparedAttribute = $mappedAttribute;
179
+ } else {
180
+ $preparedAttribute['emv_attribute'] = $emvName;
181
+ $preparedAttribute['mage_attribute'] = '';
182
+ $preparedAttribute['id'] = '';
183
+ $preparedAttribute['emv_attribute_type'] = $this->getAttributeType();
184
+ }
185
+
186
+ return $preparedAttribute;
187
+ }
188
+
189
+ /**
190
+ * @return array
191
+ */
192
+ public function getInvalidAttributes()
193
+ {
194
+ return $this->_invalidAttributes;
195
+ }
196
+
197
+ /**
198
+ * @return array
199
+ */
200
+ public function getAvailableAttributes()
201
+ {
202
+ return $this->_availableAttributes;
203
+ }
204
+
205
+ /**
206
+ * @return int
207
+ */
208
+ public function getNewIndexForAttributes()
209
+ {
210
+ $indexFromRegistry = Mage::registry(self::ATTRIBUTE_INDEX_REGISTRY);
211
+ if ($indexFromRegistry === null) {
212
+ $indexFromRegistry = 0;
213
+ } else {
214
+ (int)$indexFromRegistry++;
215
+ }
216
+
217
+ Mage::unregister(self::ATTRIBUTE_INDEX_REGISTRY);
218
+ Mage::register(self::ATTRIBUTE_INDEX_REGISTRY, $indexFromRegistry);
219
+ return $indexFromRegistry;
220
+ }
221
+
222
+ /**
223
+ * Get max rows for textarea
224
+ *
225
+ * @return number
226
+ */
227
+ public function getTextareaRows()
228
+ {
229
+ return $this->_maxRowsForTextarea;
230
+ }
231
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit/Tab/General.php ADDED
@@ -0,0 +1,317 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SmartFocus email template edit form
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Template_Edit_Tab_General extends Mage_Adminhtml_Block_Widget_Form
11
+ {
12
+ /**
13
+ * @var Emv_Core_Model_Mysql4_Account_Collection
14
+ */
15
+ protected $_accountCollection;
16
+
17
+ /**
18
+ * Prepare block children and data
19
+ */
20
+ protected function _prepareLayout()
21
+ {
22
+ $this->setChild('continue_button',
23
+ $this->getLayout()->createBlock('adminhtml/widget_button')
24
+ ->setData(array(
25
+ 'label' => Mage::helper('emvemt')->__('Continue'),
26
+ 'onclick' => 'editForm.submit();',
27
+ 'class' => 'save'
28
+ ))
29
+ );
30
+
31
+ $this->setChild('get_emv_templates',
32
+ $this->getLayout()->createBlock('adminhtml/widget_button')
33
+ ->setData(array(
34
+ 'label' => Mage::helper('emvemt')->__('Get SmartFocus templates'),
35
+ 'class' => 'save',
36
+ 'id' => 'get_emv_templates'
37
+ ))
38
+ );
39
+
40
+ parent::_prepareLayout();
41
+ }
42
+
43
+ /**
44
+ * Prepare form
45
+ */
46
+ protected function _prepareForm()
47
+ {
48
+ $form = new Varien_Data_Form();
49
+
50
+ // get SmartFocus template
51
+ $emtModel = Mage::registry(Emv_Emt_Adminhtml_TemplateController::CURRENT_EMVEMT_TEMPLATE_REGISTRY);
52
+ if (null === $emtModel)
53
+ {
54
+ $emtModel = Mage::getModel('emvemt/emt');
55
+ } elseif ($emtModel->getId()) {
56
+ $form->addField('id', 'hidden', array(
57
+ 'name' => 'id',
58
+ ));
59
+ }
60
+
61
+ // set form to block
62
+ $this->setForm($form);
63
+
64
+ $fieldset = $form->addFieldset('emt_info',
65
+ array(
66
+ 'legend' => Mage::helper('emvemt')->__('Template Mapping Configuration'),
67
+ 'class' => 'fieldset-wide',
68
+ )
69
+ );
70
+
71
+ // build SmartFocus account select
72
+ $this->prepareEmailVisionAccountSelect($fieldset, $emtModel);
73
+ // build magento template select
74
+ $this->prepareMagentoTemplateSelect($fieldset, $emtModel);
75
+
76
+ // if emt is new, only display continue button
77
+ if (!$emtModel->getId()) {
78
+ $this->addJsTemplate($fieldset);
79
+
80
+ $fieldset->addField('continue_button', 'note', array(
81
+ 'text' => $this->getChildHtml('continue_button'),
82
+ ));
83
+ return ;
84
+ }
85
+
86
+ // add mail mode select
87
+ // javascript removing unused input according to selected send mail mode
88
+ $fieldset->addField('emv_send_mail_mode_id', 'select', array(
89
+ 'value' => $emtModel->getEmvSendMailModeId(),
90
+ 'label' => Mage::helper('emvemt')->__('Sending Mode'),
91
+ 'name' => 'emv_send_mail_mode_id',
92
+ 'required' => true,
93
+ 'class' => 'validate-select',
94
+ 'values' => Emv_Emt_Model_Mailmode::toOptionArray(),
95
+ ));
96
+
97
+ // Emailvision template select
98
+ $this->prepareEmailVisionTemplateSelect($fieldset, $emtModel);
99
+
100
+ // Handle the way of displaying get Emailvision template button.
101
+ $getEmvTemplateButtonParam = array(
102
+ 'text' => '<span id="emtTemplateButtonContainer" >'
103
+ . $this->getChildHtml('get_emv_templates').'</span>',
104
+ );
105
+ $fieldset->addField('emv_template_button', 'note', $getEmvTemplateButtonParam);
106
+
107
+ // date from
108
+ $dateFormatIso = Mage::app()->getLocale()->getDateFormat(
109
+ Mage_Core_Model_Locale::FORMAT_TYPE_SHORT
110
+ );
111
+ $dateFromParam = array(
112
+ 'value' => '',
113
+ 'label' => Mage::helper('emvemt')->__('From'),
114
+ 'name' => 'from_date',
115
+ 'image' => $this->getSkinUrl('images/grid-cal.gif'),
116
+ 'format' => $dateFormatIso,
117
+ );
118
+ $fieldset->addField('from_date', 'date', $dateFromParam);
119
+
120
+ // date to
121
+ $dateToParam = array(
122
+ 'value' => '',
123
+ 'label' => Mage::helper('emvemt')->__('To'),
124
+ 'name' => 'to_date',
125
+ 'image' => $this->getSkinUrl('images/grid-cal.gif'),
126
+ 'format' => $dateFormatIso,
127
+ );
128
+ $fieldset->addField('to_date', 'date', $dateToParam);
129
+ $this->addJsTemplate($fieldset);
130
+
131
+ // set template value into form
132
+ $form->setValues($emtModel->getData());
133
+ }
134
+
135
+ /**
136
+ * Add js template into form
137
+ *
138
+ * @param Varien_Data_Form_Element_Fieldset $fieldset
139
+ */
140
+ public function addJsTemplate(Varien_Data_Form_Element_Fieldset $fieldset)
141
+ {
142
+ // js block contains all common javascript functions
143
+ $jsBlock = $this->getLayout()->createBlock('adminhtml/template');
144
+ $jsBlock->setData('edit_block', $this)->setTemplate('emailvision/emt/template/common_js.phtml');
145
+ $fieldset->addField(
146
+ 'js_block',
147
+ 'note',
148
+ array(
149
+ 'note' => $jsBlock->toHtml(),
150
+ )
151
+ );
152
+ }
153
+ /**
154
+ * Prepare Magento Template Select Element
155
+ *
156
+ * @param Varien_Data_Form_Element_Fieldset $fieldset
157
+ * @param Emv_Emt_Model_Emt $emtModel
158
+ */
159
+ public function prepareMagentoTemplateSelect(Varien_Data_Form_Element_Fieldset $fieldset, Emv_Emt_Model_Emt $emtModel)
160
+ {
161
+ $error = $this->displayErrorMessage('mage_template_id');
162
+
163
+ $options = array();
164
+
165
+ if ($error || !$emtModel->getMageTemplateId() || !Mage::registry(Emv_Emt_Adminhtml_TemplateController::MAGE_TEMPLATE_NAME_REGISTRY)) {
166
+ $emvAccount = $this->getAccountCollection();
167
+ // try to get account model from emt object
168
+ $account = $emtModel->getAccount();
169
+ // else, get the first account from the list
170
+ if (!$account && $emvAccount->getSize()) {
171
+ $account = $emvAccount->getFirstItem();
172
+ }
173
+
174
+ /* @var $magentoTemplates Emv_Emt_Model_MageTemplate */
175
+ $magentoTemplates = Mage::getModel('emvemt/mageTemplate')
176
+ ->getNotMappedMageTemplateCollection($account->getId());
177
+ if ($magentoTemplates) {
178
+ $options = $magentoTemplates->toOptionArray();
179
+ }
180
+ } else {
181
+ $options[] = array(
182
+ 'value' => $emtModel->getMageTemplateId(),
183
+ 'label' => Mage::registry(Emv_Emt_Adminhtml_TemplateController::MAGE_TEMPLATE_NAME_REGISTRY)
184
+ );
185
+ }
186
+
187
+ if (count($options) == 0) {
188
+ $error = $this->displayErrorMessage(
189
+ 'mage_template_id',
190
+ Mage::helper('emvemt')
191
+ ->__('There is no Magento email templates which can be used for this account !')
192
+ );
193
+ }
194
+
195
+ // display all available Magento email templates
196
+ $fieldset->addField('mage_template_id', 'select', array(
197
+ 'value' => $emtModel->getMageTemplateId(),
198
+ 'label' => Mage::helper('emvemt')->__('Magento Template Name'),
199
+ 'name' => 'mage_template_id',
200
+ 'disabled' => ($error || !$emtModel->getEmvSendMailModeId()) ? false : true,
201
+ 'required' => true,
202
+ 'class' => 'validate-select',
203
+ 'values' => $options,
204
+ 'after_element_html' => $error
205
+ ));
206
+ }
207
+
208
+ /**
209
+ * Get Campaign Commmander Account collection
210
+ *
211
+ * @return Emv_Core_Model_Mysql4_Account_Collection
212
+ */
213
+ public function getAccountCollection()
214
+ {
215
+ if (!$this->_accountCollection) {
216
+ $accounts = Mage::getResourceModel('emvcore/account_collection');
217
+ $accounts->getSelect()
218
+ ->reset(Zend_Db_Select::COLUMNS)
219
+ ->columns(array('id', 'name')); // we only take two fields
220
+
221
+ $this->_accountCollection = $accounts;
222
+ }
223
+
224
+ return $this->_accountCollection;
225
+ }
226
+
227
+ /**
228
+ * Prepare EmailVision Account select element - for Campaign Commader Accounts
229
+ *
230
+ * @param Varien_Data_Form_Element_Fieldset $fieldset
231
+ * @param Emv_Emt_Model_Emt $emtModel
232
+ */
233
+ public function prepareEmailVisionAccountSelect(Varien_Data_Form_Element_Fieldset $fieldset, Emv_Emt_Model_Emt $emtModel)
234
+ {
235
+ $accountOptions = array();
236
+ if ($account = $emtModel->getAccount()) {
237
+ $accountOptions[] = array(
238
+ 'value' => $account->getId(),
239
+ 'label' => $account->getName()
240
+ );
241
+ } else {
242
+ $accounts = $this->getAccountCollection();
243
+ $accountOptions = $accounts->toOptionArray();
244
+ }
245
+
246
+ $error = $this->displayErrorMessage('emv_account_id');
247
+ $disable = true;
248
+ $onchange = '';
249
+ if (!$emtModel->getEmvAccountId() || $error) {
250
+ $disable = false;
251
+ }
252
+
253
+ // display all available SmartFocus accounts
254
+ $fieldset->addField('emv_account_id', 'select', array(
255
+ 'value' => $emtModel->getEmvAccountId(),
256
+ 'label' => Mage::helper('emvemt')->__('SmartFocus Account'),
257
+ 'name' => 'emv_account_id',
258
+ 'required' => true,
259
+ 'disabled' => $disable,
260
+ 'class' => 'validate-select',
261
+ 'values' => $accountOptions,
262
+ 'after_element_html' => $error,
263
+ ));
264
+ }
265
+
266
+ /**
267
+ * Prepare SmartFocus Templates
268
+ *
269
+ * @param Varien_Data_Form_Element_Fieldset $fieldset
270
+ * @param Emv_Emt_Model_Emt $emtModel
271
+ */
272
+ public function prepareEmailVisionTemplateSelect(Varien_Data_Form_Element_Fieldset $fieldset, Emv_Emt_Model_Emt $emtModel)
273
+ {
274
+ $values = array();
275
+ if (Mage::registry(Emv_Emt_Adminhtml_TemplateController::EMV_TEMPLATE_ARRAY_REGISTRY)) {
276
+ $values = array(Mage::registry(Emv_Emt_Adminhtml_TemplateController::EMV_TEMPLATE_ARRAY_REGISTRY));
277
+ }
278
+
279
+ $fieldset->addField(
280
+ 'emv_template_id',
281
+ 'select',
282
+ array(
283
+ 'value' => $emtModel->getEmvTemplateId(),
284
+ 'label' => Mage::helper('emvemt')->__('SmartFocus Template Name'),
285
+ 'name' => 'emv_template_id',
286
+ 'required' => true,
287
+ 'class' => 'validate-select',
288
+ 'values' => $values,
289
+ )
290
+ );
291
+ }
292
+
293
+ /**
294
+ * Display error messages for form elements
295
+ *
296
+ * @param string $id - field id
297
+ * @return string
298
+ */
299
+ public function displayErrorMessage($id, $message = null)
300
+ {
301
+ $invalidFields = Mage::registry(Emv_Emt_Adminhtml_TemplateController::INVALID_FIELD_EMV_TEMPLATE_REGISTRY);
302
+
303
+ $afterElementHtml = '';
304
+ $preparedMessage = $message;
305
+ if ($invalidFields && isset($invalidFields[$id])) {
306
+ $preparedMessage = $invalidFields[$id];
307
+ }
308
+
309
+ if($preparedMessage) {
310
+ $afterElementHtml = '<div id="advice-' . $id .'" class="validation-advice">';
311
+ $afterElementHtml .= $preparedMessage;
312
+ $afterElementHtml .= '</div>';
313
+ }
314
+
315
+ return $afterElementHtml;
316
+ }
317
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit/Tabs.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EmailVision email template edit form
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Template_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs
11
+ {
12
+ public function __construct()
13
+ {
14
+ parent::__construct();
15
+ $this->setId('emv_template_tabs');
16
+
17
+ // !!! set id where the content will be copied to
18
+ $this->setDestElementId('emv_template_edit_form');
19
+ $this->setTitle(Mage::helper('emvemt')->__('Template Information'));
20
+ }
21
+
22
+ /**
23
+ * Add different tabs into the menu
24
+ *
25
+ * (non-PHPdoc)
26
+ * @see Mage_Core_Block_Abstract::_prepareLayout()
27
+ */
28
+ protected function _prepareLayout()
29
+ {
30
+ $this->addTab('general', array(
31
+ 'label' => Mage::helper('emvemt')->__('General'),
32
+ 'content' => $this->getLayout()
33
+ ->createBlock('emvemt/adminhtml_template_edit_tab_general')->toHtml(),
34
+ 'active' => true
35
+ ));
36
+
37
+ $emvEmt = Mage::registry(Emv_Emt_Adminhtml_TemplateController::CURRENT_EMVEMT_TEMPLATE_REGISTRY);
38
+ if ($emvEmt && $emvEmt->getId()) {
39
+ $this->addTab('emv_dyn', array(
40
+ 'label' => Mage::helper('catalog')->__('EMV DYN Attribute Mapping'),
41
+ 'content' => $this->getLayout()
42
+ ->createBlock('emvemt/adminhtml_template_edit_tab_emvDyn')
43
+ ->toHtml(),
44
+ 'active' => false
45
+ ));
46
+
47
+ $this->addTab('emv_content', array(
48
+ 'label' => Mage::helper('catalog')->__('EMV CONTENT Attribute Mapping'),
49
+ 'content' => $this->getLayout()
50
+ ->createBlock('emvemt/adminhtml_template_edit_tab_emvContent')->toHtml(),
51
+ 'active' => false
52
+ ));
53
+ }
54
+
55
+ return parent::_prepareLayout();
56
+ }
57
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Template/Grid.php ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EmailVision email template grid
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Template_Grid extends Mage_Adminhtml_Block_Widget_Grid
11
+ {
12
+ /**
13
+ * Prepare collection for grid
14
+ *
15
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareCollection()
16
+ */
17
+ protected function _prepareCollection()
18
+ {
19
+ $collection = Mage::getResourceModel('emvemt/emt_collection');
20
+ $collection->prepareQueryToGetMagentoName();
21
+ $collection->prepareQueryToGetAccountName();
22
+ $collection->unselectEmvSendingTemplate();
23
+ $this->setCollection($collection);
24
+
25
+ parent::_prepareCollection();
26
+ }
27
+
28
+ /**
29
+ * Prepare column for campaign commander templates grid
30
+ *
31
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareColumns()
32
+ */
33
+ protected function _prepareColumns()
34
+ {
35
+ // id
36
+ $this->addColumn('id', array(
37
+ 'header' => Mage::helper('emvemt')->__('ID'),
38
+ 'index' => 'id',
39
+ 'type' => 'number',
40
+ ));
41
+
42
+ // Magento email template code
43
+ $this->addColumn('template_code', array(
44
+ 'header' => Mage::helper('emvemt')->__('Magento Template Name'),
45
+ 'index' => 'template_code',
46
+ 'type' => 'varchar',
47
+ 'renderer' => 'emvemt/adminhtml_template_grid_renderer_mageTemplate',
48
+ ));
49
+
50
+ // Created at
51
+ $this->addColumn('created_at', array(
52
+ 'header' => Mage::helper('sales')->__('Created At'),
53
+ 'type' => 'datetime',
54
+ 'width' => '110',
55
+ 'align' => 'center',
56
+ 'index' => 'created_at',
57
+ 'gmtoffset' => true
58
+ ));
59
+
60
+ // Update at
61
+ $this->addColumn('updated_at', array(
62
+ 'header' => Mage::helper('sales')->__('Updated At'),
63
+ 'type' => 'datetime',
64
+ 'width' => '110',
65
+ 'align' => 'center',
66
+ 'index' => 'updated_at',
67
+ 'gmtoffset' => true
68
+ ));
69
+
70
+ // Created at
71
+ $this->addColumn('account_name', array(
72
+ 'header' => Mage::helper('emvemt')->__('SmartFocus Account'),
73
+ 'type' => 'varchar',
74
+ 'align' => 'center',
75
+ 'index' => 'account_name',
76
+ ));
77
+
78
+ //list of all avaiable modes
79
+ $this->addColumn('emv_send_mail_mode_id',
80
+ array(
81
+ 'header'=> Mage::helper('emvemt')->__('Sending Mode'),
82
+ 'width' => '100px',
83
+ 'index' => 'emv_send_mail_mode_id',
84
+ 'type' => 'options',
85
+ 'options' => Emv_Emt_Model_Mailmode::getMailModesAndLabels(),
86
+ ));
87
+
88
+ // SmartFocus Template Id And Name
89
+ $this->addColumn('emv_template_id_and_name', array(
90
+ 'header' => Mage::helper('emvemt')->__('SmartFocus Template Id And Name'),
91
+ 'index' => 'emv_template_id_and_name',
92
+ 'type' => 'varchar',
93
+ 'filter' => false,
94
+ 'renderer' => 'emvemt/adminhtml_template_grid_renderer_emvname',
95
+ ));
96
+
97
+ // Action column
98
+ $this->addColumn('action', array(
99
+ 'header' => Mage::helper('emvemt')->__('Action'),
100
+ 'type' => 'action',
101
+ 'width' => '100',
102
+ 'getter' => 'getId',
103
+ 'actions' => array(
104
+ array(
105
+ 'caption' => Mage::helper('emvemt')->__('Edit'),
106
+ 'url' => array('base'=> '*/*/edit'),
107
+ 'field' => 'id',
108
+ )
109
+ ),
110
+ 'filter' => false,
111
+ 'sortable' => false,
112
+ 'is_system' => true,
113
+ ));
114
+
115
+ return parent::_prepareColumns();
116
+ }
117
+
118
+ /**
119
+ * (non-PHPdoc)
120
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareMassaction()
121
+ */
122
+ protected function _prepareMassaction()
123
+ {
124
+ $this->setMassactionIdField('entity_id');
125
+ $this->getMassactionBlock()->setFormFieldName('emt');
126
+
127
+ $this->getMassactionBlock()->addItem('delete', array(
128
+ 'label' => Mage::helper('customer')->__('Delete'),
129
+ 'url' => $this->getUrl('*/*/massDelete'),
130
+ 'confirm' => Mage::helper('customer')->__('Are you sure?')
131
+ ));
132
+
133
+ return $this;
134
+ }
135
+
136
+ /**
137
+ * Get row url
138
+ *
139
+ * @see Mage_Adminhtml_Block_Widget_Grid::getRowUrl()
140
+ * @return string
141
+ */
142
+ public function getRowUrl($row)
143
+ {
144
+ return $this->getUrl('*/*/edit', array('id' => $row->getId()));
145
+ }
146
+
147
+ /**
148
+ * Get row class - determine the row class according to invalidity information
149
+ *
150
+ * @param Varien_Object $emvEmt
151
+ * @return string
152
+ */
153
+ public function getRowClass(Varien_Object $emvEmt)
154
+ {
155
+ $class = "";
156
+ // if row does not have a valid magento template and account name -> set invalid css class
157
+ if (!$emvEmt->getData('template_code') || !$emvEmt->getData('account_name')) {
158
+ $class= "invalid";
159
+ }
160
+ return $class;
161
+ }
162
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Template/Grid/Renderer/Emvname.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Emt grid renderer for email vision template name
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Template_Grid_Renderer_Emvname extends
11
+ Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
12
+ {
13
+ /**
14
+ * Render mode
15
+ *
16
+ * @param Varien_Object $row
17
+ * @return string
18
+ */
19
+ public function render(Varien_Object $row)
20
+ {
21
+ $params = $row->getEmailVisionParams();
22
+ if (isset($params['emv_id']) && isset($params['emv_name'])) {
23
+ return $params['emv_id'] . ' / ' . $params['emv_name'];
24
+ }
25
+ }
26
+
27
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Template/Grid/Renderer/MageTemplate.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Emt grid renderer for email vision template name
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Template_Grid_Renderer_MageTemplate extends
11
+ Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
12
+ {
13
+ const INVALID_EMAIL_TEMPLATE = 'N/A';
14
+
15
+ /**
16
+ * Render mode
17
+ *
18
+ * @param Varien_Object $row
19
+ * @return string
20
+ */
21
+ public function render(Varien_Object $row)
22
+ {
23
+ if ($row->getTemplateCode()) {
24
+ return $row->getTemplateCode();
25
+ } else {
26
+ return self::INVALID_EMAIL_TEMPLATE;
27
+ }
28
+ }
29
+
30
+ }
app/code/community/Emv/Emt/Block/Adminhtml/Templates.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EmailVision email template grid wrapper
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Block_Adminhtml_Templates extends Mage_Adminhtml_Block_Widget_Grid_Container
11
+ {
12
+
13
+ public function __construct()
14
+ {
15
+ parent::__construct();
16
+ $this->_blockGroup = 'emvemt';
17
+ $this->_controller = 'adminhtml_template';
18
+ $this->_headerText = Mage::helper('emvemt')->__('SmartFocus Transactional Emails');
19
+ $this->_updateButton('add', 'label', Mage::helper('emvemt')->__('Add New Transactional Email'));
20
+ }
21
+ }
app/code/community/Emv/Emt/Constants.php DELETED
@@ -1,11 +0,0 @@
1
- <?php
2
- interface Emv_Emt_Constants
3
- {
4
- const ATTRIBUTE_TYPE_EMV_CONTENT = 'EMV_CONTENT';
5
-
6
- const ATTRIBUTE_TYPE_EMV_DYN = 'EMV_DYN';
7
-
8
- const EMV_CREATE_FLAG = 'emv create';
9
- const EMV_SEND_FLAG = 'emv send';
10
- const CLASSIC_FLAG = 'classic';
11
- }
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Emt/Helper/Data.php CHANGED
@@ -1,24 +1,13 @@
1
- <?php
2
- /**
3
- *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{528B8F2F-9AE2-4ac2-9593-847C94BBB789}
8
- */
9
- class Emv_Emt_Helper_Data extends Mage_Core_Helper_Abstract
10
- {
11
-
12
- /**
13
- * Encode the mixed $valueToEncode into the JSON format
14
- *
15
- * @param mixed $valueToEncode
16
- * @return string
17
- */
18
- public function jsonEncode($valueToEncode)
19
- {
20
- $json = Zend_Json::encode($valueToEncode);
21
-
22
- return $json;
23
- }
24
  }
1
+ <?php
2
+ /**
3
+ * Emt Helper
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Helper_Data extends Mage_Core_Helper_Abstract
11
+ {
12
+
 
 
 
 
 
 
 
 
 
 
 
13
  }
app/code/community/Emv/Emt/Helper/Emvtemplate.php CHANGED
@@ -1,77 +1,502 @@
1
  <?php
2
-
 
 
 
 
 
 
 
3
  class Emv_Emt_Helper_Emvtemplate extends Mage_Core_Helper_Abstract
4
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
 
6
  /**
7
  * Return an array of strings between [EMV DYN] and [EMV /DYN]
 
 
8
  */
9
  public function getEmvAttributesFromText($text)
10
  {
11
  preg_match_all('/\[EMV\sDYN\](.*)\[EMV\s\/DYN\]/U', $text, $attributes);
12
-
13
- return $attributes[1];
 
 
 
 
 
14
  }
15
 
16
  /**
17
  * Return an array of strings between [EMV CONTENT] and [EMV /CONTENT]
 
 
18
  */
19
  public function getEmvAttributesContentFromText($text)
20
  {
21
  preg_match_all('/\[EMV\sCONTENT\](.*)\[EMV\s\/CONTENT\]/U', $text, $attributes);
22
 
23
- return $attributes[1];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  }
25
 
26
  /**
27
- * Convert an array of mapping to an array understandable by the webservice method sendObject
28
- * @param array $attributes
29
  */
30
- public function _attributesToWebServiceRequest($attributes)
31
  {
32
- $wsArray = array();
33
- foreach($attributes as $key => $value)
34
- {
35
- $wsArray[] = array('key' => $key, 'value' => $value);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  }
37
 
38
- return array('entry' => $wsArray);
 
 
 
39
  }
40
 
41
- public function getEMVTemplateName($emvTemplateId, $emvAccountId)
 
 
 
 
 
 
 
 
 
 
42
  {
43
- $name = '';
44
- if($emvTemplateId !== null)
45
- {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  try {
 
 
 
 
 
 
 
 
47
 
48
- /* @var $account Emv_Core_Model_Account */
49
- $account = Mage::getModel('emvcore/account')->load($emvAccountId);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
- /* @var $soap Emv_Core_Model_Service_Soap_Api */
52
- $soap = Mage::getModel('emvcore/service_soap_api', $account);
53
 
54
- $EMVTemplate = $soap->getTemplateById($emvTemplateId);
 
 
 
 
 
 
55
 
56
- if(isset($EMVTemplate->name))
57
- {
58
- $name = $emvTemplateId. ' / ' . $EMVTemplate->name;
59
- }
60
- else
61
- {
62
- $name = $emvTemplateId. ' / No Name';
63
- }
 
 
 
 
64
 
65
- } catch (Exception $e) {
66
- // if we couln't connect to the WS we just display the Id
67
- $name = $emvTemplateId;
 
 
 
 
 
 
68
  }
69
  }
70
- else
71
- {
72
- $name = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
74
 
75
- return $name;
76
  }
77
  }
1
  <?php
2
+ /**
3
+ * EmailVision Email template Helper
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
  class Emv_Emt_Helper_Emvtemplate extends Mage_Core_Helper_Abstract
11
  {
12
+ /**
13
+ * Xml path for different configurations
14
+ */
15
+ const XML_PATH_LOG_ENABLED = 'emvemt/transactional_service/log_enabled';
16
+ const XML_PATH_SENDING_PARAMETER_LOG_ENABLED = 'emvemt/transactional_service/parameter_log_enabled';
17
+
18
+ /**
19
+ * SmartFocus attributes for a current SmartFocus template from registry
20
+ * @var array
21
+ */
22
+ protected $_emvFields = null;
23
+
24
+ /**
25
+ * List of sorted mapped attributes
26
+ * @var array
27
+ */
28
+ protected $_sortedMappedAttributes = null;
29
+
30
+ /**
31
+ * List of different accounts and their associated default templates
32
+ *
33
+ * @var array
34
+ */
35
+ protected $_accountAndDefaultTemplates = array();
36
 
37
  /**
38
  * Return an array of strings between [EMV DYN] and [EMV /DYN]
39
+ *
40
+ * @return array
41
  */
42
  public function getEmvAttributesFromText($text)
43
  {
44
  preg_match_all('/\[EMV\sDYN\](.*)\[EMV\s\/DYN\]/U', $text, $attributes);
45
+ $sortedAttributes = array();
46
+ if (isset($attributes[1])) {
47
+ foreach($attributes[1] as $name) {
48
+ $sortedAttributes[$name] = $name;
49
+ }
50
+ }
51
+ return $sortedAttributes;
52
  }
53
 
54
  /**
55
  * Return an array of strings between [EMV CONTENT] and [EMV /CONTENT]
56
+ *
57
+ * @return array
58
  */
59
  public function getEmvAttributesContentFromText($text)
60
  {
61
  preg_match_all('/\[EMV\sCONTENT\](.*)\[EMV\s\/CONTENT\]/U', $text, $attributes);
62
 
63
+ $sortedAttributes = array();
64
+ if (isset($attributes[1])) {
65
+ foreach($attributes[1] as $name) {
66
+ $sortedAttributes[$name] = $name;
67
+ }
68
+ }
69
+
70
+ return $sortedAttributes;
71
+ }
72
+
73
+ /**
74
+ * Get all attributes (dyn content and dyn attributes)
75
+ *
76
+ * @param stdClass $template
77
+ * @param string $emvTemplateId
78
+ * @param string $emvAccountId
79
+ * @return array
80
+ */
81
+ public function getAllDynContentAndAttributes(stdClass $template = null, $emvTemplateId = '', $emvAccountId ='')
82
+ {
83
+ $text = '';
84
+ if ($template) {
85
+ $text = '';
86
+ if (isset($template->body)) {
87
+ $text .= $template->body;
88
+ }
89
+ if (isset($template->from)) {
90
+ $text .= $template->from;
91
+ }
92
+ if (isset($template->to)) {
93
+ $text .= $template->to;
94
+ }
95
+ if(isset($template->replyTo)) {
96
+ $text .= $template->replyTo;
97
+ }
98
+ if(isset($template->replyToEmail)) {
99
+ $text .= $template->replyToEmail;
100
+ }
101
+ if(isset($template->subject)) {
102
+ $text .= $template->subject;
103
+ }
104
+ }
105
+
106
+ $result = array(
107
+ Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_CONTENT => $this->getEmvAttributesContentFromText($text),
108
+ Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_DYN => $this->getEmvAttributesFromText($text)
109
+ );
110
+ return $result;
111
+ }
112
+
113
+ /**
114
+ * Get data necessary for email sending
115
+ *
116
+ * @param string $mageTemplateId
117
+ * @param string $accountId
118
+ * @return array
119
+ */
120
+ public function getDataForSending($mageTemplateId, $accountId)
121
+ {
122
+ $collection = $this->getCollectionForSending($mageTemplateId, $accountId);
123
+ $result = $collection->getFirstItem();
124
+
125
+ // prepare account
126
+ $account = Mage::getModel('emvcore/account');
127
+ $account->setData($result->getData());
128
+ $account->setId($result->getData('account_id'));
129
+
130
+ // tmp_sending
131
+ $tmpSending = Mage::getModel('emvemt/emt');
132
+ $tmpSending->setEmvParameters($result->getData('sending_template.emv_parameters'));
133
+ $tmpSending->setEmvTemplateId($result->getData('sending_template.emv_template_id'));
134
+
135
+ // prepare magento template name and original template name
136
+ $mageTemplateName = $result->getData('magento_template');
137
+ $origTemplateName = $result->getData('original_magento_template');
138
+ if (!$result->getData('magento_template') || !$result->getData('original_magento_template')) {
139
+ $magentoTemplates = Mage::getResourceModel('core/email_template_collection');
140
+ $magentoTemplates->getSelect()
141
+ ->reset(Zend_Db_Select::COLUMNS)
142
+ // only get template_id, template_code, orig_template_code
143
+ ->columns(array('template_id', 'template_code', 'orig_template_code'));
144
+ $magentoTemplates->addFieldToFilter('template_id ', array('eq' => $mageTemplateId));
145
+ $template = $magentoTemplates->getFirstItem();
146
+
147
+ $mageTemplateName = $template->getData('template_code');
148
+ $origTemplateName = $template->getData('orig_template_code');
149
+ }
150
+
151
+ $data = array(
152
+ 'emv_template' => $result,
153
+ 'account' => $account,
154
+ 'tmp_sending' => $tmpSending,
155
+
156
+ 'magento_template_name' => ($mageTemplateName != null) ? $mageTemplateName : $mageTemplateId,
157
+ 'original_magento_template_name' => ($origTemplateName != null) ? $origTemplateName : $mageTemplateId
158
+ );
159
+
160
+ return $data;
161
+ }
162
+
163
+ /**
164
+ * Get collection to retreive objects for email sending
165
+ *
166
+ * @param string $mageTemplateId
167
+ * @param string $accountId
168
+ * @return Emv_Emt_Model_Mysql4_Emt_Collection
169
+ */
170
+ public function getCollectionForSending($mageTemplateId, $accountId)
171
+ {
172
+ $emtModel = Mage::getModel('emvemt/emt');
173
+ $collection = $emtModel->getCollection();
174
+
175
+ $select = $collection->getSelect();
176
+ $resource = Mage::getSingleton('core/resource');
177
+ $emtTable = $resource->getTableName('emvemt/emt');
178
+ $accountTable = $resource->getTableName('emvcore/account');
179
+ $magentoEmailTable = $resource->getTableName('core/email_template');
180
+
181
+ // get SmartFocus sending template
182
+ $codition = 'tmp_sending.emv_account_id = main_table.emv_account_id AND tmp_sending.mage_template_id = "'
183
+ . Emv_Emt_Model_Emt::MAGENTO_TEMPLATE_ID_FOR_EMV_SEND . '"'
184
+ . ' AND tmp_sending.emv_send_mail_mode_id = ' . Emv_Emt_Model_Mailmode::EMV_CREATE
185
+ ;
186
+ $select->joinLeft(
187
+ array('tmp_sending' => $emtTable),
188
+ $codition,
189
+ array(
190
+ 'sending_template.emv_template_id' => 'tmp_sending.emv_template_id',
191
+ 'sending_template.emv_parameters' => 'tmp_sending.emv_parameters',
192
+ )
193
+ );
194
+
195
+ // get information for associated account
196
+ $select->join(
197
+ array('account' => $accountTable),
198
+ 'account.id = main_table.emv_account_id',
199
+ array(
200
+ 'account_id' => 'id',
201
+ 'account_name' => 'name',
202
+ 'account_login',
203
+ 'account_password',
204
+ 'manager_key',
205
+ 'use_proxy',
206
+ 'proxy_host',
207
+ 'proxy_port',
208
+ 'emv_urls'
209
+ )
210
+ );
211
+
212
+ // get magento template code, orignal template code
213
+ $select->join(
214
+ array('magento_template' => $magentoEmailTable),
215
+ 'magento_template.template_id = main_table.mage_template_id',
216
+ array(
217
+ 'magento_template' => 'template_code',
218
+ 'original_magento_template' => 'orig_template_code'
219
+ )
220
+ );
221
+
222
+ $select->where('main_table.emv_account_id = ?', $accountId);
223
+ $select->where('main_table.mage_template_id = ?', $mageTemplateId);
224
+
225
+ return $collection;
226
  }
227
 
228
  /**
229
+ * Need to log sending?
230
+ * @return boolean
231
  */
232
+ public function needToLogSending($storeId = null)
233
  {
234
+ return (bool)Mage::getStoreConfigFlag(self::XML_PATH_LOG_ENABLED, $storeId);
235
+ }
236
+
237
+ /**
238
+ * Need to log all Sending parameters ?
239
+ * @return boolean
240
+ */
241
+ public function needToLogEmvParameters($storeId = null)
242
+ {
243
+ return (bool)Mage::getStoreConfigFlag(self::XML_PATH_SENDING_PARAMETER_LOG_ENABLED, $storeId);
244
+ }
245
+
246
+ /**
247
+ * Prepare Log before sending email
248
+ *
249
+ * @param string $mode
250
+ * @param array $sendingData
251
+ * @param array | string $emails
252
+ * @param string $storeId
253
+ * @param string $type
254
+ * @return Emv_Emt_Model_Log
255
+ */
256
+ public function prepareLogBeforeSend($mode, $sendingData, $emails, $storeId = null, $type = Emv_Emt_Model_Log::SENDING_BASIC_WORKFLOW)
257
+ {
258
+ $log = Mage::getModel('emvemt/log');
259
+ $log->setSendingMode($mode);
260
+ $log->setEmail($emails);
261
+ $log->setSendingType($type);
262
+ $log->setStoreId($storeId);
263
+
264
+ if (isset($sendingData['account']) && $sendingData['account']->getId()) {
265
+ $log->setAccountId($sendingData['account']->getId());
266
  }
267
 
268
+ $log->setMagentoTemplateName($sendingData['magento_template_name']);
269
+ $log->setOriginalMagentoTemplateName($sendingData['original_magento_template_name']);
270
+
271
+ return $log;
272
  }
273
 
274
+ /**
275
+ * Prepare log after sending email
276
+ *
277
+ * @param Emv_Emt_Model_Log $log
278
+ * @param array $lastData
279
+ * @param array $emails
280
+ * @param boolean $sucess
281
+ * @param array $error
282
+ * @return Emv_Emt_Model_Log
283
+ */
284
+ public function prepareLogAfterSend(Emv_Emt_Model_Log $log, $lastData = array(), $emails, $sucess, $error = array(), $storeId = null)
285
  {
286
+ $log->setSentSucess($sucess);
287
+
288
+ $needToSave = $this->needToLogSending($storeId);
289
+
290
+ if (isset($lastData['emv_name'])) {
291
+ $log->setEmvName($lastData['emv_name']);
292
+ }
293
+
294
+ // set email
295
+ $log->setEmail($emails);
296
+
297
+ if (!empty($error)) {
298
+ // only log error email
299
+ $needToSave = true;
300
+ if (isset($error['msg'])) {
301
+ $log->setError($error['msg']);
302
+ }
303
+ if (isset($error['code'])) {
304
+ $log->setErrorCode($error['code']);
305
+ }
306
+ }
307
+
308
+ if ($this->needToLogEmvParameters($storeId) || !empty($error)) {
309
+ if (isset($lastData['emv_encrypt']) && isset($lastData['emv_id']) && isset($lastData['emv_random'])) {
310
+ $log->setEmvParams(
311
+ array(
312
+ 'emv_encrypt' => $lastData['emv_encrypt'],
313
+ 'emv_id' => $lastData['emv_id'],
314
+ 'emv_random' => $lastData['emv_random'],
315
+ 'emv_name' => $lastData['emv_name'],
316
+ )
317
+ );
318
+ }
319
+ if (isset($lastData['emv_content_variables'])) {
320
+ $log->setEmvContentVariables($lastData['emv_content_variables']);
321
+ }
322
+ if (isset($lastData['emv_dyn_variables'])) {
323
+ $log->setEmvDynVariables($lastData['emv_dyn_variables']);
324
+ }
325
+ }
326
+
327
+ if ($needToSave) {
328
+ // save in the new object
329
+ $log->unsId();
330
+
331
  try {
332
+ $log->save();
333
+ } catch(Exception $e) {
334
+ Mage::logException($e);
335
+ }
336
+ }
337
+
338
+ return $log;
339
+ }
340
 
341
+ /**
342
+ * Check if EmailVision parameters are correct
343
+ * @param array $params
344
+ * @return boolean
345
+ */
346
+ public function validateEmvParams($params = array())
347
+ {
348
+ $result = true;
349
+ if (
350
+ isset($params['emv_encrypt']) == false
351
+ || isset($params['emv_random']) == false
352
+ || isset($params['emv_id']) == false
353
+ || isset($params['emv_name']) == false
354
+ ) {
355
+ // throw exception
356
+ Mage::throwException('SmartFocus template parameters are not valid !');
357
+ }
358
 
359
+ return $result;
360
+ }
361
 
362
+ /**
363
+ * @param Emv_Core_Model_Account $account
364
+ */
365
+ public function checkAndCreateDefaultSendingTemplate(Emv_Core_Model_Account $account)
366
+ {
367
+ $defaultEmt = Mage::getModel('emvemt/emt');
368
+ $defaultEmt->setAccount($account);
369
 
370
+ $existingDefault = $this->getEmvEmt(Emv_Emt_Model_Emt::MAGENTO_TEMPLATE_ID_FOR_EMV_SEND, $account->getId());
371
+ $needToCreate = false;
372
+ if ($existingDefault && $existingDefault->getId()) {
373
+ if (!$existingDefault->getEmvTemplate()) {
374
+ $needToCreate = true;
375
+ $defaultEmt->setId($existingDefault->getId());
376
+ } else {
377
+ $defaultEmt = $existingDefault;
378
+ }
379
+ } else {
380
+ $needToCreate = true;
381
+ }
382
 
383
+ if ($needToCreate) {
384
+ $service = Mage::getModel('emvcore/service_transactional');
385
+ $service->setAccount($account);
386
+ $emvTemplate = $service->checkOrCreateEmvDefaultSendTemplate();
387
+ if ($emvTemplate) {
388
+ $defaultEmt->setEmvTemplate($emvTemplate);
389
+ $defaultEmt->setEmvSendMailModeId(Emv_Emt_Model_Mailmode::EMV_CREATE);
390
+ $defaultEmt->setMageTemplateId(Emv_Emt_Model_Emt::MAGENTO_TEMPLATE_ID_FOR_EMV_SEND);
391
+ $defaultEmt->save();
392
  }
393
  }
394
+
395
+ return $defaultEmt;
396
+ }
397
+
398
+ /**
399
+ * Get an account model and its associated default template
400
+ *
401
+ * @param string $accountId
402
+ * @return array :
403
+ * - account
404
+ * - tmp_sending
405
+ */
406
+ public function getAccountAndDefaultTemplate($accountId)
407
+ {
408
+ if (!isset($this->_accountAndDefaultTemplates[$accountId])) {
409
+ $account = Mage::getModel('emvcore/account')->load($accountId);
410
+
411
+ $defaultEmt = Mage::getModel('emvemt/emt');
412
+ $existingEmt = $this->getEmvEmt(Emv_Emt_Model_Emt::MAGENTO_TEMPLATE_ID_FOR_EMV_SEND, $accountId);
413
+ if ($existingEmt && $existingEmt->getId()) {
414
+ $defaultEmt = $existingEmt;
415
+ }
416
+
417
+ $this->_accountAndDefaultTemplates[$accountId] = array('account' => $account, 'tmp_sending' => $defaultEmt);
418
+ }
419
+
420
+ return $this->_accountAndDefaultTemplates[$accountId];
421
+ }
422
+
423
+ /**
424
+ * Get SmartFocus mapped template for a given magento template id and account id
425
+ *
426
+ * @param string $mageTemplateId
427
+ * @param string $accountId
428
+ * @return Emv_Emt_Model_Emt
429
+ */
430
+ public function getEmvEmt($mageTemplateId, $accountId)
431
+ {
432
+ $emvCollection = Mage::getResourceModel('emvemt/emt_collection');
433
+ $emvCollection->addAccountFilter($accountId)
434
+ ->addMageTemplateFilter($mageTemplateId);
435
+ $emt = $emvCollection->getFirstItem();
436
+
437
+ return $emt;
438
+ }
439
+
440
+ /**
441
+ * Get all dynamic and content attributes for a current SmartFocus template from registry
442
+ * - if we have some problems => return empty array
443
+ *
444
+ * @return array | false - if we have a problem to connect to the webservice
445
+ */
446
+ public function getAllEmvFieldsFromRegistry()
447
+ {
448
+ if ($this->_emvFields === null) {
449
+ $availableAttributes = Mage::registry(Emv_Emt_Adminhtml_TemplateController::EMV_AVAILABLE_ATTRIBUTE_REGISTRY);
450
+ if ($availableAttributes) {
451
+ $this->_emvFields = $availableAttributes;
452
+ } else {
453
+ $invalidField = Mage::registry(Emv_Emt_Adminhtml_TemplateController::INVALID_FIELD_EMV_TEMPLATE_REGISTRY);
454
+ $currentEmv = Mage::registry(Emv_Emt_Adminhtml_TemplateController::CURRENT_EMVEMT_TEMPLATE_REGISTRY);
455
+
456
+ $this->_emvFields = array();
457
+ if (!$invalidField || !isset($invalidField['emv_template_id'])) {
458
+ if (
459
+ $currentEmv
460
+ && $currentEmv instanceof Emv_Emt_Model_Emt
461
+ && $currentEmv->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::EMV_CREATE
462
+ ) {
463
+ try {
464
+ if ($currentEmv->getEmvTemplate()) {
465
+ $this->_emvFields = $this->getAllDynContentAndAttributes($currentEmv->getEmvTemplate());
466
+ }
467
+ } catch (Exception $e) {
468
+ Mage::logException($e);
469
+ $this->_emvFields = false;
470
+ }
471
+ }
472
+ }
473
+ }
474
+ }
475
+
476
+ return $this->_emvFields;
477
+ }
478
+
479
+ /**
480
+ * Prepare a list of all mapped attributes from registry.
481
+ * The mapped attributes are sorted by their SmartFocus attribute name
482
+ *
483
+ * @return array
484
+ */
485
+ public function getSortedMappedAttributesFromRegistry()
486
+ {
487
+ if ($this->_sortedMappedAttributes === null) {
488
+ $attributeData = Mage::registry(Emv_Emt_Adminhtml_TemplateController::EMV_ATTRIBUTES_REGISTRY);
489
+ $this->_sortedMappedAttributes = array();
490
+ if ($attributeData && is_array($attributeData)) {
491
+ foreach ($attributeData as $data) {
492
+ if (!isset($this->_sortedMappedAttributes[$data['emv_attribute_type']])) {
493
+ $this->_sortedMappedAttributes[$data['emv_attribute_type']] = array();
494
+ }
495
+ $this->_sortedMappedAttributes[$data['emv_attribute_type']][$data['emv_attribute']] = $data;
496
+ }
497
+ }
498
  }
499
 
500
+ return $this->_sortedMappedAttributes;
501
  }
502
  }
app/code/community/Emv/Emt/Model/Adminhtml/System/Config/Backend/Account.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Account Backend model for Transactionnal Messages(NMP)
4
+ *
5
+ * @category Emv
6
+ * @package Emv_DataSync
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ */
9
+ class Emv_Emt_Model_Adminhtml_System_Config_Backend_Account extends Emv_Core_Model_Adminhtml_System_Config_Backend_Account_Abstract
10
+ {
11
+ /**
12
+ * @var string
13
+ */
14
+ protected $_urlType = Emv_Core_Model_Account::URL_TRANSACTIONAL_SERVICE_TYPE;
15
+
16
+ /**
17
+ * (non-PHPdoc)
18
+ * @see Emv_Core_Model_Adminhtml_System_Config_Backend_Account_Abstract::_getService()
19
+ */
20
+ protected function _getService()
21
+ {
22
+ return Mage::getModel('emvcore/service_transactional');
23
+ }
24
+
25
+ /**
26
+ * (non-PHPdoc)
27
+ * @see Emv_Core_Model_Adminhtml_System_Config_Backend_Account_Abstract::_beforeSave()
28
+ */
29
+ protected function _beforeSave()
30
+ {
31
+ if ($this->isValueChanged() && $this->getValue()) {
32
+ $account = $this->_getAccount();
33
+ if (!$account->getId()) {
34
+ Mage::throwException(Mage::helper('emvcore')->__('Your selected account does not exist anymore!'));
35
+ }
36
+
37
+ // check url
38
+ $url = $this->_checkAndGetUrlForType($account, $this->_urlType);
39
+
40
+ try {
41
+ // check credentials
42
+ Mage::helper('emvemt/emvtemplate')->checkAndCreateDefaultSendingTemplate($account);
43
+ } catch (EmailVision_Api_Exception $e) {
44
+ if ($e->isRecoverable()) {
45
+ Mage::throwException(
46
+ Mage::helper('emvcore')
47
+ ->__('Could not verify the account. Network problems occured! Please Save again!')
48
+ );
49
+ } else {
50
+ Mage::throwException($e->getMessage());
51
+ }
52
+ }
53
+
54
+ $this->_checkAndGetUrlForType($account, Emv_Core_Model_Account::URL_REST_NOTIFICATION_SERVICE_TYPE);
55
+ }
56
+
57
+ return Mage_Core_Model_Abstract::_beforeSave();
58
+ }
59
+ }
app/code/community/Emv/Emt/Model/Attribute.php CHANGED
@@ -1,6 +1,29 @@
1
  <?php
 
 
 
 
 
 
 
 
2
  class Emv_Emt_Model_Attribute extends Mage_Catalog_Model_Abstract
3
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  protected function _construct()
5
  {
6
  $this->_init('emvemt/attribute');
@@ -10,22 +33,14 @@ class Emv_Emt_Model_Attribute extends Mage_Catalog_Model_Abstract
10
  {
11
  $error = array();
12
 
13
- if (!Zend_Validate::is($this->getMageAttribute(), 'NotEmpty')) {
14
- $errors[] = Mage::helper('emvemt')->__('Magento attribute is required.');
15
- }
16
-
17
  if (!Zend_Validate::is($this->getEmvAttribute(), 'NotEmpty')) {
18
- $errors[] = Mage::helper('emvemt')->__('Campaign Commander attribute is required.');
19
- }
20
-
21
- if ($this->mageAttributeExists()) {
22
- $errors[] = Mage::helper('emvemt')->__("Magento attribute '%s' is already mapped.",
23
- $this->htmlEscape($this->getMageAttribute()));
24
  }
25
 
26
- if ($this->emvAttributeExists()) {
27
- $errors[] = Mage::helper('emvemt')->__("Campaign Commander attribute '%s' is already mapped.",
28
- $this->htmlEscape($this->getEmvAttribute()));
 
29
  }
30
 
31
  if (empty($errors)) {
@@ -34,12 +49,22 @@ class Emv_Emt_Model_Attribute extends Mage_Catalog_Model_Abstract
34
  return $errors;
35
  }
36
 
 
 
 
 
 
37
  public function mageAttributeExists()
38
  {
39
  $result = $this->_getResource()->mageAttributeExists($this);
40
  return (is_array($result) && count($result) > 0 ) ? true : false;
41
  }
42
 
 
 
 
 
 
43
  public function emvAttributeExists()
44
  {
45
  $result = $this->_getResource()->emvAttributeExists($this);
1
  <?php
2
+ /**
3
+ * Attribute mapping class
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
  class Emv_Emt_Model_Attribute extends Mage_Catalog_Model_Abstract
11
  {
12
+ /**
13
+ * EmailVision Dynamic Attribute type
14
+ */
15
+ const ATTRIBUTE_TYPE_EMV_DYN = 'EMV_DYN';
16
+
17
+ /**
18
+ * EmailVision Dynamic content type
19
+ */
20
+ const ATTRIBUTE_TYPE_EMV_CONTENT = 'EMV_CONTENT';
21
+
22
+ /**
23
+ * Constructor
24
+ *
25
+ * @see Varien_Object::_construct()
26
+ */
27
  protected function _construct()
28
  {
29
  $this->_init('emvemt/attribute');
33
  {
34
  $error = array();
35
 
 
 
 
 
36
  if (!Zend_Validate::is($this->getEmvAttribute(), 'NotEmpty')) {
37
+ $errors[] = Mage::helper('emvemt')->__('SmartFocus attribute is required !');
 
 
 
 
 
38
  }
39
 
40
+ if (!Zend_Validate::is($this->getEmvAttributeType(), 'NotEmpty')) {
41
+ $errors[] = Mage::helper('emvemt')->__('Please provide the attribute type !');
42
+ } else if(!in_array($this->getEmvAttributeType(), array(self::ATTRIBUTE_TYPE_EMV_CONTENT, self::ATTRIBUTE_TYPE_EMV_DYN))) {
43
+ $errors[] = Mage::helper('emvemt')->__('Unknown attribute type !');
44
  }
45
 
46
  if (empty($errors)) {
49
  return $errors;
50
  }
51
 
52
+ /**
53
+ * Check if this used mageno attribute already exists in other mapping
54
+ *
55
+ * @return boolean
56
+ */
57
  public function mageAttributeExists()
58
  {
59
  $result = $this->_getResource()->mageAttributeExists($this);
60
  return (is_array($result) && count($result) > 0 ) ? true : false;
61
  }
62
 
63
+ /**
64
+ * Check if this used SmartFocus attribute already exists in other mapping
65
+ *
66
+ * @return boolean
67
+ */
68
  public function emvAttributeExists()
69
  {
70
  $result = $this->_getResource()->emvAttributeExists($this);
app/code/community/Emv/Emt/Model/Cron.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EmailVision emt cron model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Model_Cron
11
+ {
12
+ /**
13
+ * Process all error sending emails
14
+ * - convert all error sending emails into rescheduled queue messages
15
+ * - send the last rescheduled queue messages to SmartFocus platform
16
+ */
17
+ public function processErrorSendingEmails()
18
+ {
19
+ $resendingQueue = Mage::getModel('emvemt/resending_queue');
20
+ $rule = $resendingQueue->getRule();
21
+
22
+ if ($rule->lockExists()) {
23
+ return;
24
+ }
25
+
26
+ // create lock file, in order to prevent from launching several process at the same time
27
+ $rule->createLock();
28
+
29
+ try {
30
+ $resendingQueue->sendPendingMessages();
31
+ $resendingQueue->rescheduleErrorSending();
32
+ } catch(Exception $e) {
33
+ Mage::logException($e);
34
+ }
35
+
36
+ // remove lock file
37
+ $rule->removeLock();
38
+ }
39
+ }
app/code/community/Emv/Emt/Model/Emt.php CHANGED
@@ -1,16 +1,44 @@
1
  <?php
2
  /**
 
3
  *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{2EB12F64-51A5-4e90-9048-2BE20B080487}
8
  */
9
  class Emv_Emt_Model_Emt extends Mage_Core_Model_Abstract
10
  {
 
11
 
12
  /**
13
- * opGUID{B23F7DF5-EE1D-4947-9B8E-415CDB6F889F}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  */
15
  public function _construct()
16
  {
@@ -18,30 +46,128 @@ class Emv_Emt_Model_Emt extends Mage_Core_Model_Abstract
18
  }
19
 
20
  /**
21
- * opGUID{EDA1DA15-1173-4b9c-ACA9-F11EF205DCE2}
 
 
 
22
  */
23
- protected function beforeSave()
24
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  return parent::_beforeSave();
26
  }
27
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
28
  /**
29
  * Validate first page of emt creation
 
 
30
  */
31
  public function validateNewForm()
32
  {
33
  $error = array();
34
 
35
  if (!Zend_Validate::is($this->getEmvAccountId(), 'NotEmpty')) {
36
- $errors[] = Mage::helper('emvemt')->__('An EMV account is required.');
 
 
 
 
 
 
 
 
37
  }
38
 
39
  if (!Zend_Validate::is($this->getMageTemplateId(), 'NotEmpty')) {
40
- $errors[] = Mage::helper('emvemt')->__('A Magento template is required.');
41
- }
42
-
43
- if ($this->mageTemplateMapped()) {
44
- $errors[] = Mage::helper('emvemt')->__('This Magento template is already mapped.');
 
 
45
  }
46
 
47
  if (empty($errors)) {
@@ -51,59 +177,136 @@ class Emv_Emt_Model_Emt extends Mage_Core_Model_Abstract
51
  }
52
 
53
  /**
54
- * opGUID{A7EFFDD7-1441-4e26-BCEE-3DCEEAFBE894}
 
 
55
  */
56
- public function validate()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
  {
58
- $return = $this->validateNewForm();
 
 
 
 
 
 
 
59
 
60
- if(is_array($return))
61
- {
62
- $errors = $this->validateNewForm();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
- else
65
- {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  $errors = array();
67
  }
68
 
 
69
  if (!Zend_Validate::is($this->getEmvSendMailModeId(), 'NotEmpty')) {
70
- $errors[] = Mage::helper('emvemt')->__('Send mail mode is required.');
71
- }
72
- else
73
- {
74
- /* @var $mailModeModel Emv_Emt_Model_MailMode_Collection */
75
- $mailMode = Mage::getModel('emvemt/mailmode')->load($this->getSendMailModeId());
76
- if (null === $mailMode)
77
- {
78
- $errors[] = Mage::helper('emvemt')->__('This send mail mode don\'t exists.');
 
79
  }
80
  }
81
 
82
- if ($this->getEmvSendMailModeId() ==
83
- Mage::getModel('emvemt/mailmode')->getIdByName('emv create'))
84
- {
85
-
86
- if (!Zend_Validate::is($this->getEmvTemplateId(), 'NotEmpty'))
87
- {
88
- $errors[] = Mage::helper('emvemt')->__('Campaign Commander template is required.');
89
- }
90
- else
91
- {
92
  try {
93
- /* @var $account Emv_Core_Model_Account */
94
- $account = Mage::getModel('emvcore/account')->load($this->getEmvAccountId());
95
-
96
- /* @var $emvApiModel Emv_Core_Model_Service_Soap_Api */
97
- $emvApiModel = Mage::getModel('emvcore/service_soap_api', $account);
98
-
99
- if (null === $emvApiModel->getTemplateById($this->getEmvTemplateId()))
100
- {
101
- $errors[] = Mage::helper('emvemt')
102
- ->__('This Campaign Commander template don\'t exists.');
103
- }
104
  } catch (Exception $e) {
105
  $errors[] = $e->getMessage();
106
  }
 
 
 
 
 
107
  }
108
  }
109
 
@@ -113,61 +316,58 @@ class Emv_Emt_Model_Emt extends Mage_Core_Model_Abstract
113
  return $errors;
114
  }
115
 
116
- public function mageTemplateMapped()
117
- {
118
- $result = $this->_getResource()->mageTemplateMapped($this);
119
- return (is_array($result) && count($result) > 0 ) ? true : false;
120
- }
121
-
122
- public function emvTemplateExists()
123
- {
124
- $result = $this->_getResource()->emvTemplateExists($this);
125
- return (is_array($result) && count($result) > 0 ) ? true : false;
126
- }
127
-
128
  /**
129
- * Return send mail mode according to template and store id
130
- * @param $templateId
131
- * @param $storeId
 
132
  */
133
- public function getMode($templateId, $storeId)
134
  {
135
- $accountId = Mage::getStoreConfig('emvcore/emv_account/account', $storeId);
136
 
137
- if($accountId === null || $accountId == 0)
138
- {
139
- return null;
 
 
 
 
 
 
140
  }
141
 
142
- $emts = $this->_getEmtFromTemplateIdAndAccountId($templateId, $accountId);
143
- $emts->getMailModeName();
144
- $emt = $emts->getFirstItem();
 
 
 
 
 
145
 
146
- return $emt->getName();
147
  }
148
 
149
- public function getEmvEmt($mageTemplateId, $accountId)
 
 
 
 
 
150
  {
151
- $emts = $this->_getEmtFromTemplateIdAndAccountId($mageTemplateId, $accountId);
152
- $emt = $emts->getFirstItem();
153
-
154
- return $emt;
155
  }
156
 
157
  /**
 
158
  *
159
- * @param int $mageTemplateId
160
- * @param int $accountId
161
- * @return Emv_Emt_Model_Mysql4_Emt_Collection
162
  */
163
- protected function _getEmtFromTemplateIdAndAccountId($mageTemplateId, $accountId)
164
  {
165
- /* @var $emts Emv_Emt_Model_Mysql4_Emt_Collection */
166
- $emts = $this->getCollection();
167
-
168
- $emts->addAccountFilter($accountId)
169
- ->addMageTemplateFilter($mageTemplateId);
170
-
171
- return $emts;
172
  }
173
  }
1
  <?php
2
  /**
3
+ * EmailVision email template class
4
  *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
  */
10
  class Emv_Emt_Model_Emt extends Mage_Core_Model_Abstract
11
  {
12
+ const MAGENTO_TEMPLATE_ID_FOR_EMV_SEND = 'magento_emv_sending';
13
 
14
  /**
15
+ * SmartFocus account
16
+ * @var Emv_Core_Model_Account
17
+ */
18
+ protected $_account;
19
+
20
+ /**
21
+ * SmartFocus Template
22
+ *
23
+ * @var stdClass
24
+ */
25
+ protected $_emailVisionTemplate;
26
+
27
+ /**
28
+ * Invalid fields
29
+ * @var array
30
+ */
31
+ protected $_invalidFields = array();
32
+
33
+ /**
34
+ * SmartFocus paramters
35
+ *
36
+ * @var array
37
+ */
38
+ protected $_unserializedEmvParams = null;
39
+
40
+ /**
41
+ * Constructor
42
  */
43
  public function _construct()
44
  {
46
  }
47
 
48
  /**
49
+ * Add new treatment before saving
50
+ * - Modify updated_at, created_at fields
51
+ * -
52
+ * @see Mage_Core_Model_Abstract::_beforeSave()
53
  */
54
+ protected function _beforeSave()
55
  {
56
+ $this->_emailVisionParams = array();
57
+
58
+ //reset emt template if user switch mail mode from 'emv create / SmartFocus Template' to 'emv send' or 'classic'
59
+ if (
60
+ $this->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::CLASSIC_MODE
61
+ || $this->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::EMV_SEND
62
+ ) {
63
+ $this->setEmvTemplateId(null);
64
+ } else {
65
+ if (
66
+ $this->getEmvTemplate()
67
+ && isset($this->getEmvTemplate()->id)
68
+ ) {
69
+ $this->_unserializedEmvParams = $this->getEmailVisionParams($this->_emailVisionTemplate);
70
+ } else {
71
+ // throw exception, SmartFocus template shoud be loaded
72
+ Mage::throwException(
73
+ Mage::helper('emvemt')->__('Please select a SmartFocus template !')
74
+ );
75
+ }
76
+ }
77
+
78
+ // if _unserializedEmvParams property is defined, and in mode create
79
+ if (
80
+ $this->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::EMV_CREATE
81
+ && is_array($this->_unserializedEmvParams)
82
+ ) {
83
+ $this->setData('emv_parameters', serialize($this->_unserializedEmvParams));
84
+ } else {
85
+ $this->setData('emv_parameters', null);
86
+ }
87
+
88
+ // update datetime field
89
+ $gmtDate = Mage::getModel('core/date')->gmtDate();
90
+ if (!$this->getId()) {
91
+ $this->setData('created_at', $gmtDate);
92
+ }
93
+ $this->setData('updated_at', $gmtDate);
94
+
95
  return parent::_beforeSave();
96
  }
97
 
98
+ /**
99
+ * Get SmartFocus parameters :
100
+ * - from a given SmartFocus template.
101
+ * - from SmartFocus template if defined as object's property
102
+ * - unserialize $this->getData('emv_parameters')
103
+ *
104
+ * @param stdClass $emv
105
+ * @return array
106
+ */
107
+ public function getEmailVisionParams(stdClass $emv = null)
108
+ {
109
+ $result = array();
110
+
111
+ if ($emv == null) {
112
+ if (is_array($this->_unserializedEmvParams)) {
113
+ return $this->_unserializedEmvParams;
114
+
115
+ } elseif ($this->getData('emv_parameters')) {
116
+ $params = $this->getData('emv_parameters');
117
+ $params = unserialize($params);
118
+ if ($params && is_array($params)) {
119
+ $this->_unserializedEmvParams = $params;
120
+ }
121
+
122
+ return $this->_unserializedEmvParams;
123
+ }
124
+ }
125
+
126
+ if ($emv && isset($emv->id) && isset($emv->random) && isset($emv->encrypt) && isset($emv->name)) {
127
+ $result['emv_id'] = $emv->id;
128
+ $result['emv_random'] = $emv->random;
129
+ $result['emv_encrypt'] = $emv->encrypt;
130
+ $result['emv_name'] = $emv->name;
131
+
132
+ $vars = Mage::helper('emvemt/emvtemplate')->getAllDynContentAndAttributes($emv);
133
+ $result[Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_CONTENT]
134
+ = $vars[Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_CONTENT];
135
+ $result[Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_DYN]
136
+ = $vars[Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_DYN];
137
+ }
138
+
139
+ return $result;
140
+ }
141
+
142
  /**
143
  * Validate first page of emt creation
144
+ *
145
+ * @return true | array - errors
146
  */
147
  public function validateNewForm()
148
  {
149
  $error = array();
150
 
151
  if (!Zend_Validate::is($this->getEmvAccountId(), 'NotEmpty')) {
152
+ $errors[] = Mage::helper('emvemt')->__('SmartFocus account is required !');
153
+ $this->_invalidFields['emv_account_id'] = Mage::helper('emvemt')
154
+ ->__('Please select a SmartFocus account !');
155
+ } else {
156
+ if ($this->getAccount() == null) {
157
+ $errors[] = Mage::helper('emvemt')->__('SmartFocus account does not exist !');
158
+ $this->_invalidFields['emv_account_id'] = Mage::helper('emvemt')
159
+ ->__('Your selected SmartFocus account does not exist anymore ! Please select a new one !');
160
+ }
161
  }
162
 
163
  if (!Zend_Validate::is($this->getMageTemplateId(), 'NotEmpty')) {
164
+ $errors[] = Mage::helper('emvemt')->__('Magento template is required !');
165
+ $this->_invalidFields['mage_template_id'] = Mage::helper('emvemt')
166
+ ->__('Please select a Magento template !');
167
+ } else if ($this->mageTemplateMapped()) {
168
+ $errors[] = Mage::helper('emvemt')->__('This Magento template is already mapped !');
169
+ $this->_invalidFields['mage_template_id'] = Mage::helper('emvemt')
170
+ ->__('Please select another Magento template !');
171
  }
172
 
173
  if (empty($errors)) {
177
  }
178
 
179
  /**
180
+ * Get invalid fields
181
+ *
182
+ * @return array
183
  */
184
+ public function getInvalidFields()
185
+ {
186
+ return $this->_invalidFields;
187
+ }
188
+
189
+ /**
190
+ * Get SmartFocus account - make sure emv_account_id is set
191
+ *
192
+ * @return Emv_Core_Model_Account
193
+ */
194
+ public function getAccount()
195
+ {
196
+ if (
197
+ $this->getEmvAccountId()
198
+ && (!isset($this->_account) || $this->dataHasChangedFor('emv_account_id'))
199
+ ) {
200
+ $this->_account = Mage::getModel('emvcore/account')->load($this->getEmvAccountId());
201
+ if (!$this->_account->getId()) {
202
+ $this->_account = null;
203
+ }
204
+ }
205
+
206
+ return $this->_account;
207
+ }
208
+
209
+ /**
210
+ * Set SmartFocus Account
211
+ * @param Emv_Core_Model_Account $account
212
+ * @return Emv_Emt_Model_Emt
213
+ */
214
+ public function setAccount(Emv_Core_Model_Account $account)
215
  {
216
+ if ($account->getId()) {
217
+ $this->setEmvAccountId($account->getId());
218
+ $this->setOrigData('emv_account_id', $account->getId());
219
+ $this->_account = $account;
220
+ }
221
+
222
+ return $this;
223
+ }
224
 
225
+ /**
226
+ * Get SmartFocus template
227
+ *
228
+ * @throws Exception - if network errors occur
229
+ * @return stdClass | null
230
+ */
231
+ public function getEmvTemplate()
232
+ {
233
+ if (
234
+ $this->getEmvTemplateId()
235
+ && (!isset($this->_emailVisionTemplate) || $this->dataHasChangedFor('emv_template_id'))
236
+ ) {
237
+ $service = Mage::getModel('emvcore/service_transactional');
238
+ $service->setAccount($this->getAccount());
239
+ $this->_emailVisionTemplate = $service->getTemplateById($this->getEmvTemplateId());
240
+ }
241
+
242
+ return $this->_emailVisionTemplate;
243
+ }
244
+
245
+ /**
246
+ * Set SmartFocus Template
247
+ *
248
+ * @param stdClass $emvTemplate
249
+ */
250
+ public function setEmvTemplate(stdClass $emvTemplate)
251
+ {
252
+ if ($emvTemplate && isset($emvTemplate->id)) {
253
+ $this->setEmvTemplateId($emvTemplate->id);
254
+ $this->setOrigData('emv_template_id', $emvTemplate->id);
255
+ $this->_emailVisionTemplate = $emvTemplate;
256
  }
257
+
258
+ return $this;
259
+ }
260
+
261
+ /**
262
+ * Validate SmartFocus mapped template. Return true if everything is ok or an list of errors
263
+ *
264
+ * @return true | array - errors
265
+ */
266
+ public function validate()
267
+ {
268
+ $errors = $this->validateNewForm();
269
+
270
+ if (is_array($errors) && count($errors) > 0) {
271
+ return $errors;
272
+ } else {
273
  $errors = array();
274
  }
275
 
276
+ // validate if send mode is valide
277
  if (!Zend_Validate::is($this->getEmvSendMailModeId(), 'NotEmpty')) {
278
+ $errors[] = Mage::helper('emvemt')->__('Sending mode is required !');
279
+ $this->_invalidFields['emv_send_mail_mode_id'] = Mage::helper('emvemt')
280
+ ->__('Please select a sending mode !');
281
+ } else {
282
+ if (
283
+ !in_array($this->getEmvSendMailModeId(), Emv_Emt_Model_Mailmode::getSupportedModes())
284
+ ) {
285
+ $errors[] = Mage::helper('emvemt')->__('This sending mode doesn\'t exists !');
286
+ $this->_invalidFields['emv_send_mail_mode_id'] = Mage::helper('emvemt')
287
+ ->__('Please select another sending mode !');
288
  }
289
  }
290
 
291
+ // in case we use email vision template to send email
292
+ if ($this->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::EMV_CREATE) {
293
+ if (!Zend_Validate::is($this->getEmvTemplateId(), 'NotEmpty')) {
294
+ $errors[] = Mage::helper('emvemt')->__('SmartFocus template is required !');
295
+ $this->_invalidFields['emv_template_id'] = Mage::helper('emvemt')
296
+ ->__('Please select an SmartFocus template !');
297
+ } else {
298
+ $emv = null;
 
 
299
  try {
300
+ // Verify if SmartFocus template exists or not
301
+ $emv = $this->getEmvTemplate();
 
 
 
 
 
 
 
 
 
302
  } catch (Exception $e) {
303
  $errors[] = $e->getMessage();
304
  }
305
+
306
+ if (null === $emv) {
307
+ $this->_invalidFields['emv_template_id'] = Mage::helper('emvemt')
308
+ ->__('Please select another SmartFocus template !');
309
+ }
310
  }
311
  }
312
 
316
  return $errors;
317
  }
318
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  /**
320
+ * Validate mapped attributes
321
+ *
322
+ * @param array $attributes
323
+ * @return array
324
  */
325
+ public function validateMappedAttributes($attributes = array())
326
  {
327
+ $errors = array();
328
 
329
+ $emvTypes = array();
330
+ foreach ($attributes as $attrInfo) {
331
+ if ($attrInfo['emv_attribute']) {
332
+ if (!isset($emvType['emv_attribute'])) {
333
+ $emvTypes[$attrInfo['emv_attribute']] = 1;
334
+ } else {
335
+ $emvTypes[$attrInfo['emv_attribute']] ++;
336
+ }
337
+ }
338
  }
339
 
340
+ foreach ($emvTypes as $type => $occurrence) {
341
+ if ($occurrence > 1) {
342
+ $errors[] = Mage::helper('emvemt')->__(
343
+ "SmartFocus attribute '%s' is already mapped !",
344
+ Mage::helper('core')->escapeHtml($type)
345
+ );
346
+ }
347
+ }
348
 
349
+ return $errors;
350
  }
351
 
352
+ /**
353
+ * Check if a Magento template has been mapped to current account
354
+ *
355
+ * @return boolean
356
+ */
357
+ public function mageTemplateMapped()
358
  {
359
+ $result = $this->_getResource()->mageTemplateMapped($this);
360
+ return (is_array($result) && count($result) > 0 ) ? true : false;
 
 
361
  }
362
 
363
  /**
364
+ * Check if an SmartFocus email template already exists with the current data
365
  *
366
+ * @return boolean
 
 
367
  */
368
+ public static function emvTemplateExists()
369
  {
370
+ $result = $this->_getResource()->emvTemplateExists($this);
371
+ return (is_array($result) && count($result) > 0 ) ? true : false;
 
 
 
 
 
372
  }
373
  }
app/code/community/Emv/Emt/Model/Log.php ADDED
@@ -0,0 +1,151 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Message sending log Model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Model_Log extends Mage_Core_Model_Abstract
11
+ {
12
+
13
+ /**
14
+ * Constant for sending basic workflow
15
+ */
16
+ const SENDING_BASIC_WORKFLOW = 'normal';
17
+
18
+ /**
19
+ * Constant for resending workflow
20
+ */
21
+ const RESENDING_WORKFLOW = 'resending';
22
+
23
+ const RESCHEDULED = 1;
24
+
25
+ /**
26
+ * (non-PHPdoc)
27
+ * @see Varien_Object::_construct()
28
+ */
29
+ public function _construct()
30
+ {
31
+ $this->_init('emvemt/log', 'id');
32
+ }
33
+
34
+ /**
35
+ * (non-PHPdoc)
36
+ * @see Mage_Core_Model_Abstract::_beforeSave()
37
+ */
38
+ protected function _beforeSave()
39
+ {
40
+ $this->prepareDataBeforeSave();
41
+ return parent::_beforeSave();
42
+ }
43
+
44
+ /**
45
+ * @return array
46
+ */
47
+ public static function getAllWorkFlowOptions()
48
+ {
49
+ return array(
50
+ self::SENDING_BASIC_WORKFLOW => Mage::helper('emvemt')->__('Normal'),
51
+ self::RESENDING_WORKFLOW => Mage::helper('emvemt')->__('Resending'),
52
+ );
53
+ }
54
+ /**
55
+ * (non-PHPdoc)
56
+ * @see Mage_Core_Model_Abstract::_afterLoad()
57
+ */
58
+ protected function _afterLoad()
59
+ {
60
+ $this->prepareDataAfterLoad();
61
+ return parent::_afterLoad();
62
+ }
63
+
64
+ /**
65
+ * Prepare data before save
66
+ * - all data of type "array" will be serailized
67
+ * - if created_at is not set, use gmt date
68
+ * - email will be store in the the following form : email1,email2 ....
69
+ *
70
+ * @return Emv_Emt_Model_Log
71
+ */
72
+ public function prepareDataBeforeSave()
73
+ {
74
+ $coreHelper = Mage::helper('core');
75
+ $emvParams = $this->getData('emv_params');
76
+ if (is_array($emvParams)) {
77
+ $this->setData('emv_params', $coreHelper->jsonEncode($emvParams));
78
+ } else {
79
+ $this->setData('emv_params', null);
80
+ }
81
+
82
+ $emvContent = $this->getData('emv_content_variables');
83
+ if (is_array($emvContent)) {
84
+ $this->setData('emv_content_variables', $coreHelper->jsonEncode($emvContent));
85
+ } else {
86
+ $this->setData('emv_content_variables', null);
87
+ }
88
+
89
+ $emvVariables = $this->getData('emv_dyn_variables');
90
+ if (is_array($emvVariables)) {
91
+ $this->setData('emv_dyn_variables', $coreHelper->jsonEncode($emvVariables));
92
+ } else {
93
+ $this->setData('emv_dyn_variables', null);
94
+ }
95
+
96
+ $email = $this->getData('email');
97
+ if (is_array($email)) {
98
+ $this->setData('email', implode(',', $email));
99
+ }
100
+
101
+ if ($this->getData('created_at') == null) {
102
+ // created_at is also in gmt date
103
+ $gmtDate = Mage::getModel('core/date')->gmtDate();
104
+ $this->setData('created_at', $gmtDate);
105
+ }
106
+
107
+ return $this;
108
+ }
109
+
110
+ /**
111
+ * Prepare data before load
112
+ * @return Emv_Emt_Model_Log
113
+ */
114
+ public function prepareDataAfterLoad()
115
+ {
116
+ $coreHelper = Mage::helper('core');
117
+
118
+ $emvParams = $this->getData('emv_params');
119
+ if ($emvParams) {
120
+ $this->setData('emv_params', $coreHelper->jsonDecode($emvParams));
121
+ }
122
+
123
+ $emvContent = $this->getData('emv_content_variables');
124
+ if ($emvContent) {
125
+ $this->setData('emv_content_variables', $coreHelper->jsonDecode($emvContent));
126
+ }
127
+
128
+ $emvVariables = $this->getData('emv_dyn_variables');
129
+ if ($emvVariables) {
130
+ $this->setData('emv_dyn_variables', $coreHelper->jsonDecode($emvVariables));
131
+ }
132
+
133
+ $email = $this->getData('email');
134
+ $this->setData('email', explode(',', $email));
135
+ return $this;
136
+ }
137
+
138
+ /**
139
+ * @return array
140
+ */
141
+ public static function getErrorCodeOptions()
142
+ {
143
+ return array(
144
+ 0 => Mage::helper('emvemt')->__('Unknow Error'),
145
+ EmailVision_Api_Exception::APPLICATION_ERROR => Mage::helper('emvemt')->__('Server Error'),
146
+ EmailVision_Api_Exception::CONNECT_ERROR => Mage::helper('emvemt')->__('Network Problem'),
147
+ EmailVision_Api_Exception::INVALID_EMAIL_SENDING_PARAMETERS
148
+ => Mage::helper('emvemt')->__('Invalid SmartFocus Parameters')
149
+ );
150
+ }
151
+ }
app/code/community/Emv/Emt/Model/Mage/Core/Email/Template.php CHANGED
@@ -1,14 +1,53 @@
1
  <?php
 
 
 
 
 
 
 
 
 
 
2
  class Emv_Emt_Model_Mage_Core_Email_Template extends Mage_Core_Model_Email_Template
3
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
 
5
- private $emvSendMode = false;
 
 
 
 
6
 
7
  /**
8
- * Send transactional email to recipient
 
 
 
9
  *
10
  * @param int $templateId
11
- * @param string|array $sender sneder informatio, can be declared as part of config path
12
  * @param string $email recipient email
13
  * @param string $name recipient name
14
  * @param array $vars varianles which can be used in template
@@ -17,6 +56,106 @@ class Emv_Emt_Model_Mage_Core_Email_Template extends Mage_Core_Model_Email_Templ
17
  */
18
  public function sendTransactional($templateId, $sender, $email, $name, $vars=array(), $storeId=null)
19
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
20
  if (is_numeric($templateId)) {
21
  $this->load($templateId);
22
  } else {
@@ -24,123 +163,210 @@ class Emv_Emt_Model_Mage_Core_Email_Template extends Mage_Core_Model_Email_Templ
24
  $this->loadDefault($templateId, $localeCode);
25
  }
26
 
27
- /* @var $emt Emv_Emt_Model_Emt */
28
- $emt = Mage::getModel('emvemt/emt');
29
- $mode = $emt->getMode($templateId, $storeId);
30
 
31
- if($mode === null)
32
- {
33
- $mode = Emv_Emt_Constants::CLASSIC_FLAG;
 
 
 
 
34
  }
35
 
36
- if($this->emvSendMode)
37
- {
38
- $mode = Emv_Emt_Constants::EMV_SEND_FLAG;
 
 
39
  }
 
 
 
 
 
 
 
 
40
 
41
- switch($mode)
42
- {
43
- case Emv_Emt_Constants::CLASSIC_FLAG :
44
- parent::sendTransactional($templateId, $sender, $email, $name, $vars, $storeId);
45
- break;
46
- case Emv_Emt_Constants::EMV_CREATE_FLAG :
47
- try {
48
- $accountId = Mage::getStoreConfig('emvcore/emv_account/account', $storeId);
49
- /* @var $account Emv_Emt_Model_Emt */
50
- $emvemt = Mage::getModel('emvemt/emt')->getEmvEmt($templateId, $accountId);
51
-
52
- $emvTemplateId = $emvemt->getEmvTemplateId();
53
-
54
- /* @var $account Emv_Core_Model_Account */
55
- $account = Mage::getModel('emvcore/account')->load($accountId);
56
- /* @var $emvApiModel Emv_Core_Model_Service_Soap_Api */
57
- $emvApiModel = Mage::getModel('emvcore/service_soap_api', $account);
58
-
59
- /* @var $attributes Emv_Emt_Model_Mysql4_Attribute_Collection */
60
- $attributes = Mage::getResourceModel('emvemt/attribute_collection');
61
- $mappedEmvDynAttributes = $attributes->addEmtFilter($emvemt->getId())
62
- ->addAttributeTypeFilter(Emv_Emt_Constants::ATTRIBUTE_TYPE_EMV_DYN)
63
- ->load()->getMapping();
64
-
65
- // get magento template variable value
66
- $realValueEmvDynAttributes = $this->prepareAttributes($mappedEmvDynAttributes, $vars);
67
-
68
- /* @var $attributes Emv_Emt_Model_Mysql4_Attribute_Collection */
69
- $attributes2 = Mage::getResourceModel('emvemt/attribute_collection');
70
- $mappedEmvContentAttributes = $attributes2->addEmtFilter($emvemt->getId())
71
- ->addAttributeTypeFilter(Emv_Emt_Constants::ATTRIBUTE_TYPE_EMV_CONTENT)
72
- ->load()->getMapping();
73
-
74
- // get magento template variable value
75
- $realValueEmvContentAttributes = $this->prepareAttributes($mappedEmvContentAttributes, $vars);
76
-
77
- //Send the email
78
- $emvTemplate = $emvApiModel->getTemplateById($emvTemplateId);
79
- $emvApiModel->sendEmv($emvTemplate,
80
- Mage::helper('emvemt/emvtemplate')->_attributesToWebServiceRequest($realValueEmvDynAttributes),
81
- $email, Mage::helper('emvemt/emvtemplate')->_attributesToWebServiceRequest($realValueEmvContentAttributes));
82
- } catch (Exception $e) {
83
- Mage::log('Error with CC (emv create), trying to send mail in classic mode', null,
84
- Mage::helper('emvcore')->LOG_FILE, true);
85
- parent::sendTransactional($templateId, $sender, $email, $name, $vars, $storeId);
86
- }
87
- break;
88
- case Emv_Emt_Constants::EMV_SEND_FLAG :
89
- try {
90
-
91
- $this->setTemplateText($this->getProcessedTemplate($vars));
92
- $this->setTemplateSubject($this->getProcessedTemplateSubject($vars));
93
- $accountId = Mage::getStoreConfig('emvcore/emv_account/account', $storeId);
94
- /* @var $account Emv_Core_Model_Account */
95
- $account = Mage::getModel('emvcore/account')->load($accountId);
96
-
97
- if (!is_array($sender)) {
98
- $this->setSenderName(Mage::getStoreConfig('trans_email/ident_'.$sender.'/name', $storeId));
99
- $this->setSenderEmail(Mage::getStoreConfig('trans_email/ident_'.$sender.'/email', $storeId));
100
- } else {
101
- $this->setSenderName($sender['name']);
102
- $this->setSenderEmail($sender['email']);
103
- }
104
-
105
- /* @var $emvApiModel Emv_Core_Model_Service_Soap_Api */
106
- $emvApiModel = Mage::getModel('emvcore/service_soap_api', $account);
107
- if($name === null)
108
- {
109
- $name = $email;
110
- }
111
- $emvApiModel->sendEmvEmt($this, $name, $email);
112
-
113
- } catch (Exception $e) {
114
- Mage::log('Error with CC (emv send), trying to send mail in classic mode', null,
115
- Mage::helper('emvcore')->LOG_FILE, true);
116
- parent::sendTransactional($templateId, $sender, $email, $name, $vars, $storeId);
117
  }
118
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  }
 
 
120
  }
121
 
122
  /**
123
  * Return values of magento template variables in an array
 
124
  * @param array $attributesArray
125
- * @param array $var array of magento instance (cutomer, order ...) where we going to
126
- * pick values
 
127
  */
128
  public function prepareAttributes($attributesArray, $var)
129
  {
130
-
131
  $attributesWithValues = array();
132
 
133
  $this->setTemplateStyles(null);
134
 
135
- foreach($attributesArray as $emv => $mage)
136
- {
137
- if(preg_match(Varien_Filter_Template::CONSTRUCTION_PATTERN, $mage))
138
- {
139
  $this->setTemplateText($mage);
140
  $attributesWithValues[$emv] = $this->getProcessedTemplate($var);
141
- }
142
- else
143
- {
144
  //it's a constant
145
  $attributesWithValues[$emv] = $mage;
146
  }
@@ -149,8 +375,15 @@ class Emv_Emt_Model_Mage_Core_Email_Template extends Mage_Core_Model_Email_Templ
149
  return $attributesWithValues;
150
  }
151
 
 
 
 
 
 
 
152
  public function setEmvSend($emvSendMode)
153
  {
154
- $this->emvSendMode = $emvSendMode;
 
155
  }
156
  }
1
  <?php
2
+ /**
3
+ * Email template class
4
+ * Override in order to add additional treatement on email sending mechanism.
5
+ * The different sending method are defined in sendTransactional method
6
+ *
7
+ * @category Emv
8
+ * @package Emv_Emt
9
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
10
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
11
+ */
12
  class Emv_Emt_Model_Mage_Core_Email_Template extends Mage_Core_Model_Email_Template
13
  {
14
+ /**
15
+ * EmailVision send mode is used or not ?
16
+ * @var boolean
17
+ */
18
+ private $_emvSendMode = false;
19
+
20
+ /**
21
+ * Xml path config for SmartFocus account
22
+ */
23
+ const XML_PATH_CONFIG_ACCOUNT = 'emvemt/transactional_service/account';
24
+
25
+ /**
26
+ * The last email has been used to send
27
+ * @var string | array
28
+ */
29
+ protected $_lastEmail = null;
30
+
31
+ /**
32
+ * Log
33
+ * @var Emv_Emt_Model_Log
34
+ */
35
+ protected $_log = null;
36
 
37
+ /**
38
+ * Last used data
39
+ * @var array
40
+ */
41
+ protected $_lastData = array();
42
 
43
  /**
44
+ * Send transactional email to recipient. 3 different sending methods :
45
+ * - Classic : Email will be sent by Magento system
46
+ * - Send : Email will be sent by EmailVision system
47
+ * - Create : Email will be sent by EmailVision system by using EmailVision template
48
  *
49
  * @param int $templateId
50
+ * @param string|array $sender sender information, can be declared as part of config path
51
  * @param string $email recipient email
52
  * @param string $name recipient name
53
  * @param array $vars varianles which can be used in template
56
  */
57
  public function sendTransactional($templateId, $sender, $email, $name, $vars=array(), $storeId=null)
58
  {
59
+ // emailvision account id
60
+ $accountId = Mage::getStoreConfig(self::XML_PATH_CONFIG_ACCOUNT, $storeId);
61
+
62
+ /* @var $account Emv_Emt_Helper_Emvtemplate */
63
+ $templateHelper = Mage::helper('emvemt/emvtemplate');
64
+ $sendingData = $templateHelper->getDataForSending($templateId, $accountId);
65
+
66
+ $emvemt = $sendingData['emv_template'];
67
+
68
+ // get sending mode
69
+ $mode = $emvemt->getData('emv_send_mail_mode_id');
70
+ // use classic mode
71
+ if ($mode === null) {
72
+ $mode = Emv_Emt_Model_Mailmode::CLASSIC_MODE;
73
+ }
74
+ // if we are forced to send by emailvision defaut template
75
+ if ($this->_emvSendMode) {
76
+ $mode = Emv_Emt_Model_Mailmode::EMV_SEND;
77
+ if ($accountId) {
78
+ $account = $sendingData['account'];
79
+ if (!$account->getId()) {
80
+ $accountAndDefaultTemplate = $templateHelper->getAccountAndDefaultTemplate($accountId);
81
+ $sendingData['account'] = $accountAndDefaultTemplate['account'];
82
+ $sendingData['tmp_sending'] = $accountAndDefaultTemplate['tmp_sending'];
83
+ }
84
+ }
85
+ }
86
+
87
+ $this->_lastEmail = $email;
88
+
89
+ // prepare log
90
+ $this->_log = $templateHelper->prepareLogBeforeSend($mode, $sendingData, $this->_lastEmail, $storeId);
91
+ try {
92
+ switch ($mode) {
93
+ // classic mode - email is sent by Magento
94
+ case Emv_Emt_Model_Mailmode::CLASSIC_MODE :
95
+ parent::sendTransactional($templateId, $sender, $email, $name, $vars, $storeId);
96
+ $templateHelper->prepareLogAfterSend($this->_log, $this->_lastData, $this->_lastEmail, true);
97
+ break;
98
+
99
+ // create mode - email is sent by using EmailVision template
100
+ case Emv_Emt_Model_Mailmode::EMV_CREATE :
101
+ $this->sendEmailByEmvTemplate($sendingData, $email, $vars, $storeId);
102
+ break;
103
+
104
+ // send mode - email is sent by EmailVision using Magento template
105
+ case Emv_Emt_Model_Mailmode::EMV_SEND :
106
+ $this->sendEmailByDefaultTemplate($sendingData, $templateId, $sender, $email, $name, $vars, $storeId);
107
+ break;
108
+ }
109
+ } catch (Exception $e) {
110
+ Mage::logException($e);
111
+
112
+ $error = array(
113
+ 'msg' => $e->getMessage(),
114
+ 'code' => $e->getCode()
115
+ );
116
+
117
+ $templateHelper->prepareLogAfterSend($this->_log, $this->_lastData, $this->_lastEmail, false, $error, $storeId);
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Send Email by EmailVision API using EmailVision Default Template
123
+ *
124
+ * @param array $sendingData
125
+ * @param string $templateId
126
+ * @param string | array $sender
127
+ * @param string | array $email
128
+ * @param string | array $name
129
+ * @param array $vars
130
+ * @param string $storeId
131
+ * @return boolean | string
132
+ */
133
+ public function sendEmailByDefaultTemplate($sendingData, $templateId, $sender, $email, $name, $vars=array(), $storeId=null)
134
+ {
135
+ /* @var $defaultTemplate Emv_Emt_Model_Emt */
136
+ $defaultTemplate = $sendingData['tmp_sending'];
137
+ $templateHelper = Mage::helper('emvemt/emvtemplate');
138
+ /* @var $account Emv_Core_Model_Account */
139
+ $account = $sendingData['account'];
140
+
141
+ $this->_lastData = array();
142
+
143
+ // get emailvision parameters from template
144
+ $params = $defaultTemplate->getEmailVisionParams();
145
+
146
+ if (!is_array($email)) {
147
+ $email = array($email);
148
+ }
149
+ if (!is_array($name)) {
150
+ $name = array($name);
151
+ }
152
+
153
+ $result = true;
154
+
155
+ // try to validate emv params, in case invalid throw exception
156
+ $templateHelper->validateEmvParams($params);
157
+
158
+ // load email template
159
  if (is_numeric($templateId)) {
160
  $this->load($templateId);
161
  } else {
163
  $this->loadDefault($templateId, $localeCode);
164
  }
165
 
166
+ // prepare body and subject for email
167
+ $this->setTemplateText($this->getProcessedTemplate($vars));
168
+ $this->setTemplateSubject($this->getProcessedTemplateSubject($vars));
169
 
170
+ // prepare sender name and email
171
+ if (!is_array($sender)) {
172
+ $this->setSenderName(Mage::getStoreConfig('trans_email/ident_'.$sender.'/name', $storeId));
173
+ $this->setSenderEmail(Mage::getStoreConfig('trans_email/ident_'.$sender.'/email', $storeId));
174
+ } else {
175
+ $this->setSenderName($sender['name']);
176
+ $this->setSenderEmail($sender['email']);
177
  }
178
 
179
+ // prepare variables in order to use default template
180
+ if($this->getTemplateType() == Mage_Newsletter_Model_Template::TYPE_HTML) {
181
+ $varContent = array('1' => $this->getTemplateText());
182
+ } else {
183
+ $varContent = array('2' => $this->getTemplateText());
184
  }
185
+ $varDyn = array (
186
+ 'SUBJECT' => $this->getTemplateSubject(),
187
+ 'FROM' => $this->getSenderName(),
188
+ 'FROM_EMAIL' => $this->getSenderEmail(),
189
+ 'TO' => '',
190
+ 'REPLY' => $this->getSenderName(),
191
+ 'REPLY_EMAIL' => $this->getSenderEmail(),
192
+ );
193
 
194
+ foreach ($email as $index => $oneMail) {
195
+ try {
196
+ // Name destination
197
+ $oneName = $name[0];
198
+ if (isset($name[$index])) {
199
+ $oneName = $name[$index];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  }
201
+ $varDyn['TO'] = $oneName;
202
+
203
+ // set last email
204
+ $this->_lastEmail = $oneMail;
205
+ // set last data
206
+ $this->_lastData = $this->prepareLastData(
207
+ $params['emv_encrypt'], $params['emv_id'], $params['emv_random'], $params['emv_name'],
208
+ $varContent, $varDyn
209
+ );
210
+
211
+ /* @var $notificationService Emv_Core_Model_Service_Notification */
212
+ $notificationService = Mage::getSingleton('emvcore/service_notification');
213
+ $result = $notificationService->sendTemplate(
214
+ $params['emv_encrypt'],
215
+ $params['emv_id'],
216
+ $params['emv_random'],
217
+ $oneMail,
218
+ $varContent,
219
+ $varDyn,
220
+ $account,
221
+ $storeId
222
+ );
223
+
224
+ // everything is ok
225
+ $templateHelper->prepareLogAfterSend($this->_log, $this->_lastData, $this->_lastEmail, true, array(), $storeId);
226
+ } catch(Exception $e) {
227
+ Mage::logException($e);
228
+ $error = array(
229
+ 'msg' => $e->getMessage(),
230
+ 'code' => $e->getCode()
231
+ );
232
+
233
+ $templateHelper->prepareLogAfterSend($this->_log, $this->_lastData, $this->_lastEmail, false, $error, $storeId);
234
+ }
235
+ }
236
+
237
+ return $result;
238
+ }
239
+
240
+ /**
241
+ * Prepare an assocative array for last data
242
+ *
243
+ * @param string $emvEncrypt
244
+ * @param string $emvId
245
+ * @param string $emvRandom
246
+ * @param string $emvName
247
+ * @param array $emvContent
248
+ * @param array $emvDyn
249
+ * @return array
250
+ */
251
+ public function prepareLastData($emvEncrypt, $emvId, $emvRandom, $emvName, $emvContent = array(), $emvDyn = array())
252
+ {
253
+ return array(
254
+ 'emv_encrypt' => $emvEncrypt,
255
+ 'emv_id' => $emvId,
256
+ 'emv_random' => $emvRandom,
257
+ 'emv_name' => $emvName,
258
+
259
+ 'emv_content_variables' => $emvContent,
260
+ 'emv_dyn_variables' => $emvDyn
261
+ );
262
+ }
263
+
264
+ /**
265
+ * Send Email by EmailVision using an EmailVision template
266
+ *
267
+ * @param array $sendingData
268
+ * @param array | string $email
269
+ * @param array $vars
270
+ * @param string $storeId
271
+ * @return boolean | string
272
+ */
273
+ public function sendEmailByEmvTemplate($sendingData, $email, $vars = array(), $storeId = null)
274
+ {
275
+ $emvemt = $sendingData['emv_template'];
276
+ $templateHelper = Mage::helper('emvemt/emvtemplate');
277
+
278
+ // validate emailvision parameters
279
+ $params = $emvemt->getEmailVisionParams();
280
+ $templateHelper->validateEmvParams($params);
281
+
282
+ $this->_lastData = array();
283
+
284
+ /* @var $attributes Emv_Emt_Model_Mysql4_Attribute_Collection */
285
+ $attributes = Mage::getResourceModel('emvemt/attribute_collection');
286
+ // get attribute mapping
287
+ $mappedAttributes = $attributes->addEmtFilter($emvemt->getId())
288
+ ->load()->getMappingWithType();
289
+
290
+ // get content variables
291
+ $realValueEmvContentAttributes = array();
292
+ if (isset($mappedAttributes[Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_CONTENT])) {
293
+ $realValueEmvContentAttributes = $this->prepareAttributes(
294
+ $mappedAttributes[Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_CONTENT],
295
+ $vars
296
+ );
297
+ }
298
+ // get dynamic variables
299
+ $realValueEmvDynAttributes = array();
300
+ if (isset($mappedAttributes[Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_DYN])) {
301
+ $realValueEmvDynAttributes = $this->prepareAttributes(
302
+ $mappedAttributes[Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_DYN],
303
+ $vars
304
+ );
305
+ }
306
+
307
+ $result = true;
308
+ if (!is_array($email)) {
309
+ $email = array($email);
310
+ }
311
+
312
+ /* @var $notificationService Emv_Core_Model_Service_Notification */
313
+ $notificationService = Mage::getSingleton('emvcore/service_notification');
314
+ foreach ($email as $oneMail) {
315
+ try {
316
+ // set last email
317
+ $this->_lastEmail = $oneMail;
318
+ // set last data$notificationService
319
+ $this->_lastData = $this->prepareLastData(
320
+ $params['emv_encrypt'], $params['emv_id'], $params['emv_random'], $params['emv_name'],
321
+ $realValueEmvContentAttributes, $realValueEmvDynAttributes
322
+ );
323
+ $result = $notificationService->sendTemplate(
324
+ $params['emv_encrypt'],
325
+ $params['emv_id'],
326
+ $params['emv_random'],
327
+ $oneMail,
328
+ $realValueEmvContentAttributes,
329
+ $realValueEmvDynAttributes,
330
+ $sendingData['account'],
331
+ $storeId
332
+ );
333
+
334
+ // everything is ok
335
+ $templateHelper->prepareLogAfterSend($this->_log, $this->_lastData, $this->_lastEmail, true, array(), $storeId);
336
+ } catch(Exception $e) {
337
+ Mage::logException($e);
338
+
339
+ $error = array(
340
+ 'msg' => $e->getMessage(),
341
+ 'code' => $e->getCode()
342
+ );
343
+
344
+ $templateHelper->prepareLogAfterSend($this->_log, $this->_lastData, $this->_lastEmail, false, $error, $storeId);
345
+ }
346
  }
347
+
348
+ return $result;
349
  }
350
 
351
  /**
352
  * Return values of magento template variables in an array
353
+ *
354
  * @param array $attributesArray
355
+ * @param array $var array of magento attributes (cutomer, order ...) from which we going to
356
+ * pick values
357
+ * @return array
358
  */
359
  public function prepareAttributes($attributesArray, $var)
360
  {
 
361
  $attributesWithValues = array();
362
 
363
  $this->setTemplateStyles(null);
364
 
365
+ foreach($attributesArray as $emv => $mage) {
366
+ if (preg_match(Varien_Filter_Template::CONSTRUCTION_PATTERN, $mage)) {
 
 
367
  $this->setTemplateText($mage);
368
  $attributesWithValues[$emv] = $this->getProcessedTemplate($var);
369
+ } else {
 
 
370
  //it's a constant
371
  $attributesWithValues[$emv] = $mage;
372
  }
375
  return $attributesWithValues;
376
  }
377
 
378
+ /**
379
+ * Sending with default EmailVision Template.
380
+ *
381
+ * @param boolean $emvSendMode
382
+ * @return Emv_Emt_Model_Mage_Core_Email_Template
383
+ */
384
  public function setEmvSend($emvSendMode)
385
  {
386
+ $this->_emvSendMode = $emvSendMode;
387
+ return $this;
388
  }
389
  }
app/code/community/Emv/Emt/Model/MageTemplate.php CHANGED
@@ -1,9 +1,21 @@
1
  <?php
2
-
 
 
 
 
 
 
 
3
  class Emv_Emt_Model_MageTemplate extends Mage_Core_Model_Abstract
4
  {
5
-
6
- public function getNotMappedMageTemplateCollection($emvAccountId)
 
 
 
 
 
7
  {
8
  if(!is_numeric($emvAccountId))
9
  {
@@ -18,6 +30,11 @@ class Emv_Emt_Model_MageTemplate extends Mage_Core_Model_Abstract
18
  $emt->getSelect()->reset(Zend_Db_Select::COLUMNS)->columns('mage_template_id')->where("emv_account_id = ?", $emvAccountId);
19
 
20
  $magentoTemplates->addFieldToFilter('template_id', array('nin' => $emt->getSelect()));
 
 
 
 
 
21
 
22
  $magentoTemplates->load();
23
 
1
  <?php
2
+ /**
3
+ * EmailVision email template class
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
  class Emv_Emt_Model_MageTemplate extends Mage_Core_Model_Abstract
11
  {
12
+ /**
13
+ * Get not mapped Magento template collection
14
+ * @param string $emvAccountId
15
+ * @param array $selectFields => selected fields
16
+ * @return void|Mage_Core_Model_Mysql4_Email_Template_Collection
17
+ */
18
+ public function getNotMappedMageTemplateCollection($emvAccountId, $selectFields = array())
19
  {
20
  if(!is_numeric($emvAccountId))
21
  {
30
  $emt->getSelect()->reset(Zend_Db_Select::COLUMNS)->columns('mage_template_id')->where("emv_account_id = ?", $emvAccountId);
31
 
32
  $magentoTemplates->addFieldToFilter('template_id', array('nin' => $emt->getSelect()));
33
+ if (count($selectFields)) {
34
+ $magentoTemplates->getSelect()
35
+ ->reset(Zend_Db_Select::COLUMNS)
36
+ ->columns($selectFields);
37
+ }
38
 
39
  $magentoTemplates->load();
40
 
app/code/community/Emv/Emt/Model/Mailmode.php CHANGED
@@ -1,48 +1,75 @@
1
  <?php
2
  /**
 
3
  *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{2EB12F64-51A5-4e90-9048-2BE20B080487}
8
  */
9
  class Emv_Emt_Model_Mailmode extends Mage_Core_Model_Abstract
10
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
 
12
  /**
13
- * opGUID{B23F7DF5-EE1D-4947-9B8E-415CDB6F889F}
14
  */
15
  public function _construct()
16
  {
17
  $this->_init('emvemt/mailmode');
18
  }
19
 
20
- public function getIdByName($name)
 
 
 
 
21
  {
22
- /* @var $emts Emv_Emt_Model_Mysql4_Mailmode_Collection */
23
- $modes = $this->getCollection();
24
-
25
- $modes->addNameFilter($name);
26
- $mode = $modes->getFirstItem();
27
-
28
- return $mode->getId();
29
  }
30
 
31
  /**
32
- * opGUID{EDA1DA15-1173-4b9c-ACA9-F11EF205DCE2}
 
 
33
  */
34
- protected function beforeSave()
35
  {
36
- $this->validate();
37
- return parent::_beforeSave();
 
 
 
38
  }
39
-
40
  /**
41
- * opGUID{A7EFFDD7-1441-4e26-BCEE-3DCEEAFBE894}
 
 
42
  */
43
- private function validate()
44
  {
45
- //TODO
 
 
 
 
 
46
  }
47
-
48
  }
1
  <?php
2
  /**
3
+ * Mail mode class
4
  *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
  */
10
  class Emv_Emt_Model_Mailmode extends Mage_Core_Model_Abstract
11
  {
12
+ /**
13
+ * Classic mode - email is sent by Magento
14
+ */
15
+ const CLASSIC_MODE = 1;
16
+
17
+ /**
18
+ * Create mode - email is sent by EmailVision template
19
+ */
20
+ const EMV_CREATE = 2;
21
+
22
+ /**
23
+ * Send mode - email is sent by EmailVision by using Magento template
24
+ */
25
+ const EMV_SEND = 3;
26
 
27
  /**
28
+ * Constructor
29
  */
30
  public function _construct()
31
  {
32
  $this->_init('emvemt/mailmode');
33
  }
34
 
35
+ /**
36
+ * Get mail modes and their translated labels
37
+ * @return array
38
+ */
39
+ public static function getMailModesAndLabels()
40
  {
41
+ return array(
42
+ self::CLASSIC_MODE => Mage::helper('emvemt')->__('classic'),
43
+ self::EMV_CREATE => Mage::helper('emvemt')->__('emv create'),
44
+ self::EMV_SEND => Mage::helper('emvemt')->__('emv send'),
45
+ );
 
 
46
  }
47
 
48
  /**
49
+ * Get all sending supported modes
50
+ *
51
+ * @return array
52
  */
53
+ public static function getSupportedModes()
54
  {
55
+ return array(
56
+ self::CLASSIC_MODE,
57
+ self::EMV_CREATE,
58
+ self::EMV_SEND,
59
+ );
60
  }
 
61
  /**
62
+ * To option array for select element
63
+ *
64
+ * @return array
65
  */
66
+ public static function toOptionArray()
67
  {
68
+ $mailModesAndLabels = self::getMailModesAndLabels();
69
+ return array(
70
+ array('value' => self::CLASSIC_MODE, 'label' => $mailModesAndLabels[self::CLASSIC_MODE]),
71
+ array('value' => self::EMV_CREATE, 'label' => $mailModesAndLabels[self::EMV_CREATE]),
72
+ array('value' => self::EMV_SEND, 'label' => $mailModesAndLabels[self::EMV_SEND]),
73
+ );
74
  }
 
75
  }
app/code/community/Emv/Emt/Model/Mysql4/Attribute.php CHANGED
@@ -1,4 +1,12 @@
1
  <?php
 
 
 
 
 
 
 
 
2
  class Emv_Emt_Model_Mysql4_Attribute extends Mage_Core_Model_Mysql4_Abstract
3
  {
4
  protected function _construct()
@@ -6,16 +14,27 @@ class Emv_Emt_Model_Mysql4_Attribute extends Mage_Core_Model_Mysql4_Abstract
6
  $this->_init('emvemt/attribute', 'id');
7
  }
8
 
 
 
 
 
 
 
9
  public function mageAttributeExists(Mage_Core_Model_Abstract $attribute)
10
  {
11
- return $this->_fieldAlreadyExist('mage_attribute', $attribute->getMageAttribute,
12
- $attribute->getEmvEmtId, $attribute->getId());
13
  }
14
 
 
 
 
 
 
15
  public function emvAttributeExists(Mage_Core_Model_Abstract $attribute)
16
  {
17
- return $this->_fieldAlreadyExist('emv_attribute', $attribute->getEmvAttribute,
18
- $attribute->getEmvEmtId, $attribute->getId());
19
  }
20
 
21
  /**
1
  <?php
2
+ /**
3
+ * Emt Mapped Attribute Resource Class
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
  class Emv_Emt_Model_Mysql4_Attribute extends Mage_Core_Model_Mysql4_Abstract
11
  {
12
  protected function _construct()
14
  $this->_init('emvemt/attribute', 'id');
15
  }
16
 
17
+ /**
18
+ * Check if the given Mage Attribute is already mapped
19
+ *
20
+ * @param Mage_Core_Model_Abstract $attribute
21
+ * @return array | null
22
+ */
23
  public function mageAttributeExists(Mage_Core_Model_Abstract $attribute)
24
  {
25
+ return $this->_fieldAlreadyExist('mage_attribute', $attribute->getMageAttribute(),
26
+ $attribute->getEmvEmtId(), $attribute->getId());
27
  }
28
 
29
+ /**
30
+ * Check if the given EmailVision Attribute is mapped
31
+ * @param Mage_Core_Model_Abstract $attribute
32
+ * @return array | null
33
+ */
34
  public function emvAttributeExists(Mage_Core_Model_Abstract $attribute)
35
  {
36
+ return $this->_fieldAlreadyExist('emv_attribute', $attribute->getEmvAttribute(),
37
+ $attribute->getEmvEmtId(), $attribute->getId());
38
  }
39
 
40
  /**
app/code/community/Emv/Emt/Model/Mysql4/Attribute/Collection.php CHANGED
@@ -1,4 +1,12 @@
1
  <?php
 
 
 
 
 
 
 
 
2
  class Emv_Emt_Model_Mysql4_Attribute_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
3
  {
4
 
@@ -7,12 +15,20 @@ class Emv_Emt_Model_Mysql4_Attribute_Collection extends Mage_Core_Model_Mysql4_C
7
  $this->_init('emvemt/attribute','emvemt/attribute');
8
  }
9
 
 
 
 
 
10
  public function addEmtFilter($emtId)
11
  {
12
  $this->getSelect()->where('main_table.emv_emt_id = ?', $emtId);
13
  return $this;
14
  }
15
 
 
 
 
 
16
  public function addAttributeTypeFilter($attributeType)
17
  {
18
  $this->getSelect()->where('main_table.emv_attribute_type = ?', $attributeType);
@@ -20,21 +36,38 @@ class Emv_Emt_Model_Mysql4_Attribute_Collection extends Mage_Core_Model_Mysql4_C
20
  }
21
 
22
  /**
23
- * Return mapped attributes in an array of array (key is Campaign Commander attribute name, value is
24
  * magento attribute name).
25
  * ex :
26
  * array ( 'emvAttribute1' => 'customer.firstname',
27
  * 'emvAttribute2' => 'customer.lastname')
28
- *
29
  */
30
  public function getMapping()
31
  {
32
  $mappedAttributes = array();
33
- foreach($this as $mapping)
34
- {
35
  $mappedAttributes[$mapping->getEmvAttribute()] = $mapping->getMageAttribute();
36
  }
37
 
38
  return $mappedAttributes;
39
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  }
1
  <?php
2
+ /**
3
+ * Emt Mapped Attribute Collection Class
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
  class Emv_Emt_Model_Mysql4_Attribute_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
11
  {
12
 
15
  $this->_init('emvemt/attribute','emvemt/attribute');
16
  }
17
 
18
+ /**
19
+ * @param string $emtId
20
+ * @return Emv_Emt_Model_Mysql4_Attribute_Collection
21
+ */
22
  public function addEmtFilter($emtId)
23
  {
24
  $this->getSelect()->where('main_table.emv_emt_id = ?', $emtId);
25
  return $this;
26
  }
27
 
28
+ /**
29
+ * @param string $attributeType
30
+ * @return Emv_Emt_Model_Mysql4_Attribute_Collection
31
+ */
32
  public function addAttributeTypeFilter($attributeType)
33
  {
34
  $this->getSelect()->where('main_table.emv_attribute_type = ?', $attributeType);
36
  }
37
 
38
  /**
39
+ * Return mapped attributes in an array of array (key is SmartFocus attribute name, value is
40
  * magento attribute name).
41
  * ex :
42
  * array ( 'emvAttribute1' => 'customer.firstname',
43
  * 'emvAttribute2' => 'customer.lastname')
44
+ * @return array
45
  */
46
  public function getMapping()
47
  {
48
  $mappedAttributes = array();
49
+ foreach($this as $mapping) {
 
50
  $mappedAttributes[$mapping->getEmvAttribute()] = $mapping->getMageAttribute();
51
  }
52
 
53
  return $mappedAttributes;
54
  }
55
+
56
+ /**
57
+ * Get all mapped attributes with their type
58
+ * @return array
59
+ */
60
+ public function getMappingWithType()
61
+ {
62
+ $mappedAttributes = array();
63
+ foreach($this as $mapping) {
64
+ if (!isset($mappedAttributes[$mapping->getEmvAttributeType()])) {
65
+ $mappedAttributes[$mapping->getEmvAttributeType()] = array();
66
+ }
67
+
68
+ $mappedAttributes[$mapping->getEmvAttributeType()][$mapping->getEmvAttribute()] = $mapping->getMageAttribute();
69
+ }
70
+
71
+ return $mappedAttributes;
72
+ }
73
  }
app/code/community/Emv/Emt/Model/Mysql4/Emt.php CHANGED
@@ -1,40 +1,59 @@
1
  <?php
2
  /**
 
3
  *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{7F6F8AE8-32E4-464d-BC2A-41496B850033}
8
  */
9
  class Emv_Emt_Model_Mysql4_Emt extends Mage_Core_Model_Mysql4_Abstract
10
  {
11
-
12
  /**
13
- * opGUID{CC97992D-58AB-4416-9D3D-A745A91C759D}
 
 
14
  */
15
  protected function _construct()
16
  {
17
  $this->_init('emvemt/emt','id');
18
  }
19
 
 
 
 
 
 
 
 
20
  public function mageTemplateMapped(Mage_Core_Model_Abstract $emt)
21
  {
22
  $emtTable = $this->getTable('emvemt/emt');
 
23
  $select = $this->_getReadAdapter()->select();
24
  $select->from($emtTable);
25
  $select->where("{$emtTable}.mage_template_id = '{$emt->getMageTemplateId()}' AND ".
26
  "{$emtTable}.emv_account_id = '{$emt->getEmvAccountId()}' AND ".
27
  "{$emtTable}.id != '{$emt->getId()}'");
 
28
  return $this->_getReadAdapter()->fetchRow($select);
29
  }
30
 
 
 
 
 
 
 
31
  public function emvTemplateExists(Mage_Core_Model_Abstract $emt)
32
  {
33
  $emtTable = $this->getTable('emvemt/emt');
 
34
  $select = $this->_getReadAdapter()->select();
35
  $select->from($emtTable);
36
  $select->where("{$emtTable}.emv_template_id = '{$emt->getEmvTemplateId()}' ".
37
  "AND {$emtTable}.id != '{$emt->getId()}'");
 
38
  return $this->_getReadAdapter()->fetchRow($select);
39
  }
40
 
1
  <?php
2
  /**
3
+ * EmailVision email template resource class
4
  *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
  */
10
  class Emv_Emt_Model_Mysql4_Emt extends Mage_Core_Model_Mysql4_Abstract
11
  {
 
12
  /**
13
+ * Constructor
14
+ *
15
+ * @see Mage_Core_Model_Resource_Abstract::_construct()
16
  */
17
  protected function _construct()
18
  {
19
  $this->_init('emvemt/emt','id');
20
  }
21
 
22
+
23
+ /**
24
+ * Retreive an SmartFocus email template by Magento template id and SmartFocus account id
25
+ *
26
+ * @param Mage_Core_Model_Abstract $emt
27
+ * @return mixed
28
+ */
29
  public function mageTemplateMapped(Mage_Core_Model_Abstract $emt)
30
  {
31
  $emtTable = $this->getTable('emvemt/emt');
32
+
33
  $select = $this->_getReadAdapter()->select();
34
  $select->from($emtTable);
35
  $select->where("{$emtTable}.mage_template_id = '{$emt->getMageTemplateId()}' AND ".
36
  "{$emtTable}.emv_account_id = '{$emt->getEmvAccountId()}' AND ".
37
  "{$emtTable}.id != '{$emt->getId()}'");
38
+
39
  return $this->_getReadAdapter()->fetchRow($select);
40
  }
41
 
42
+ /**
43
+ * Retreive an SmartFocus email template by EmailVision template id and SmartFocus account id
44
+ *
45
+ * @param Mage_Core_Model_Abstract $emt
46
+ * @return mixed
47
+ */
48
  public function emvTemplateExists(Mage_Core_Model_Abstract $emt)
49
  {
50
  $emtTable = $this->getTable('emvemt/emt');
51
+
52
  $select = $this->_getReadAdapter()->select();
53
  $select->from($emtTable);
54
  $select->where("{$emtTable}.emv_template_id = '{$emt->getEmvTemplateId()}' ".
55
  "AND {$emtTable}.id != '{$emt->getId()}'");
56
+
57
  return $this->_getReadAdapter()->fetchRow($select);
58
  }
59
 
app/code/community/Emv/Emt/Model/Mysql4/Emt/Collection.php CHANGED
@@ -1,17 +1,15 @@
1
  <?php
2
  /**
 
3
  *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{BC3880C7-9F66-4b24-A15E-84573DEE1F72}
8
  */
9
  class Emv_Emt_Model_Mysql4_Emt_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
10
  {
11
 
12
- /**
13
- * opGUID{CEA29ABD-15C0-4159-96C7-0FEFA9101B67}
14
- */
15
  protected function _construct()
16
  {
17
  $this->_init('emvemt/emt','emvemt/emt');
@@ -19,22 +17,44 @@ class Emv_Emt_Model_Mysql4_Emt_Collection extends Mage_Core_Model_Mysql4_Collect
19
 
20
  /**
21
  * Join collection with the Magento template name
 
 
22
  */
23
- public function getMagentoEMTName()
24
  {
25
- $this->join('core/email_template', 'mage_template_id=template_id', 'template_code');
 
 
 
 
 
26
  return $this;
27
  }
28
 
29
  /**
30
- * Join collection with the Magento template name
 
 
31
  */
32
- public function getMailModeName()
33
  {
34
- $this->join('emvemt/mailmode', 'emv_send_mail_mode_id=`emvemt/mailmode`.id', 'name');
 
 
 
 
 
 
35
  return $this;
36
  }
37
 
 
 
 
 
 
 
 
38
  public function addAccountFilter($accountId)
39
  {
40
  $this->addFieldToFilter('emv_account_id', array('eq' => $accountId));
@@ -42,10 +62,25 @@ class Emv_Emt_Model_Mysql4_Emt_Collection extends Mage_Core_Model_Mysql4_Collect
42
  return $this;
43
  }
44
 
 
 
 
 
 
 
45
  public function addMageTemplateFilter($mageTemplateId)
46
  {
47
  $this->addFieldToFilter('mage_template_id', array('eq' => $mageTemplateId));
48
 
49
  return $this;
50
  }
 
 
 
 
 
 
 
 
 
51
  }
1
  <?php
2
  /**
3
+ * EmailVision email template Resource Collection Class
4
  *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
  */
10
  class Emv_Emt_Model_Mysql4_Emt_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
11
  {
12
 
 
 
 
13
  protected function _construct()
14
  {
15
  $this->_init('emvemt/emt','emvemt/emt');
17
 
18
  /**
19
  * Join collection with the Magento template name
20
+ *
21
+ * @return Emv_Emt_Model_Mysql4_Emt_Collection
22
  */
23
+ public function prepareQueryToGetMagentoName()
24
  {
25
+ // left join to get also
26
+ $select = $this->getSelect();
27
+ $select->joinLeft(
28
+ array('core/email_template' => $this->getTable('core/email_template')),
29
+ 'main_table.mage_template_id=template_id',
30
+ array('template_code'));
31
  return $this;
32
  }
33
 
34
  /**
35
+ * Join collection with the EmailVision Account name
36
+ *
37
+ * @return Emv_Emt_Model_Mysql4_Emt_Collection
38
  */
39
+ public function prepareQueryToGetAccountName()
40
  {
41
+ // left join to get also
42
+ $select = $this->getSelect();
43
+ $select->joinLeft(
44
+ array('account' => $this->getTable('emvcore/account')),
45
+ 'main_table.emv_account_id = account.id',
46
+ array('account_name' => 'account.name')
47
+ );
48
  return $this;
49
  }
50
 
51
+ /**
52
+ *
53
+ * Add account filter into collection
54
+ *
55
+ * @param string $accountId - EmailVision account
56
+ * @return Emv_Emt_Model_Mysql4_Emt_Collection
57
+ */
58
  public function addAccountFilter($accountId)
59
  {
60
  $this->addFieldToFilter('emv_account_id', array('eq' => $accountId));
62
  return $this;
63
  }
64
 
65
+ /**
66
+ * Add Magento Tempalte filter
67
+ *
68
+ * @param string $mageTemplateId - Magento template id
69
+ * @return Emv_Emt_Model_Mysql4_Emt_Collection
70
+ */
71
  public function addMageTemplateFilter($mageTemplateId)
72
  {
73
  $this->addFieldToFilter('mage_template_id', array('eq' => $mageTemplateId));
74
 
75
  return $this;
76
  }
77
+
78
+ /**
79
+ * @return Emv_Emt_Model_Mysql4_Emt_Collection
80
+ */
81
+ public function unselectEmvSendingTemplate()
82
+ {
83
+ $this->addFieldToFilter('mage_template_id', array('neq' => Emv_Emt_Model_Emt::MAGENTO_TEMPLATE_ID_FOR_EMV_SEND));
84
+ return $this;
85
+ }
86
  }
app/code/community/Emv/Emt/Model/Mysql4/Log.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Log Resource Model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Model_Mysql4_Log extends Mage_Core_Model_Mysql4_Abstract
11
+ {
12
+ protected function _construct()
13
+ {
14
+ $this->_init('emvemt/log', 'id');
15
+ }
16
+ }
app/code/community/Emv/Emt/Model/Mysql4/Log/Collection.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Email Sending Log Resource Collection Class
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Model_Mysql4_Log_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
11
+ {
12
+
13
+ protected function _construct()
14
+ {
15
+ $this->_init('emvemt/log','emvemt/log');
16
+ }
17
+
18
+ /**
19
+ * Join collection with the EmailVision Account name
20
+ *
21
+ * @return Emv_Emt_Model_Mysql4_Log_Collection
22
+ */
23
+ public function prepareQueryToGetAccountName()
24
+ {
25
+ // left join to get also
26
+ $select = $this->getSelect();
27
+ $select->joinLeft(
28
+ array('account' => $this->getTable('emvcore/account')),
29
+ 'main_table.account_id = account.id',
30
+ array('account_name' => 'account.name')
31
+ );
32
+
33
+ return $this;
34
+ }
35
+ }
app/code/community/Emv/Emt/Model/Mysql4/Mailmode.php DELETED
@@ -1,19 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{7F6F8AE8-32E4-464d-BC2A-41496B850033}
8
- */
9
- class Emv_Emt_Model_Mysql4_Mailmode extends Mage_Core_Model_Mysql4_Abstract
10
- {
11
-
12
- /**
13
- * opGUID{CC97992D-58AB-4416-9D3D-A745A91C759D}
14
- */
15
- protected function _construct()
16
- {
17
- $this->_init('emvemt/mailmode','id');
18
- }
19
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Emt/Model/Mysql4/Mailmode/Collection.php DELETED
@@ -1,31 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{BC3880C7-9F66-4b24-A15E-84573DEE1F72}
8
- */
9
- class Emv_Emt_Model_Mysql4_Mailmode_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
10
- {
11
-
12
- /**
13
- * opGUID{CEA29ABD-15C0-4159-96C7-0FEFA9101B67}
14
- */
15
- protected function _construct()
16
- {
17
- $this->_init('emvemt/mailmode','emvemt/mailmode');
18
- }
19
-
20
- public function toOptionArray()
21
- {
22
- return $this->_toOptionArray('id', 'name');
23
- }
24
-
25
- public function addNameFilter($name)
26
- {
27
- $this->addFieldToFilter('name', array('eq' => $name));
28
-
29
- return $this;
30
- }
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Emt/Model/Mysql4/Resending/Queue/Message.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EmailVision resending queue message resource model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Model_Mysql4_Resending_Queue_Message extends Mage_Core_Model_Mysql4_Abstract
11
+ {
12
+ /**
13
+ * (non-PHPdoc)
14
+ * @see Varien_Object::_construct()
15
+ */
16
+ public function _construct()
17
+ {
18
+ $this->_init('emvemt/resending_queue_message', 'id');
19
+ }
20
+ }
app/code/community/Emv/Emt/Model/Mysql4/Resending/Queue/Message/Collection.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EmailVision resending queue message collection resource model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Model_Mysql4_Resending_Queue_Message_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
11
+ {
12
+
13
+ /**
14
+ * (non-PHPdoc)
15
+ * @see Mage_Core_Model_Resource_Db_Collection_Abstract::_construct()
16
+ */
17
+ protected function _construct()
18
+ {
19
+ $this->_init('emvemt/resending_queue_message');
20
+ }
21
+
22
+ /**
23
+ * Get list of messages that have not been sent
24
+ *
25
+ * @return Emv_Emt_Model_Mysql4_Resending_Queue_Message_Collection
26
+ */
27
+ public function getListNotSent()
28
+ {
29
+ $this->getSelect()
30
+ ->where('main_table.sent_sucess = ?', Emv_Emt_Model_Resending_Queue_Message::IS_NOT_SENT)
31
+ ->orWhere('main_table.sent_sucess IS NULL')
32
+ ->where('main_table.number_attempts IS NULL OR main_table.number_attempts < ?', Emv_Emt_Model_Resending_Queue_Message::MAX_ATTEMPT)
33
+ ->order('main_table.id');
34
+
35
+ return $this;
36
+ }
37
+ }
app/code/community/Emv/Emt/Model/Resending/Queue.php ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EmailVision resending queue model
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Model_Resending_Queue extends Mage_Core_Model_Abstract
11
+ {
12
+ /**
13
+ * Queue rule
14
+ * @var Emv_Emt_Model_Emt_Resending_Rule
15
+ */
16
+ protected $_rule = null;
17
+
18
+ /**
19
+ * Limit of emails to be sent
20
+ */
21
+ const EMAIL_LIMIT = 500;
22
+
23
+ /**
24
+ * Set message queue rule
25
+ *
26
+ * @param Emv_Emt_Model_Emt_Resending_Rule $rule
27
+ * @return Emv_Emt_Model_Resending_Queue
28
+ */
29
+ public function setRule(Emv_Emt_Model_Emt_Resending_Rule $rule)
30
+ {
31
+ $this->_rule = $rule;
32
+ return $this;
33
+ }
34
+
35
+ /**
36
+ * Get message queue rule
37
+ *
38
+ * @return Emv_Emt_Model_Emt_Resending_Rule
39
+ */
40
+ public function getRule()
41
+ {
42
+ if ($this->_rule == null) {
43
+ $this->_rule = Mage::getModel('emvemt/resending_rule');
44
+ }
45
+ return $this->_rule;
46
+ }
47
+
48
+ /**
49
+ * Reschedule Error Sending. The rule will determine if possible or not and execute the rescheduling.
50
+ *
51
+ * @return Emv_Emt_Model_Resending_Queue
52
+ */
53
+ public function rescheduleErrorSending()
54
+ {
55
+ if (!$this->getRule()->canScheduleErrorSending()) {
56
+ return $this;
57
+ }
58
+
59
+ try {
60
+ $this->getRule()->rescheduleErrorSending();
61
+ } catch (Exception $e) {
62
+ Mage::logException($e);
63
+ }
64
+
65
+ return $this;
66
+ }
67
+
68
+ /**
69
+ * Get all pending messages
70
+ *
71
+ * @return Emv_Emt_Model_Mysql4_Resending_Queue_Message_Collection
72
+ */
73
+ public function getPendingMessages()
74
+ {
75
+ return Mage::getModel('emvemt/resending_queue_message')->getCollection()->getListNotSent();
76
+ }
77
+
78
+ /**
79
+ * Send pending message
80
+ *
81
+ * @return Emv_Emt_Model_Resending_Queue
82
+ */
83
+ public function sendPendingMessages()
84
+ {
85
+ if (!$this->getRule()->canSendPendingMessage()) {
86
+ return $this;
87
+ }
88
+
89
+ /* @var $templateHelper Emv_Emt_Helper_Emvtemplate */
90
+ $templateHelper = Mage::helper('emvemt/emvtemplate');
91
+ /* @var $notificationService Emv_Core_Model_Service_Notification */
92
+ $notificationService = Mage::getSingleton('emvcore/service_notification');
93
+
94
+ $list = $this->getPendingMessages();
95
+ $size = $list->getSize();
96
+ $pageCount = ceil($size / self::EMAIL_LIMIT);
97
+
98
+ for ($curPage = 1; $curPage <= $pageCount; $curPage++) {
99
+ // Define current page
100
+ $list->clear()
101
+ ->setPageSize(self::EMAIL_LIMIT)
102
+ ->setCurPage($curPage);
103
+
104
+ foreach ($list as $message) {
105
+ if (!$this->getRule()->isMessageReadyToBeSent($message)) {
106
+ continue;
107
+ }
108
+
109
+ // need to execute this method in order to have the unserialized variables
110
+ $message->prepareDataAfterLoad();
111
+
112
+ /* @var $message Emv_Emt_Model_Resending_Queue_Message */
113
+ $params = $message->getData('emv_params');
114
+
115
+ $lastEmail = $message->getEmail();
116
+ $emailToSend = $message->getEmail();
117
+ $sentEmail = array();
118
+
119
+ // get account
120
+ $account = null;
121
+ if ($message->getAccountId()) {
122
+ $account = Mage::helper('emvcore')->getAccount($message->getAccountId());
123
+ }
124
+
125
+ // log - prepare log object before sending email
126
+ $sendingData = array(
127
+ 'account' => $account,
128
+ 'magento_template_name' => $message->getData('magento_template_name'),
129
+ 'original_magento_template_name' => $message->getData('original_magento_template_name'),
130
+ );
131
+ $log = $templateHelper->prepareLogBeforeSend(
132
+ $message->getSendingMode(),
133
+ $sendingData,
134
+ $lastEmail,
135
+ $message->getStoreId(),
136
+ Emv_Emt_Model_Log::RESENDING_WORKFLOW
137
+ );
138
+
139
+ $lastData = array('emv_name' => $message->getData('emv_name'));
140
+ try {
141
+ // validate if all SmartFocus parameters are valid
142
+ $templateHelper->validateEmvParams($params);
143
+
144
+ $emvContent = is_array($message->getData('emv_content_variables'))
145
+ ? $message->getData('emv_content_variables') : array();
146
+ $emvAttribute = is_array($message->getData('emv_dyn_variables'))
147
+ ? $message->getData('emv_dyn_variables') : array();
148
+
149
+ // in case we have several emails to send
150
+ foreach($emailToSend as $oneMail ) {
151
+ $lastEmail = $oneMail;
152
+
153
+ // send message
154
+ $result = $notificationService->sendTemplate(
155
+ $params['emv_encrypt'],
156
+ $params['emv_id'],
157
+ $params['emv_random'],
158
+ $oneMail,
159
+ $emvContent,
160
+ $emvAttribute,
161
+ $account,
162
+ $message->getStoreId()
163
+ );
164
+ $sentEmail[] = $oneMail;
165
+
166
+ // if everything is ok, we can send the email
167
+ $templateHelper->prepareLogAfterSend(
168
+ $log,
169
+ $lastData,
170
+ $lastEmail,
171
+ true,
172
+ array(),
173
+ $message->getStoreId()
174
+ );
175
+ }
176
+ } catch(Exception $e) {
177
+ Mage::logException($e);
178
+
179
+ // if error happens, log error
180
+ $error = array(
181
+ 'msg' => $e->getMessage(),
182
+ 'code' => $e->getCode()
183
+ );
184
+
185
+ $templateHelper->prepareLogAfterSend($log, $lastData, $lastEmail, false, $error, $message->getStoreId());
186
+ }
187
+
188
+ // if we couldn't send all scheduled emails
189
+ if (count($emailToSend) != count($sentEmail)) {
190
+ if (count($sentEmail) >= 1) {
191
+ // if message is not correctly sent to all email,
192
+ // we need to reschedule the resending for the rest of emails
193
+ $newMessage = Mage::getModel('emvemt/queue_message');
194
+ $newMessage->setData($message->getData());
195
+ // get the rest of emails to send
196
+ $rest = array_diff($emailToSend, $sentEmail);
197
+ $newMessage->setEmail($rest);
198
+ $newMessage->setSentSucess(false);
199
+ $newMessage->save();
200
+
201
+ $message->addSuccessAttempt();
202
+ } else {
203
+ $message->incrementAttempt();
204
+ }
205
+ } else {
206
+ $message->addSuccessAttempt();
207
+ }
208
+ $message->save();
209
+ }
210
+ }
211
+
212
+ return $this;
213
+ }
214
+ }
app/code/community/Emv/Emt/Model/Resending/Queue/Message.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EmailVision resending queue message model - all timestamp fields are always in GMT
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Model_Resending_Queue_Message extends Emv_Emt_Model_Log
11
+ {
12
+ /**
13
+ * Constant for not sent message
14
+ */
15
+ const IS_NOT_SENT = 0;
16
+
17
+ /**
18
+ * Constant for sent message
19
+ */
20
+ const IS_SENT = 1;
21
+
22
+ /**
23
+ * Resending Max attempt limit
24
+ */
25
+ const MAX_ATTEMPT = 4;
26
+
27
+ /**
28
+ * (non-PHPdoc)
29
+ * @see Varien_Object::_construct()
30
+ */
31
+ public function _construct()
32
+ {
33
+ $this->_init('emvemt/resending_queue_message');
34
+ }
35
+
36
+ /**
37
+ * Add success attempt
38
+ *
39
+ * @return Emv_Emt_Model_Resending_Queue_Message
40
+ */
41
+ public function addSuccessAttempt()
42
+ {
43
+ $this->incrementAttempt();
44
+ $this->setSentSucess(self::IS_SENT);
45
+
46
+ return $this;
47
+ }
48
+
49
+ /**
50
+ * Get number attempts
51
+ *
52
+ * @return int
53
+ */
54
+ public function getNumberAttempts()
55
+ {
56
+ $attempts = $this->getData('number_attempts');
57
+ if (!$attempts) {
58
+ $attempts = 0;
59
+ }
60
+ return $attempts;
61
+ }
62
+
63
+ /**
64
+ * Increment sending attempt
65
+ *
66
+ * @return Emv_Emt_Model_Resending_Queue_Message
67
+ */
68
+ public function incrementAttempt()
69
+ {
70
+ $attempts = $this->getNumberAttempts();
71
+ // get gmt date time
72
+ $gmtDate = Mage::getModel('core/date')->gmtDate();
73
+
74
+ if (!$attempts) {
75
+ $attempts = 1;
76
+ $this->setData('first_attempt', $gmtDate);
77
+ } else {
78
+ $attempts++;
79
+ }
80
+
81
+ $this->setData('last_attempt', $gmtDate);
82
+ $this->setNumberAttempts($attempts);
83
+ return $this;
84
+ }
85
+ }
app/code/community/Emv/Emt/Model/Resending/Rule.php ADDED
@@ -0,0 +1,263 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EmailVision resending rule model
4
+ * - Indicate if some actions (reschedule, or resend emails) are available or not
5
+ * - Perform rescheduling error sending
6
+ * - handle the lock mechanism in order to avoid several processes running at the same time
7
+ *
8
+ * @category Emv
9
+ * @package Emv_Emt
10
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
11
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
12
+ */
13
+ class Emv_Emt_Model_Resending_Rule extends Mage_Core_Model_Abstract
14
+ {
15
+ /**
16
+ * XML Path to configs for resending mechanism
17
+ */
18
+ const XML_PATH_RESENDING_ACTIVE = 'emvemt/resending_mechanism/enabled';
19
+ const XML_PATH_FIRST_DELAY = 'emvemt/resending_mechanism/first_delay';
20
+ const XML_PATH_SECOND_DELAY = 'emvemt/resending_mechanism/second_delay';
21
+ const XML_PATH_THIRD_DELAY = 'emvemt/resending_mechanism/third_delay';
22
+ const XML_PATH_FOURTH_DELAY = 'emvemt/resending_mechanism/fourth_delay';
23
+
24
+ /**
25
+ * Lock file name pattern
26
+ */
27
+ const LOCK_FILE_NAME_PATTERN = 'email_resending_process.lock';
28
+
29
+ /**
30
+ * Is resending mechanism activated ?
31
+ *
32
+ * @return boolean
33
+ */
34
+ public function isResendingMechanismActivated()
35
+ {
36
+ return (bool)Mage::getStoreConfig(self::XML_PATH_RESENDING_ACTIVE);
37
+ }
38
+
39
+ /**
40
+ * Can send pending message ?
41
+ *
42
+ * @return boolean
43
+ */
44
+ public function canSendPendingMessage()
45
+ {
46
+ return $this->isResendingMechanismActivated();
47
+ }
48
+
49
+ /**
50
+ * Can schedule error sending ?
51
+ *
52
+ * @return boolean
53
+ */
54
+ public function canScheduleErrorSending()
55
+ {
56
+ return $this->isResendingMechanismActivated();
57
+ }
58
+
59
+ /**
60
+ * Reschedule all error sending
61
+ * - 1. get all error sending email list
62
+ * - 2. convert these into resending queue messages
63
+ * - 3. flag all transformed error sending emails to avoid converting in resending queue messages next time again
64
+ *
65
+ * @return Emv_Emt_Model_Resending_Rule
66
+ */
67
+ public function rescheduleErrorSending()
68
+ {
69
+ $sql = $this->prepareSelectToGetErrorSending();
70
+
71
+ $dbConnection = Mage::getSingleton('core/resource')->getConnection('core_write');
72
+ $result = $dbConnection->query($sql)->fetchAll();
73
+
74
+ // prepare error list
75
+ $list = array();
76
+ foreach ($result as $error) {
77
+ if (isset($error['id'])) {
78
+ $list[] = $error['id'];
79
+ }
80
+ }
81
+
82
+ // if we have error sending
83
+ if (count($list)) {
84
+ // reschedule all error sending
85
+ $select = $this->prepareQueryToRescheduleErrorSending($list);
86
+ $result = $dbConnection->query($select);
87
+
88
+ if ($result) {
89
+ $select = $this->prepareQueryToFlagAllErrorSending($list);
90
+ $result = $dbConnection->query($select);
91
+ }
92
+ }
93
+ return $this;
94
+ }
95
+
96
+ /**
97
+ * Prepare query to reschedule all error sending
98
+ * - Use replace into to update and create new resending queue messages from error sending emails
99
+ *
100
+ * @return string
101
+ */
102
+ public function prepareQueryToRescheduleErrorSending(array $listError)
103
+ {
104
+ $resource = Mage::getModel('core/resource');
105
+ $logTable = $resource->getTableName('emvemt/log');
106
+ $messageTable = $resource->getTableName('emvemt/resending_queue_message');
107
+ $gmtDate = Mage::getModel('core/date')->gmtDate();
108
+ $listError = implode(',', $listError);
109
+
110
+ $select = "
111
+ REPLACE INTO `{$messageTable}`
112
+ (
113
+ `created_at`, `sent_sucess`, `number_attempts`, `sending_mode`, `email`, `store_id`, `account_id`, `magento_template_name`, `original_magento_template_name`,
114
+ `emv_name`, `emv_params`, `emv_content_variables`, `emv_dyn_variables`
115
+ )
116
+ SELECT
117
+ '$gmtDate' AS `created_at`, 0 AS `sent_sucess`, 0 AS `number_attempts`, `sending_mode`, `email`, `store_id`, `account_id`, `magento_template_name`, `original_magento_template_name`,
118
+ `emv_name`, `emv_params`, `emv_content_variables`, `emv_dyn_variables`
119
+
120
+ FROM `{$logTable}`
121
+ WHERE `id` IN ({$listError})
122
+ ";
123
+
124
+ return $select;
125
+ }
126
+
127
+ /**
128
+ * Prepare select to get list of error sending
129
+ *
130
+ * @return string
131
+ */
132
+ public function prepareSelectToGetErrorSending()
133
+ {
134
+ $resource = Mage::getModel('core/resource');
135
+ $logTable = $resource->getTableName('emvemt/log');
136
+ $messageTable = $resource->getTableName('emvemt/resending_queue_message');
137
+ $gmtDate = Mage::getModel('core/date')->gmtDate();
138
+ $sendingType = Emv_Emt_Model_Log::SENDING_BASIC_WORKFLOW;
139
+ $rescheduled = Emv_Emt_Model_Log::RESCHEDULED;
140
+
141
+ $select = "
142
+ SELECT `id`
143
+ FROM `{$logTable}`
144
+ WHERE `error` IS NOT NULL
145
+ AND `emv_params` IS NOT NULL
146
+ AND `sending_type` = '{$sendingType}'
147
+ AND `rescheduled` != {$rescheduled}
148
+ ";
149
+
150
+ return $select;
151
+ }
152
+
153
+ /**
154
+ * Prepare query to flag all error sending
155
+ *
156
+ * @param array $listError
157
+ * @return string
158
+ */
159
+ public function prepareQueryToFlagAllErrorSending(array $listError)
160
+ {
161
+ $resource = Mage::getModel('core/resource');
162
+ $listError = implode(',', $listError);
163
+ $logTable = $resource->getTableName('emvemt/log');
164
+ $rescheduled = Emv_Emt_Model_Log::RESCHEDULED;
165
+ $select = "
166
+ UPDATE `{$logTable}`
167
+ SET rescheduled = {$rescheduled}
168
+ WHERE `id` IN ({$listError})
169
+ ";
170
+
171
+ return $select;
172
+ }
173
+
174
+ /**
175
+ * Check if lock file exists
176
+ *
177
+ * @throw Exception $e - if have some write problem permission
178
+ * @return boolean
179
+ */
180
+ public function lockExists()
181
+ {
182
+ $lockExists = Mage::helper('emvcore')->checkLockFile(self::LOCK_FILE_NAME_PATTERN);
183
+ return $lockExists;
184
+ }
185
+
186
+ /**
187
+ * Remove lock file
188
+ *
189
+ * @throw Exception $e - if have some write problem permission
190
+ * @return boolean
191
+ */
192
+ public function removeLock()
193
+ {
194
+ return Mage::helper('emvcore')->removeLockFile(self::LOCK_FILE_NAME_PATTERN);
195
+ }
196
+
197
+ /**
198
+ * Create lock file
199
+ *
200
+ * @throw Exception $e - if have some write problem permission
201
+ * @return boolean
202
+ */
203
+ public function createLock($content = '')
204
+ {
205
+ if (!$content) {
206
+ $content = 'email_resending_process at ' . Mage::getModel('core/date')->date('Y-m-d H:i:s');
207
+ }
208
+ return Mage::helper('emvcore')->createLockFile(self::LOCK_FILE_NAME_PATTERN, $content);
209
+ }
210
+
211
+ /**
212
+ * Check if message is ready to be sent according to the delay configurations (first delay, second delay...)
213
+ *
214
+ * @param Emv_Emt_Model_Emt_Resending_Queue_Message $message
215
+ * @return boolean
216
+ */
217
+ public function isMessageReadyToBeSent(Emv_Emt_Model_Resending_Queue_Message $message)
218
+ {
219
+ $isAllowed = false;
220
+ // all calculations need to be done in GMT
221
+ if ($message->getLastAttempt()) {
222
+ $lastAttempt = strtotime($message->getLastAttempt());
223
+ } else {
224
+ $lastAttempt = strtotime($message->getCreatedAt());
225
+ }
226
+
227
+ // gmt time stamp
228
+ $now = Mage::getModel('core/date')->gmtTimestamp();
229
+ $delta = abs($now - $lastAttempt);
230
+ $deltaInMinutes = ceil($delta/60);
231
+
232
+ $attempts = $message->getNumberAttempts();
233
+ // the cron is planned every 5 minutes so we need to planify every thing with 5 minutes of difference
234
+ switch (($attempts % Emv_Emt_Model_Resending_Queue_Message::MAX_ATTEMPT)) {
235
+ case 0 :
236
+ $firstDelay = Mage::getStoreConfig(self::XML_PATH_FIRST_DELAY);
237
+ if ($firstDelay && $deltaInMinutes >= $firstDelay) {
238
+ $isAllowed = true;
239
+ }
240
+ break;
241
+ case 1 :
242
+ $secondDelay = Mage::getStoreConfig(self::XML_PATH_SECOND_DELAY);
243
+ if ($secondDelay && $deltaInMinutes >= $secondDelay) {
244
+ $isAllowed = true;
245
+ }
246
+ break;
247
+ case 2 :
248
+ $thirdDelay = Mage::getStoreConfig(self::XML_PATH_THIRD_DELAY);
249
+ if ($thirdDelay && $deltaInMinutes >= $thirdDelay) {
250
+ $isAllowed = true;
251
+ }
252
+ break;
253
+ case 3 :
254
+ $fourthDelay = Mage::getStoreConfig(self::XML_PATH_FOURTH_DELAY);
255
+ if ($fourthDelay && $deltaInMinutes >= $fourthDelay) {
256
+ $isAllowed = true;
257
+ }
258
+ break;
259
+ }
260
+
261
+ return $isAllowed;
262
+ }
263
+ }
app/code/community/Emv/Emt/Model/Resource/Setup.php CHANGED
@@ -1,10 +1,11 @@
1
  <?php
2
  /**
3
- *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{4757F1CF-7E30-475d-B6FA-81A4944D693F}
 
8
  */
9
  class Emv_Emt_Model_Resource_Setup extends Mage_Core_Model_Resource_Setup
10
  {
1
  <?php
2
  /**
3
+ * EmailVision emt resource setup class
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
  */
10
  class Emv_Emt_Model_Resource_Setup extends Mage_Core_Model_Resource_Setup
11
  {
app/code/community/Emv/Emt/controllers/Adminhtml/EmtController.php DELETED
@@ -1,484 +0,0 @@
1
- <?php
2
- /**
3
- *
4
- * @category
5
- * @package
6
- * @author cservieres <info@x2i.fr>
7
- * @version 1.0 eaGUID{C6D231D8-0B37-457d-9DE1-7B4AA8B86B9B}
8
- */
9
- class Emv_Emt_Adminhtml_EmtController extends Mage_Adminhtml_Controller_Action
10
- {
11
-
12
- protected function _initAction()
13
- {
14
- $this->loadLayout();
15
- $this->_setActiveMenu('system/emvemt');
16
- }
17
-
18
- /**
19
- * Initialise the account model.
20
- *
21
- * @return Emv_Emt_Model_Emt
22
- */
23
- protected function _initEmt()
24
- {
25
- $id = $this->getRequest()->getParam('id', null);
26
- $emtModel = Mage::getModel('emvemt/emt')->load($id);
27
- Mage::register('current_emvemt', $emtModel);
28
-
29
- // take attributes of this emt
30
- $collection = Mage::getResourceModel('emvemt/attribute_collection')
31
- ->addEmtFilter($emtModel->getId())
32
- ->load();
33
- $result = array();
34
- foreach ($collection as $attribute) {
35
- $result[] = $attribute->getData();
36
- }
37
-
38
- Mage::register('emt_attributes', $result);
39
-
40
- return $emtModel;
41
- }
42
-
43
- /**
44
- * opGUID{013E0776-95CB-44d2-97D3-DC99D91F7C34}
45
- */
46
- public function indexAction()
47
- {
48
- $this->_initAction();
49
- $this->_addContent($this->getLayout()->createBlock('emvemt/adminhtml_emts'));
50
- $this->renderLayout();
51
- }
52
-
53
- /**
54
- * opGUID{FF53F7D3-4A3E-4549-B687-FF295606F803}
55
- */
56
- public function editAction()
57
- {
58
- $this->_initAction();
59
- $emtModel = $this->_initEmt();
60
-
61
- $data = $this->_getSession()->getEditEmtFormData(true);
62
- if(isset($data))
63
- {
64
- // set entered data if was error when we do save
65
- $emtModel->addData($data);
66
- }
67
-
68
- try {
69
- if(null !== $emtModel->getEmvAccountId() && null !== $emtModel->getEmvTemplateId())
70
- {
71
- /* @var $account Emv_Core_Model_Account */
72
- $account = Mage::getModel('emvcore/account')->load($emtModel->getEmvAccountId());
73
-
74
- /* @var $soap Emv_Core_Model_Service_Soap_Api */
75
- $soap = Mage::getModel('emvcore/service_soap_api', $account);
76
-
77
- Mage::register('current_emv_template_array',
78
- $soap->getTemplateInfoInArray($emtModel->getEmvTemplateId()));
79
- }
80
-
81
- $mageTemplateName = Mage::getModel('core/email_template')
82
- ->load($emtModel->getMageTemplateId())->getTemplateCode();
83
- Mage::register('mage_template_name', $mageTemplateName);
84
- Mage::register('emt_accounts', Mage::getResourceModel('emvcore/account_collection'));
85
- Mage::register('mail_modes', Mage::getResourceModel('emvemt/mailmode_collection'));
86
- Mage::register('mage_templates', Mage::getResourceModel('core/email_template_collection'));
87
-
88
- $this->_addContent($this->getLayout()->createBlock('emvemt/adminhtml_emt_edit'));
89
- $this->renderLayout();
90
- } catch (Exception $e) {
91
- $this->_getSession()->addError($e->getMessage());
92
- $this->_redirect('*/*/index');
93
- return;
94
- }
95
- }
96
-
97
- public function newAction()
98
- {
99
-
100
- // Check if an emv account is set
101
- $emvAccount = Mage::getResourceModel('emvcore/account_collection');
102
- $accountId = $emvAccount->getFirstItem()->getId();
103
- if(null === $accountId)
104
- {
105
- $this->_getSession()->addError(Mage::helper('emvemt')->__('A Campaign Commander account has not been set.'));
106
- $this->_redirect('*/*/index');
107
- return;
108
- }
109
-
110
- $this->_initAction();
111
- $this->_addContent($this->getLayout()->createBlock('emvemt/adminhtml_emt_new'));
112
- $this->renderLayout();
113
- }
114
-
115
- /**
116
- * Return an select with emv from periode $from to $to
117
- */
118
- public function getEmvTemplateSelectAjaxAction()
119
- {
120
- $data = $this->getRequest()->getPost();
121
- $data['from'] = Mage::helper('core')->escapeHtml($data['from']);
122
- $data['to'] = Mage::helper('core')->escapeHtml($data['to']);
123
- $data['accountId'] = Mage::helper('core')->escapeHtml($data['accountId']);
124
- $dateFormatIso = Mage::app()->getLocale()->getDateFormat(
125
- Mage_Core_Model_Locale::FORMAT_TYPE_SHORT
126
- );
127
-
128
- $locale = Mage::app()->getLocale()->getLocale();
129
-
130
- /* @var $from_2 Zend_Date */
131
- /* @var $to_2 Zend_Date */
132
- if(!Zend_Date::isDate($data['from'], $dateFormatIso, $locale))
133
- {
134
- //set a default large periode to match all campaign commander templates
135
- $from_2 = new Zend_Date('1980-01-01', 'YYYY-MM-dd', $locale);
136
- }
137
- else
138
- {
139
- $from_2 = new Zend_Date($data['from'], $dateFormatIso, $locale);
140
- }
141
-
142
- if(!Zend_Date::isDate($data['to'], $dateFormatIso, $locale))
143
- {
144
- $to_2 = Zend_Date::now($locale);
145
- }
146
- else
147
- {
148
- $to_2 = new Zend_Date($data['to'], $dateFormatIso, $locale);
149
- }
150
-
151
- // make the period cover all the day because Zend_Date set hour to 00:00:00 by default
152
- // so we add 23h59m59s
153
- $to_2->addHour(23);
154
- $to_2->addMinute(59);
155
- $to_2->addSecond(59);
156
-
157
- $apiDateFormat = 'YYYY-MM-dd HH:mm:ss';
158
-
159
- try {
160
- /* @var $account Emv_Core_Model_Account */
161
- $account = Mage::getModel('emvcore/account')->load($data['accountId']);
162
-
163
- /* @var $soap Emv_Core_Model_Service_Soap_Api */
164
- $soap = Mage::getModel('emvcore/service_soap_api', $account);
165
-
166
- $templatesId = $soap->getTemplatesByPeriod($from_2->toString($apiDateFormat),
167
- $to_2->toString($apiDateFormat));
168
-
169
- $options = array();
170
- if(is_array($templatesId))
171
- {
172
- foreach ($templatesId as $templateId)
173
- {
174
- $options[] = $soap->getTemplateInfoInArray($templateId);
175
- }
176
- }
177
- elseif($templatesId !== null)
178
- {
179
- $options[] = $soap->getTemplateInfoInArray($templatesId);
180
- }
181
- else
182
- {
183
- echo '<strong id="emv_template_id">'.
184
- Mage::helper('emvemt')->__('There isn\'t any template in this period').
185
- '</strong>';
186
- return;
187
- }
188
-
189
- $select = $this->getLayout()->createBlock('adminhtml/html_select')
190
- ->setId('emv_template_id')
191
- ->setName('emv_template_id')
192
- ->setOptions($options);
193
-
194
- echo $select->getHtml();
195
- } catch (Exception $e) {
196
- echo $e->getMessage();
197
- }
198
- }
199
-
200
- /**
201
- * Display a select of magento template not already mapped with the emv account given in post
202
- */
203
- public function getNotMappedMagentoTemplateSelectAjaxAction()
204
- {
205
- $data = $this->getRequest()->getPost();
206
-
207
- /* @var $magentoTemplates Mage_Core_Model_Mysql4_Email_Template_Collection */
208
- $magentoTemplates = Mage::getModel('emvemt/mageTemplate')->getNotMappedMageTemplateCollection($data['emvAccount']);
209
-
210
- if($magentoTemplates->getSize() == 0)
211
- {
212
- echo '<strong id="mage_template_id">'.
213
- Mage::helper('emvemt')->__('There is no Magento templates not mapped with this account.').
214
- '</strong>';
215
- }
216
- else
217
- {
218
- $options = $magentoTemplates->toOptionArray();
219
-
220
- $select = $this->getLayout()->createBlock('adminhtml/html_select')
221
- ->setId('mage_template_id')
222
- ->setName('mage_template_id')
223
- ->setOptions($options);
224
-
225
- echo $select->getHtml();
226
- }
227
- }
228
-
229
- public function getEmvAttributesSelectAjaxAction()
230
- {
231
- $data = $this->getRequest()->getPost();
232
-
233
- $data['emv_attribute_type'] = Mage::helper('core')->escapeHtml($data['emv_attribute_type']);
234
- $data['emvTemplateId'] = Mage::helper('core')->escapeHtml($data['emvTemplateId']);
235
- $data['index'] = Mage::helper('core')->escapeHtml($data['index']);
236
- $data['accountId'] = Mage::helper('core')->escapeHtml($data['accountId']);
237
- if(key_exists('default_value', $data))
238
- {
239
- $data['default_value'] = Mage::helper('core')->escapeHtml($data['default_value']);
240
- }
241
-
242
- if(isset($data['emvTemplateId']))
243
- {
244
- $options = array('' => $this->__('Custom attribute, no mapping'));
245
-
246
- /* @var $account Emv_Core_Model_Account */
247
- $account = Mage::getModel('emvcore/account')->load($data['accountId']);
248
-
249
- /* @var $soap Emv_Core_Model_Service_Soap_Api */
250
- $soap = Mage::getModel('emvcore/service_soap_api', $account);
251
-
252
- try {
253
- $template = $soap->getTemplateById($data['emvTemplateId']);
254
-
255
- $text = '';
256
- if(isset($template->body))
257
- {
258
- $text .= $template->body;
259
- }
260
- if(isset($template->from))
261
- {
262
- $text .= $template->from;
263
- }
264
- if(isset($template->to))
265
- {
266
- $text .= $template->to;
267
- }
268
- if(isset($template->replyTo))
269
- {
270
- $text .= $template->replyTo;
271
- }
272
- if(isset($template->replyToEmail))
273
- {
274
- $text .= $template->replyToEmail;
275
- }
276
- if(isset($template->subject))
277
- {
278
- $text .= $template->subject;
279
- }
280
-
281
- $attributes = array();
282
-
283
- if(Emv_Emt_Constants::ATTRIBUTE_TYPE_EMV_CONTENT == $data['emv_attribute_type'])
284
- {
285
- $attributes = Mage::helper('emvemt/emvtemplate')->getEmvAttributesContentFromText($text);
286
- }
287
- elseif(Emv_Emt_Constants::ATTRIBUTE_TYPE_EMV_DYN == $data['emv_attribute_type'])
288
- {
289
- $attributes = Mage::helper('emvemt/emvtemplate')->getEmvAttributesFromText($text);
290
- }
291
-
292
- foreach ($attributes as $attribute)
293
- {
294
- $options[$attribute] = $attribute;
295
- }
296
-
297
- $select = $this->getLayout()->createBlock('adminhtml/html_select')
298
- ->setId('emv_attribute_'.$data['index'].'_emv_attribute')
299
- ->setName('attributes['.$data['index'].'][emv_attribute]')
300
- ->setOptions($options);
301
- if(isset($data['default_value']))
302
- {
303
- $select->setValue($data['default_value']);
304
- }
305
- echo $select->getHtml();
306
- } catch (Exception $e) {
307
- echo $e->getMessage();
308
- }
309
- }
310
- }
311
-
312
- public function saveAction()
313
- {
314
- if ($data = $this->getRequest()->getPost())
315
- {
316
- $emtId = $this->getRequest()->getParam('id', null);
317
-
318
- $emtModel = Mage::getModel('emvemt/emt')->load($emtId);
319
- $emtModel->addData($data);
320
-
321
- //reset emt template if user switch mail mode from 'emv create / Campaign Commander Template' to 'emv send' or 'classic'
322
- if($emtModel->getEmvSendMailModeId() ===
323
- Mage::getModel('emvemt/mailmode')->getIdByName(Emv_Emt_Constants::CLASSIC_FLAG) ||
324
- $emtModel->getEmvSendMailModeId() ===
325
- Mage::getModel('emvemt/mailmode')->getIdByName(Emv_Emt_Constants::EMV_SEND_FLAG))
326
- {
327
- $emtModel->setEmvTemplateId(null);
328
- }
329
-
330
- if (null !== $emtId)
331
- {
332
- // we're in mode edit (2nd form)
333
- $result = $emtModel->validate();
334
- if (is_array($result))
335
- {
336
- $this->_getSession()->setEditEmtFormData($data);
337
- foreach ($result as $message)
338
- {
339
- $this->_getSession()->addError($message);
340
- }
341
- $this->_redirect('*/*/edit', array('id'=>$emtModel->getId()));
342
- return $this;
343
- }
344
- }
345
- else
346
- {
347
- // set send mode to classic by default
348
- $emtModel->setEmvSendMailModeId(
349
- Mage::getModel('emvemt/mailmode')->getIdByName(Emv_Emt_Constants::CLASSIC_FLAG));
350
-
351
- // we're in 1st form
352
- $result = $emtModel->validateNewForm();
353
-
354
- if (is_array($result))
355
- {
356
- foreach ($result as $message)
357
- {
358
- $this->_getSession()->addError($message);
359
- }
360
- $this->_redirect('*/*/new');
361
- return $this;
362
- }
363
- }
364
-
365
- try {
366
- $emtModel->save();
367
-
368
- if(null !== $emtId)
369
- {
370
- // User come from edit mode
371
- // delete old mapping attribute
372
- $this->_deleteAllEmtAttribute($emtModel->getId());
373
-
374
- if($emtModel->getEmvSendMailModeId() ===
375
- Mage::getModel('emvemt/mailmode')->getIdByName(Emv_Emt_Constants::EMV_CREATE_FLAG))
376
- {
377
- $attributes = $this->getRequest()->getParam('attributes');
378
- if (is_array($attributes))
379
- {
380
- $modelId = $emtModel->getId();
381
-
382
- foreach ($attributes as $attrInfo)
383
- {
384
- if (isset($attrInfo['delete']) && $attrInfo['delete'] == 1) {
385
- continue;
386
- }
387
-
388
- $attributeModel = Mage::getModel('emvemt/attribute')
389
- ->setEmvAttribute($attrInfo['emv_attribute'])
390
- ->setEmvAttributeType($attrInfo['emv_attribute_type'])
391
- ->setMageAttribute($attrInfo['mage_attribute'])
392
- ->setEmvEmtId($modelId);
393
-
394
- $result = $attributeModel->validate();
395
-
396
- if (is_array($result))
397
- {
398
- $this->_getSession()->setEditEmtFormData($data);
399
- foreach ($result as $message)
400
- {
401
- $this->_getSession()->addError($message);
402
- }
403
- $this->_redirect('*/*/edit', array('id'=>$emtModel->getId()));
404
- return $this;
405
- }
406
- $attributeModel->save();
407
- }
408
- }
409
- }
410
- $this->_getSession()->addSuccess(
411
- Mage::helper('emvemt')->__('The Campaign Commander account has been saved.'));
412
- $this->_redirect('*/*/');
413
- }
414
- else
415
- {
416
- //user come from New form so we redirect him to second part of form (edit)
417
- $this->_redirect('*/*/edit', array('id'=>$emtModel->getId()));
418
- }
419
- return;
420
- } catch (Exception $e) {
421
- $this->_getSession()->addError($e->getMessage());
422
- $this->_getSession()->setEditEmtFormData($data);
423
- if(null !== $emtId)
424
- {
425
- $this->_redirect('*/*/edit', array('id'=>$emtModel->getId()));
426
- }
427
- else
428
- {
429
- $this->_redirect('*/*/');
430
- }
431
- return;
432
- }
433
- }
434
- $this->_redirect('*/*/');
435
- return;
436
- }
437
-
438
- /**
439
- * Delete all mapping attribute of an emt
440
- **/
441
- protected function _deleteAllEmtAttribute($emtId)
442
- {
443
- $collection = Mage::getResourceModel('emvemt/attribute_collection')
444
- ->addEmtFilter($emtId);
445
- $collection->walk('delete');
446
- }
447
-
448
- public function deleteAction()
449
- {
450
- if ($id = $this->getRequest()->getParam('id'))
451
- {
452
- try {
453
- $this->_deleteAllEmtAttribute($id);
454
-
455
- $model = Mage::getModel('emvemt/emt')->load($id);
456
- $model->delete();
457
- $this->_getSession()->addSuccess(
458
- Mage::helper('emvemt')->__('EMT deleted.'));
459
- $this->_redirect('*/*/');
460
- return;
461
- }
462
- catch (Exception $e) {
463
- $this->_getSession()->addError($e->getMessage());
464
- $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getPost('id')));
465
- return;
466
- }
467
- }
468
- Mage::getSingleton('adminhtml/session')->addError(Mage::helper('emvemt')
469
- ->__('Unable to find an emt to delete.'));
470
- $this->_redirect('*/*/');
471
- }
472
-
473
- /**
474
- * opGUID{DEBEFFFC-1E57-43a2-8A05-DA0F0F15FAE2}
475
- *
476
- * @return boolean
477
- */
478
- protected function _isallowed()
479
- {
480
- //TODO
481
- return true;
482
- }
483
-
484
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/code/community/Emv/Emt/controllers/Adminhtml/LogController.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Sending Log controller
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Adminhtml_LogController extends Mage_Adminhtml_Controller_Action
11
+ {
12
+
13
+ /**
14
+ * Inialize action
15
+ */
16
+ protected function _initAction()
17
+ {
18
+ $this->loadLayout();
19
+ $this->_setActiveMenu('emailvision/emvemt');
20
+ $this->_title(Mage::helper('emvemt')->__('SmartFocus'))
21
+ ->_title(Mage::helper('emvemt')->__('Email Sending Logs'));
22
+ }
23
+ /**
24
+ * Index action - display a grid of all email sending log
25
+ */
26
+ public function indexAction()
27
+ {
28
+ $this->_initAction();
29
+ $this->_addContent($this->getLayout()->createBlock('emvemt/adminhtml_log'));
30
+ $this->renderLayout();
31
+ }
32
+
33
+ /**
34
+ * Mass delete action
35
+ */
36
+ public function massDeleteAction()
37
+ {
38
+ $logIds = $this->getRequest()->getParam('log');
39
+ if (!is_array($logIds)) {
40
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('emvemt')->__('Please select email sending log(s) !'));
41
+ } else {
42
+ try {
43
+ $log = Mage::getModel('emvemt/log');
44
+ foreach ($logIds as $id) {
45
+ $log->setId($id)
46
+ ->delete();
47
+ }
48
+ Mage::getSingleton('adminhtml/session')->addSuccess(
49
+ Mage::helper('adminhtml')->__('Total of %d record(s) were deleted.', count($logIds))
50
+ );
51
+ } catch (Exception $e) {
52
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
53
+ }
54
+ }
55
+
56
+ $this->_redirect('*/*/index');
57
+ }
58
+
59
+ public function getErrorAction()
60
+ {
61
+ $id = $this->getRequest()->getParam('id');
62
+ $log = Mage::getModel('emvemt/log');
63
+ $log->load($id);
64
+
65
+ $content = $log->getError();
66
+ if ($content) {
67
+ $this->_prepareDownloadResponse('error-log.txt', $content);
68
+ } else {
69
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('emvemt')->__('Not found error log !'));
70
+ $this->_redirect('*/*/index');
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Check if having a correct permission
76
+ *
77
+ * @return boolean
78
+ */
79
+ protected function _isallowed()
80
+ {
81
+ return Mage::getSingleton('admin/session')->isAllowed('emailvision/emvemt/log');
82
+ }
83
+ }
app/code/community/Emv/Emt/controllers/Adminhtml/RescheduleController.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Sending Log controller
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Adminhtml_RescheduleController extends Mage_Adminhtml_Controller_Action
11
+ {
12
+
13
+ /**
14
+ * Inialize action
15
+ */
16
+ protected function _initAction()
17
+ {
18
+ $this->loadLayout();
19
+ $this->_setActiveMenu('emailvision/emvemt');
20
+ $this->_title(Mage::helper('emvemt')->__('SmartFocus'))
21
+ ->_title(Mage::helper('emvemt')->__('Re-scheduled Email List'));
22
+ }
23
+ /**
24
+ * Index action - display a grid of rescheduled emails
25
+ */
26
+ public function indexAction()
27
+ {
28
+ $this->_initAction();
29
+ $this->_addContent($this->getLayout()->createBlock('emvemt/adminhtml_resending'));
30
+ $this->renderLayout();
31
+ }
32
+
33
+ /**
34
+ * Mass delete action
35
+ */
36
+ public function massDeleteAction()
37
+ {
38
+ $resendingIds = $this->getRequest()->getParam('resending_message');
39
+ if (!is_array($resendingIds)) {
40
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('emvemt')->__('Please select record(s) !'));
41
+ } else {
42
+ try {
43
+ $resendingMessage = Mage::getModel('emvemt/resending_queue_message');
44
+ foreach ($resendingIds as $id) {
45
+ $resendingMessage->setId($id)
46
+ ->delete();
47
+ }
48
+ Mage::getSingleton('adminhtml/session')->addSuccess(
49
+ Mage::helper('adminhtml')->__('Total of %d record(s) were deleted.', count($resendingIds))
50
+ );
51
+ } catch (Exception $e) {
52
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
53
+ }
54
+ }
55
+
56
+ $this->_redirect('*/*/index');
57
+ }
58
+
59
+ /**
60
+ * Check if having a correct permission
61
+ *
62
+ * @return boolean
63
+ */
64
+ protected function _isallowed()
65
+ {
66
+ return Mage::getSingleton('admin/session')->isAllowed('emailvision/emvemt/reschedule');
67
+ }
68
+ }
app/code/community/Emv/Emt/controllers/Adminhtml/TemplateController.php ADDED
@@ -0,0 +1,716 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * SmartFocus email template controller
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Emt
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Emt_Adminhtml_TemplateController extends Mage_Adminhtml_Controller_Action
11
+ {
12
+ /**
13
+ * Registry variables
14
+ */
15
+ const EMV_ATTRIBUTES_REGISTRY = 'emt_attributes';
16
+ const EMV_TEMPLATE_REGISTRY = 'current_emv_template';
17
+ const EMV_TEMPLATE_ARRAY_REGISTRY = 'current_emv_template_array';
18
+ const MAGE_TEMPLATE_NAME_REGISTRY = 'mage_template_name';
19
+ const CURRENT_EMVEMT_TEMPLATE_REGISTRY = 'current_emvemt';
20
+ const INVALID_FIELD_EMV_TEMPLATE_REGISTRY = 'invalid_emt_fields';
21
+ const EMV_AVAILABLE_ATTRIBUTE_REGISTRY = 'available_emv_attributes';
22
+
23
+ /**
24
+ * Date format for API
25
+ */
26
+ const API_DATE_FORMAT = 'YYYY-MM-ddTHH:mm:ssZZZZ';
27
+
28
+ /**
29
+ * Check if having a correct permission
30
+ *
31
+ * @return boolean
32
+ */
33
+ protected function _isallowed()
34
+ {
35
+ return Mage::getSingleton('admin/session')->isAllowed('emailvision/emvemt/emt');
36
+ }
37
+
38
+ /**
39
+ * Inialize action
40
+ */
41
+ protected function _initAction()
42
+ {
43
+ $this->loadLayout()
44
+ ->_setActiveMenu('emailvision/emvemt');
45
+
46
+ $this->_title(Mage::helper('emvemt')->__('SmartFocus'))
47
+ ->_title(Mage::helper('emvemt')->__('Manage Email Templates'));
48
+ }
49
+
50
+ /**
51
+ * Action to create a new campaign commander template mapping
52
+ */
53
+ public function newAction()
54
+ {
55
+ // Check if an emv account is set
56
+ $emvAccount = Mage::getResourceModel('emvcore/account_collection');
57
+ $accountId = $emvAccount->getFirstItem()->getId();
58
+ if (null === $accountId) {
59
+ // get back to template grid and display the errors
60
+ $this->_getSession()->addError(Mage::helper('emvemt')->__('SmartFocus account has not been set !'));
61
+ $this->_redirect('*/*/index');
62
+ return;
63
+ }
64
+
65
+ $this->_initAction();
66
+ $this->_title(Mage::helper('emvemt')->__('New Template'));
67
+
68
+ $this->_addContent($this->getLayout()->createBlock('emvemt/adminhtml_template_edit'))
69
+ ->_addLeft($this->getLayout()->createBlock('emvemt/adminhtml_template_edit_tabs'))
70
+ ;
71
+ $this->renderLayout();
72
+ }
73
+
74
+ /**
75
+ * Index action - display a grid of SmartFocus templates
76
+ */
77
+ public function indexAction()
78
+ {
79
+ // save all messages from session
80
+ $this->getLayout()->getMessagesBlock()->setMessages(
81
+ $this->_getSession()->getMessages()
82
+ );
83
+
84
+ $this->_initAction();
85
+
86
+ $this->_addContent($this->getLayout()->createBlock('emvemt/adminhtml_templates'));
87
+ $this->renderLayout();
88
+ }
89
+
90
+ /**
91
+ * EmailVision template edit action
92
+ */
93
+ public function editAction()
94
+ {
95
+ $emtModel = $this->_initEmt();
96
+
97
+ // prepare attribute data form
98
+ $data = $this->_getSession()->getData('edit_emt_form_data',true);
99
+ $attributeData = array();
100
+ if (isset($data)) {
101
+ // set entered data if was error when we do save
102
+ $emtModel->addData($data);
103
+ }
104
+
105
+ if ($emtModel->getId() && $emtModel->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::EMV_CREATE){
106
+ // take attributes of this emt
107
+ $collection = Mage::getResourceModel('emvemt/attribute_collection')
108
+ ->addEmtFilter($emtModel->getId())
109
+ ->load();
110
+
111
+ $attributeData = $collection->getItems();
112
+ } else {
113
+ // get back attribute data
114
+ if ($data && isset($data['attributes']) && is_array($data['attributes'])) {
115
+ $attributeData = $data['attributes'];
116
+ }
117
+ }
118
+ Mage::register(self::EMV_ATTRIBUTES_REGISTRY, $attributeData);
119
+
120
+ // don't display form if account does not exist in database
121
+ $account = $emtModel->getAccount();
122
+ if (!$account && null !== $emtModel->getEmvAccountId()) {
123
+ $this->_getSession()->addError(
124
+ Mage::helper('emvemt')
125
+ ->__('Your SmartFocus account associated to this template does not exist anymore ! Please delete it !')
126
+ );
127
+ $this->_redirect('*/*/');
128
+ return;
129
+ }
130
+
131
+ // try to retreive invalid fields if we just came back from save action
132
+ // all invalid fields are stored in session
133
+ $invalidFields = $this->_getSession()->getData('invalid_emt_fields',true);
134
+ if (!$invalidFields) {
135
+ $invalidFields = array();
136
+ }
137
+
138
+ $options = null;
139
+ $emvParams = $emtModel->getEmailVisionParams();
140
+ if ($emvParams && is_array($emvParams)) {
141
+ $options = array(
142
+ 'value' => $emvParams['emv_id'],
143
+ 'label' => $emvParams['emv_name'],
144
+ );
145
+ }
146
+
147
+ $templateCode = '';
148
+ $error = array();
149
+ try {
150
+ if (null != $emtModel->getEmvAccountId() && null != $emtModel->getMageTemplateId()) {
151
+ if (count($invalidFields) == 0) {
152
+ // if emt is not already tested, verify emt data
153
+ $error = $emtModel->validate();
154
+ $invalidFields = $emtModel->getInvalidFields();
155
+ }
156
+
157
+ // check whether magento template exists
158
+ /* @var $magentoTemplates Mage_Core_Model_Mysql4_Email_Template_Collection */
159
+ $magentoTemplates = Mage::getResourceModel('core/email_template_collection');
160
+ $magentoTemplates->getSelect()->reset(Zend_Db_Select::COLUMNS)
161
+ ->columns(array('template_id', 'template_code')); // only get template_id, and template_code
162
+ $magentoTemplates->addFieldToFilter('template_id ', array('eq' => $emtModel->getMageTemplateId()));
163
+ $template = $magentoTemplates->getFirstItem();
164
+ if (!$template->getId()) {
165
+ $invalidFields['mage_template_id'] = Mage::helper('emvemt')
166
+ ->__('Your selected Magento template does not exist. Please select a new one !');
167
+ } else {
168
+ $templateCode = $template->getTemplateCode();
169
+ }
170
+
171
+ // to enhance the performance, only get campaign commander template if we don't have any invalid fields
172
+ // and the template is in mode emv_create
173
+ if (
174
+ (!$invalidFields || !isset($invalidFields['emv_template_id']))
175
+ && $emtModel->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::EMV_CREATE
176
+ ){
177
+ $template = $emtModel->getEmvTemplate();
178
+ if ($template && isset($template->name)) {
179
+ Mage::register(self::EMV_TEMPLATE_REGISTRY, $template);
180
+ $options = array(
181
+ 'value' => $emtModel->getEmvTemplateId(),
182
+ 'label' => $template->name
183
+ );
184
+ }
185
+ }
186
+
187
+ if (is_array($error)) {
188
+ foreach ($error as $message) {
189
+ $this->_getSession()->addError($message);
190
+ }
191
+ }
192
+ }
193
+ } catch (Exception $e) {
194
+ $this->_getSession()->addError($e->getMessage());
195
+ }
196
+
197
+ Mage::register(self::EMV_TEMPLATE_ARRAY_REGISTRY,$options);
198
+ Mage::register(self::MAGE_TEMPLATE_NAME_REGISTRY, $templateCode);
199
+ Mage::register(self::INVALID_FIELD_EMV_TEMPLATE_REGISTRY, $invalidFields);
200
+
201
+ $this->_initAction();
202
+ $this->_title(($templateCode));
203
+ // add emt edit block form html to return
204
+ $this->_addContent($this->getLayout()->createBlock('emvemt/adminhtml_template_edit'))
205
+ ->_addLeft($this->getLayout()->createBlock('emvemt/adminhtml_template_edit_tabs'))
206
+ ;
207
+ $this->renderLayout();
208
+ }
209
+
210
+ /**
211
+ * Initialise the account model.
212
+ *
213
+ * @return Emv_Emt_Model_Emt
214
+ */
215
+ protected function _initEmt()
216
+ {
217
+ $id = $this->getRequest()->getParam('id', null);
218
+ $emtModel = Mage::getModel('emvemt/emt')->load($id);
219
+ Mage::register(self::CURRENT_EMVEMT_TEMPLATE_REGISTRY, $emtModel);
220
+
221
+ return $emtModel;
222
+ }
223
+
224
+ /**
225
+ * Save action
226
+ */
227
+ public function saveAction()
228
+ {
229
+ $emtId = null;
230
+ if ($data = $this->getRequest()->getPost()) {
231
+ $emtId = $this->getRequest()->getParam('id', null);
232
+ $emtModel = Mage::getModel('emvemt/emt')->load($emtId);
233
+ $emtModel->addData($data);
234
+ if ($emtId != $emtModel->getId()) {
235
+ $emtId = null;
236
+ }
237
+
238
+ // try to validate data
239
+ if (null !== $emtId) {
240
+ // we're in mode edit (2nd form)
241
+ $result = $emtModel->validate();
242
+ $this->_getSession()->setData('edit_emt_form_data',$data);
243
+ } else {
244
+ // set send mode to classic by default
245
+ $emtModel->setEmvSendMailModeId(Emv_Emt_Model_Mailmode::CLASSIC_MODE);
246
+ // we're in 1st form
247
+ $result = $emtModel->validateNewForm();
248
+ }
249
+
250
+ if (is_array($result)) {
251
+ $this->_getSession()->setData('invalid_emt_fields', $emtModel->getInvalidFields());
252
+ foreach ($result as $message) {
253
+ $this->_getSession()->addError($message);
254
+ }
255
+
256
+ $this->_redirect('*/*/edit', array('id' => $emtModel->getId()));
257
+ return;
258
+ }
259
+
260
+ try {
261
+ $emtModel->save();
262
+ $emtId = $emtModel->getId();
263
+
264
+ if (null !== $emtId) {
265
+ $errors = array();
266
+ $treatedAttributes = array();
267
+ $deletedAttributes = array();
268
+
269
+ // validate all given attributes
270
+ if ($emtModel->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::EMV_CREATE) {
271
+ $attributes = $this->getRequest()->getParam('attributes');
272
+ if (is_array($attributes)) {
273
+ $checkAttributeForEmt = $emtModel->validateMappedAttributes(
274
+ $attributes
275
+ );
276
+ if (is_array($checkAttributeForEmt) && count($checkAttributeForEmt)) {
277
+ $errors = array_merge($errors, $checkAttributeForEmt);
278
+ }
279
+
280
+ foreach ($attributes as $attrInfo) {
281
+
282
+ $emvAttributeId = null;
283
+ if (isset($attrInfo['id']) && $attrInfo['id'] > 0) {
284
+ $emvAttributeId = $attrInfo['id'];
285
+ }
286
+
287
+ $attributeModel = Mage::getModel('emvemt/attribute')
288
+ ->setEmvAttribute($attrInfo['emv_attribute'])
289
+ ->setEmvAttributeType($attrInfo['emv_attribute_type'])
290
+ ->setMageAttribute(
291
+ isset($attrInfo['mage_attribute']) ? $attrInfo['mage_attribute'] : ''
292
+ )
293
+ ->setEmvEmtId($emtId)
294
+ ->setId($emvAttributeId)
295
+ ;
296
+
297
+ // treat delete information
298
+ if (isset($attrInfo['delete']) && $attrInfo['delete'] == 1) {
299
+ if ($emvAttributeId) {
300
+ $deletedAttributes[] = $attributeModel;
301
+ }
302
+
303
+ continue;
304
+ }
305
+
306
+ $treatedAttributes[] = $attributeModel;
307
+
308
+ // the errors willl be merged back to the global errors array
309
+ $result = $attributeModel->validate();
310
+ if (is_array($result) && count($result)) {
311
+ $errors = array_merge($errors, $result);
312
+ }
313
+ }
314
+ }
315
+ } else {
316
+ $this->_deleteAllEmtAttribute($emtId);
317
+ }
318
+
319
+ // if some problems occur
320
+ if (is_array($errors) && count($errors) >0) {
321
+ $this->_getSession()->setData('edit_emt_form_data',$data);
322
+ foreach ($errors as $message) {
323
+ $this->_getSession()->addError($message);
324
+ }
325
+ } else {
326
+ // User come from edit mode
327
+ // delete old mapping attribute
328
+ foreach($deletedAttributes as $attribute) {
329
+ $attribute->delete();
330
+ }
331
+ foreach ($treatedAttributes as $attribute) {
332
+ $attribute->save();
333
+ }
334
+
335
+ $this->_getSession()->addSuccess(
336
+ Mage::helper('emvemt')->__('The template was saved.')
337
+ );
338
+ }
339
+ }
340
+ } catch (Exception $e) {
341
+ $this->_getSession()->addError($e->getMessage());
342
+ $this->_getSession()->setEditEmtFormData($data);
343
+ }
344
+ }
345
+
346
+ $this->_redirect('*/*/edit', array('id' => $emtId));
347
+ return;
348
+ }
349
+
350
+ /**
351
+ * Delete all mapping attribute of an emt
352
+ **/
353
+ protected function _deleteAllEmtAttribute($emtId)
354
+ {
355
+ $collection = Mage::getResourceModel('emvemt/attribute_collection')
356
+ ->addEmtFilter($emtId);
357
+ $collection->walk('delete');
358
+ }
359
+
360
+ /**
361
+ * Delete emt action
362
+ */
363
+ public function deleteAction()
364
+ {
365
+ if ($id = $this->getRequest()->getParam('id')) {
366
+ try {
367
+ $this->_deleteAllEmtAttribute($id);
368
+
369
+ $model = Mage::getModel('emvemt/emt')->load($id);
370
+ $model->delete();
371
+ $this->_getSession()->addSuccess(
372
+ Mage::helper('emvemt')->__('The template was deleted.'));
373
+ $this->_redirect('*/*/');
374
+ return;
375
+ }
376
+ catch (Exception $e) {
377
+ $this->_getSession()->addError($e->getMessage());
378
+ $this->_redirect('*/*/edit', array('id' => $this->getRequest()->getPost('id')));
379
+ return;
380
+ }
381
+ }
382
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('emvemt')
383
+ ->__('Not found template!'));
384
+ $this->_redirect('*/*/');
385
+ }
386
+
387
+ /**
388
+ * Mass delete action
389
+ */
390
+ public function massDeleteAction()
391
+ {
392
+ $emtIds = $this->getRequest()->getParam('emt');
393
+ if (!is_array($emtIds)) {
394
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('emvemt')->__('Please select email template(s) !'));
395
+ } else {
396
+ try {
397
+ // delete emt template and its attributes
398
+ $emt = Mage::getModel('emvemt/emt');
399
+ foreach ($emtIds as $id) {
400
+ $emt->setId($id)
401
+ ->delete();
402
+
403
+ $this->_deleteAllEmtAttribute($id);
404
+ }
405
+
406
+ Mage::getSingleton('adminhtml/session')->addSuccess(
407
+ Mage::helper('adminhtml')->__('Total of %d template(s) were deleted.', count($emtIds))
408
+ );
409
+ } catch (Exception $e) {
410
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
411
+ }
412
+ }
413
+
414
+ $this->_redirect('*/*/index');
415
+ }
416
+
417
+ /**
418
+ * Return an array containing emv template from periode $fromDate to $toDate and eventual errors
419
+ */
420
+ public function getEmvTemplateSelectAjaxAction()
421
+ {
422
+ $data = $this->getRequest()->getPost();
423
+ $options = array();
424
+ $error = '';
425
+
426
+ if (isset($data['from']) && isset($data['to']) && isset($data['account_id'])) {
427
+ $data['from'] = Mage::helper('core')->escapeHtml($data['from']);
428
+ $data['to'] = Mage::helper('core')->escapeHtml($data['to']);
429
+ $data['account_id'] = Mage::helper('core')->escapeHtml($data['account_id']);
430
+
431
+ // prepare date format
432
+ $dateFormatIso = Mage::app()->getLocale()->getDateFormat(
433
+ Mage_Core_Model_Locale::FORMAT_TYPE_SHORT
434
+ );
435
+
436
+ // get our locale
437
+ $locale = Mage::app()->getLocale()->getLocale();
438
+
439
+ /* @var $fromDate Zend_Date */
440
+ /* @var $toDate Zend_Date */
441
+ if (!Zend_Date::isDate($data['from'], $dateFormatIso, $locale)) {
442
+ //set a default large periode to match all campaign commander templates
443
+ $fromDate = new Zend_Date('1980-01-01', 'YYYY-MM-dd', $locale);
444
+ } else {
445
+ $fromDate = new Zend_Date($data['from'], $dateFormatIso, $locale);
446
+ }
447
+
448
+ // prepare date to
449
+ if (!Zend_Date::isDate($data['to'], $dateFormatIso, $locale)) {
450
+ $toDate = Zend_Date::now($locale);
451
+ } else {
452
+ $toDate = new Zend_Date($data['to'], $dateFormatIso, $locale);
453
+ }
454
+ // make the period cover all the day because Zend_Date set hour to 00:00:00 by default
455
+ // so we add 23h59m59s
456
+ $toDate->addHour(23);
457
+ $toDate->addMinute(59);
458
+ $toDate->addSecond(59);
459
+
460
+ try {
461
+ /* @var $account Emv_Core_Model_Account */
462
+ $account = Mage::getModel('emvcore/account')->load($data['account_id']);
463
+ $service = Mage::getModel('emvcore/service_transactional');
464
+ $service->setAccount($account);
465
+ // get all lists
466
+ $list = $service->getTemplatesByPeriod(
467
+ $fromDate->toString(self::API_DATE_FORMAT),
468
+ $toDate->toString(self::API_DATE_FORMAT)
469
+ );
470
+
471
+ // prepare options (id and name)
472
+ if (count($list)) {
473
+ $options[] = array('value' => '', 'label' => Mage::helper('emvemt')->__('Please select a template'));
474
+ }
475
+ foreach ($list as $template) {
476
+ $options[] = array(
477
+ 'value' => $template->id,
478
+ 'label' => $template->name
479
+ );
480
+ }
481
+ } catch (Exception $e) {
482
+ $error = $e->getMessage();
483
+ }
484
+ }
485
+
486
+ // if we don't have any template
487
+ if (count($options) == 0 && !$error) {
488
+ $error = Mage::helper('emvemt')->__('There isn\'t any template in this period !');
489
+ }
490
+
491
+ $this->getResponse()->setBody(
492
+ Mage::helper('core')->jsonEncode(
493
+ array(
494
+ 'options' => $options,
495
+ 'error' => $error
496
+ )
497
+ )
498
+ );
499
+ }
500
+
501
+ /**
502
+ * Display a select of magento template not already mapped with the emv account given in post
503
+ */
504
+ public function getNotMappedMagentoTemplateSelectAjaxAction()
505
+ {
506
+ $data = $this->getRequest()->getPost();
507
+
508
+ $options = array();
509
+ $error = '';
510
+
511
+ if (isset($data['account_id']) && $data['account_id']) {
512
+ try {
513
+ /* @var $magentoTemplates Mage_Core_Model_Mysql4_Email_Template_Collection */
514
+ $magentoTemplates = Mage::getModel('emvemt/mageTemplate')
515
+ ->getNotMappedMageTemplateCollection($data['account_id']);
516
+
517
+ // in case that we do not have any available magento template
518
+ if($magentoTemplates->getSize() > 0) {
519
+ $options = $magentoTemplates->toOptionArray();
520
+ }
521
+ } catch(Exception $e) {
522
+ $error = $e->getMessage();
523
+ }
524
+ }
525
+
526
+ if (count($options) == 0 && !$error) {
527
+ $error = Mage::helper('emvemt')->__('There is no Magento email templates which can be used for this account !');
528
+ }
529
+
530
+ $this->getResponse()->setBody(
531
+ Mage::helper('core')->jsonEncode(
532
+ array(
533
+ 'options' => $options,
534
+ 'error' => $error
535
+ )
536
+ )
537
+ );
538
+ }
539
+
540
+ /**
541
+ * Get SmartFocus Attributes action
542
+ * The return will be in JSON format
543
+ */
544
+ public function getEmvAttributesAjaxAction()
545
+ {
546
+ $data = $this->getRequest()->getPost();
547
+
548
+ $html = array();
549
+ $error = '';
550
+ if (
551
+ $data
552
+ && isset($data['emv_template_id'])
553
+ && isset($data['account_id'])
554
+ ) {
555
+ $data['emv_template_id'] = Mage::helper('core')->escapeHtml($data['emv_template_id']);
556
+ $data['account_id'] = Mage::helper('core')->escapeHtml($data['account_id']);
557
+
558
+ $emtModel = $this->_initEmt();
559
+ if ($emtModel->getId() && $emtModel->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::EMV_CREATE){
560
+ // take attributes of this template
561
+ $collection = Mage::getResourceModel('emvemt/attribute_collection')
562
+ ->addEmtFilter($emtModel->getId())
563
+ ->load();
564
+
565
+ Mage::register(self::EMV_ATTRIBUTES_REGISTRY, $collection->getItems());
566
+ }
567
+ }
568
+
569
+ if ($data['emv_template_id']) {
570
+ try {
571
+ /* @var $account Emv_Core_Model_Account */
572
+ $account = Mage::getModel('emvcore/account')->load($data['account_id']);
573
+ $service = Mage::getModel('emvcore/service_transactional');
574
+ $service->setAccount($account);
575
+
576
+ // retreive SmartFocus template
577
+ $emvTemplate = $service->getTemplateById($data['emv_template_id']);
578
+ if ($emvTemplate) {
579
+ $fields = Mage::helper('emvemt/emvtemplate')->getAllDynContentAndAttributes($emvTemplate);
580
+ Mage::register(self::EMV_AVAILABLE_ATTRIBUTE_REGISTRY, $fields);
581
+
582
+ $html = array();
583
+ $emvDynBlock = $this->getLayout()->createBlock('emvemt/adminhtml_template_edit_tab_emvDyn');
584
+ $html[$emvDynBlock->getDivContentId()] = $emvDynBlock->toHtml();
585
+ $emvContentBlock = $this->getLayout()->createBlock('emvemt/adminhtml_template_edit_tab_emvContent');
586
+ $html[$emvContentBlock->getDivContentId()] = $emvContentBlock->toHtml();
587
+ }
588
+
589
+ } catch(Exception $e) {
590
+ $error = $e->getMessage();
591
+ }
592
+ }
593
+
594
+ $this->getResponse()->setBody(
595
+ Mage::helper('core')->jsonEncode(
596
+ array(
597
+ 'html' => $html,
598
+ 'error_messages' => $error
599
+ )
600
+ )
601
+ );
602
+ }
603
+
604
+ /**
605
+ * Retrieve all available Magento variables to insert into email
606
+ * The return will be in JSON format
607
+ */
608
+ public function getVariablesForMageTemplateAction()
609
+ {
610
+ $variables = array();
611
+
612
+ // default variables
613
+ $variables[] = Mage::getModel('core/source_email_variables')
614
+ ->toOptionArray(true);
615
+
616
+ // custom variables
617
+ $customVariables = Mage::getModel('core/variable')
618
+ ->getVariablesOptionArray(true);
619
+ if ($customVariables) {
620
+ $variables[] = $customVariables;
621
+ }
622
+
623
+ // template's variables
624
+ $mageTemplateId = (int)$this->getRequest()->getParam('mage_template_id');
625
+ /* @var $mageTemplate Mage_Core_Model_Email_Template */
626
+ $mageTemplate = Mage::getModel('adminhtml/email_template');
627
+ if ($mageTemplateId) {
628
+ $mageTemplate->load($mageTemplateId);
629
+ if ($mageTemplate->getId() && $templateVariables = $mageTemplate->getVariablesOptionArray(true)) {
630
+ $variables[] = $templateVariables;
631
+ }
632
+ }
633
+
634
+ $this->getResponse()->setBody(
635
+ Mage::helper('core')->jsonEncode(
636
+ array(
637
+ 'variables' => $variables,
638
+ )
639
+ )
640
+ );
641
+ }
642
+
643
+ /**
644
+ * Get preview action
645
+ */
646
+ public function getPreviewAction()
647
+ {
648
+ $data = $this->getRequest()->getPost();
649
+
650
+ $preview = '';
651
+ $vars = array();
652
+
653
+ if ($data && isset($data['emv_send_mail_mode_id'])) {
654
+ try {
655
+ switch ($data['emv_send_mail_mode_id']) {
656
+ case Emv_Emt_Model_Mailmode::EMV_CREATE :
657
+ if (
658
+ isset($data['emv_template_id'])
659
+ && $data['emv_template_id']
660
+ && isset($data['emv_account_id'])
661
+ && $data['emv_account_id']
662
+ ) {
663
+ $preparedAttributes = array(
664
+ Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_DYN => array(),
665
+ Emv_Emt_Model_Attribute::ATTRIBUTE_TYPE_EMV_CONTENT => array()
666
+ );
667
+
668
+ $attributes = $this->getRequest()->getParam('attributes');
669
+ if ($attributes) {
670
+ foreach ($attributes as $attrInfo) {
671
+ if (
672
+ (isset($attrInfo['emv_attribute_type']) && $attrInfo['emv_attribute_type'])
673
+ && (isset($attrInfo['emv_attribute']) && $attrInfo['emv_attribute'])
674
+ && (isset($attrInfo['mage_attribute']) && $attrInfo['mage_attribute'])
675
+ ) {
676
+ if (isset($attrInfo['delete']) && $attrInfo['delete']) {
677
+ continue;
678
+ }
679
+
680
+ $preparedAttributes[$attrInfo['emv_attribute_type']][$attrInfo['emv_attribute']]
681
+ = $attrInfo['mage_attribute'];
682
+ }
683
+ }
684
+ }
685
+
686
+ /* @var $account Emv_Core_Model_Account */
687
+ $account = Mage::getModel('emvcore/account')->load($data['emv_account_id']);
688
+ $service = Mage::getModel('emvcore/service_transactional');
689
+ $service->setAccount($account);
690
+ $preview = $service->getPreviewTemplate($data['emv_template_id'], $preparedAttributes);
691
+ }
692
+ break;
693
+
694
+ default:
695
+ if (isset($data['mage_template_id']) && $data['mage_template_id']) {
696
+ /** @var $template Mage_Core_Model_Email_Template */
697
+ $template = Mage::getModel('core/email_template');
698
+ $template->load($data['mage_template_id']);
699
+
700
+ $preview = $template->getProcessedTemplate($vars, true);
701
+
702
+ if ($template->isPlain()) {
703
+ $preview = "<pre>" . htmlspecialchars($preview) . "</pre>";
704
+ }
705
+ }
706
+ break;
707
+ }
708
+ } catch (Exception $e) {
709
+ $preview = Mage::helper('emvemt')->__($e->getMessage());
710
+ }
711
+ }
712
+
713
+ echo $preview;
714
+ }
715
+
716
+ }
app/code/community/Emv/Emt/etc/adminhtml.xml CHANGED
@@ -1,31 +1,66 @@
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <config>
3
  <menu>
4
- <system>
 
5
  <children>
6
  <emvemt translate="title" module="emvemt">
7
- <title>Campaign Commander EMT</title>
8
- <sort_order>1000</sort_order>
9
- <action>emailvisionemt/emt</action>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
  </emvemt>
11
  </children>
12
- </system>
13
  </menu>
 
14
  <acl>
15
  <resources>
16
  <admin>
17
  <children>
18
- <system>
 
19
  <children>
20
  <emvemt translate="title" module="emvemt">
21
- <title>Campaign Commander EMT</title>
22
- <sort_order>1000</sort_order>
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  </emvemt>
 
 
 
 
24
  <config>
25
  <children>
26
- <emvemt translate="title" module="emvemt">
27
- <title>Campaign Commander EMT</title>
28
- <sort_order>1000</sort_order>
29
  </emvemt>
30
  </children>
31
  </config>
1
  <?xml version="1.0" encoding="UTF-8"?>
2
  <config>
3
  <menu>
4
+ <!-- EmailVision menu in the back office -->
5
+ <emailvision translate="title" module="adminhtml">
6
  <children>
7
  <emvemt translate="title" module="emvemt">
8
+ <title>Transactional Messages (NMP)</title>
9
+ <sort_order>50</sort_order>
10
+ <children>
11
+ <emt translate="title" module="emvemt">
12
+ <title>Email Templates</title>
13
+ <sort_order>10</sort_order>
14
+ <action>emv_emt/template</action>
15
+ </emt>
16
+ <log translate="title" module="emvemt">
17
+ <title>Email Sending Logs</title>
18
+ <sort_order>50</sort_order>
19
+ <action>emv_emt/log</action>
20
+ </log>
21
+ <reschedule translate="title" module="emvemt">
22
+ <title>Re-scheduled Email List</title>
23
+ <sort_order>100</sort_order>
24
+ <action>emv_emt/reschedule</action>
25
+ </reschedule>
26
+ </children>
27
  </emvemt>
28
  </children>
29
+ </emailvision>
30
  </menu>
31
+
32
  <acl>
33
  <resources>
34
  <admin>
35
  <children>
36
+ <!-- EmailVision acl -->
37
+ <emailvision>
38
  <children>
39
  <emvemt translate="title" module="emvemt">
40
+ <title>Transactional Messages (NMP)</title>
41
+ <children>
42
+ <emt>
43
+ <title>Email Templates</title>
44
+ <sort_order>10</sort_order>
45
+ </emt>
46
+ <log>
47
+ <title>Email Sending Logs</title>
48
+ <sort_order>50</sort_order>
49
+ </log>
50
+ <reschedule>
51
+ <title>Re-scheduled Email List</title>
52
+ <sort_order>100</sort_order>
53
+ </reschedule>
54
+ </children>
55
  </emvemt>
56
+ </children>
57
+ </emailvision>
58
+ <system>
59
+ <children>
60
  <config>
61
  <children>
62
+ <emvemt>
63
+ <title>SmartFocus - Transactional Service Setting</title>
 
64
  </emvemt>
65
  </children>
66
  </config>
app/code/community/Emv/Emt/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <Emv_Emt>
5
- <version>0.2.0</version>
6
  </Emv_Emt>
7
  </modules>
8
  <global>
@@ -32,6 +32,12 @@
32
  <emt>
33
  <table>emv_emt</table>
34
  </emt>
 
 
 
 
 
 
35
  <attribute>
36
  <table>emv_emt_attribute_mapping</table>
37
  </attribute>
@@ -67,9 +73,32 @@
67
  <use>admin</use>
68
  <args>
69
  <module>Emv_Emt_Adminhtml</module>
70
- <frontName>emailvisionemt</frontName>
71
  </args>
72
  </emvemt>
73
  </routers>
74
  </admin>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
  </config>
2
  <config>
3
  <modules>
4
  <Emv_Emt>
5
+ <version>0.4.1</version>
6
  </Emv_Emt>
7
  </modules>
8
  <global>
32
  <emt>
33
  <table>emv_emt</table>
34
  </emt>
35
+ <resending_queue_message>
36
+ <table>emv_queue_message</table>
37
+ </resending_queue_message>
38
+ <log>
39
+ <table>emv_sending_log</table>
40
+ </log>
41
  <attribute>
42
  <table>emv_emt_attribute_mapping</table>
43
  </attribute>
73
  <use>admin</use>
74
  <args>
75
  <module>Emv_Emt_Adminhtml</module>
76
+ <frontName>emv_emt</frontName>
77
  </args>
78
  </emvemt>
79
  </routers>
80
  </admin>
81
+ <crontab>
82
+ <jobs>
83
+ <emailvision_process_error_sending_emails>
84
+ <schedule>
85
+ <cron_expr>*/5 * * * *</cron_expr>
86
+ </schedule>
87
+ <run>
88
+ <model>emvemt/cron::processErrorSendingEmails</model>
89
+ </run>
90
+ </emailvision_process_error_sending_emails>
91
+ </jobs>
92
+ </crontab>
93
+ <default>
94
+ <emvemt>
95
+ <resending_mechanism>
96
+ <enabled>0</enabled>
97
+ <first_delay>5</first_delay>
98
+ <second_delay>60</second_delay>
99
+ <third_delay>120</third_delay>
100
+ <fourth_delay>240</fourth_delay>
101
+ </resending_mechanism>
102
+ </emvemt>
103
+ </default>
104
  </config>
app/code/community/Emv/Emt/etc/system.xml ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <sections>
4
+ <emvemt translate="label" module="emvemt">
5
+ <label>Transactional Messages (NMP)</label>
6
+ <tab>emailvision</tab>
7
+ <sort_order>10</sort_order>
8
+ <show_in_default>1</show_in_default>
9
+ <show_in_website>1</show_in_website>
10
+ <show_in_store>1</show_in_store>
11
+ <groups>
12
+ <transactional_service translate="label" module="emvemt">
13
+ <label>General</label>
14
+ <expanded>1</expanded>
15
+ <frontend_type>text</frontend_type>
16
+ <sort_order>0</sort_order>
17
+ <show_in_default>1</show_in_default>
18
+ <show_in_website>1</show_in_website>
19
+ <show_in_store>1</show_in_store>
20
+ <fields>
21
+ <account translate="label">
22
+ <label>SmartFocus Account</label>
23
+ <frontend_type>select</frontend_type>
24
+ <source_model>emvcore/system_config_source_account</source_model>
25
+ <backend_model>emvemt/adminhtml_system_config_backend_account</backend_model>
26
+ <sort_order>0</sort_order>
27
+ <show_in_default>1</show_in_default>
28
+ <show_in_website>1</show_in_website>
29
+ <show_in_store>1</show_in_store>
30
+ </account>
31
+ <log_enabled translate="label" module="emvemt">
32
+ <label>Activate Sending Log</label>
33
+ <frontend_type>select</frontend_type>
34
+ <source_model>adminhtml/system_config_source_yesno</source_model>
35
+ <comment>By default, only error emails will be logged</comment>
36
+ <sort_order>30</sort_order>
37
+ <show_in_default>1</show_in_default>
38
+ <show_in_website>1</show_in_website>
39
+ <show_in_store>1</show_in_store>
40
+ </log_enabled>
41
+ <parameter_log_enabled translate="label" module="emvemt">
42
+ <label>Activate Sending Parameters Log</label>
43
+ <frontend_type>select</frontend_type>
44
+ <source_model>adminhtml/system_config_source_yesno</source_model>
45
+ <comment>All SmartFocus sending parameters will be logged</comment>
46
+ <sort_order>40</sort_order>
47
+ <show_in_default>1</show_in_default>
48
+ <show_in_website>1</show_in_website>
49
+ <show_in_store>1</show_in_store>
50
+ </parameter_log_enabled>
51
+ </fields>
52
+ </transactional_service>
53
+ <resending_mechanism translate="label" module="emvemt">
54
+ <label>Resending Mechanism Configuration</label>
55
+ <expanded>1</expanded>
56
+ <sort_order>20</sort_order>
57
+ <show_in_default>1</show_in_default>
58
+ <fields>
59
+ <enabled translate="label" module="emvemt">
60
+ <label>Activate Resending Mechanism</label>
61
+ <frontend_type>select</frontend_type>
62
+ <source_model>adminhtml/system_config_source_yesno</source_model>
63
+ <sort_order>10</sort_order>
64
+ <show_in_default>1</show_in_default>
65
+ </enabled>
66
+ <first_delay translate="label" module="emvemt">
67
+ <label>First Delay (in minutes)</label>
68
+ <frontend_type>text</frontend_type>
69
+ <sort_order>20</sort_order>
70
+ <show_in_default>1</show_in_default>
71
+ </first_delay>
72
+ <second_delay translate="label" module="emvemt">
73
+ <label>Second Delay (in minutes)</label>
74
+ <frontend_type>text</frontend_type>
75
+ <sort_order>30</sort_order>
76
+ <show_in_default>1</show_in_default>
77
+ </second_delay>
78
+ <third_delay translate="label" module="emvemt">
79
+ <label>Third Delay (in minutes)</label>
80
+ <frontend_type>text</frontend_type>
81
+ <sort_order>40</sort_order>
82
+ <show_in_default>1</show_in_default>
83
+ </third_delay>
84
+ <fourth_delay translate="label" module="emvemt">
85
+ <label>Fourth Delay (in minutes)</label>
86
+ <frontend_type>text</frontend_type>
87
+ <sort_order>50</sort_order>
88
+ <show_in_default>1</show_in_default>
89
+ </fourth_delay>
90
+ </fields>
91
+ </resending_mechanism>
92
+ </groups>
93
+ </emvemt>
94
+ </sections>
95
+ </config>
96
+
app/code/community/Emv/Emt/sql/emvemt_setup/mysql4-upgrade-0.1.0-0.2.0.php CHANGED
@@ -9,8 +9,11 @@ ALTER TABLE {$installer->getTable('emvemt/attribute')}
9
  ADD COLUMN `emv_attribute_type` VARCHAR(200) NOT NULL AFTER emv_emt_id
10
  ");
11
 
 
 
12
  $installer->run("
13
  UPDATE {$installer->getTable('emvemt/attribute')} SET `emv_attribute_type` = '".Emv_Emt_Constants::ATTRIBUTE_TYPE_EMV_DYN."'
14
  ");
 
15
 
16
  $installer->endSetup();
9
  ADD COLUMN `emv_attribute_type` VARCHAR(200) NOT NULL AFTER emv_emt_id
10
  ");
11
 
12
+ // This part is intentionally commented - Emv_Emt_Constants class has been removed in later version
13
+ /*
14
  $installer->run("
15
  UPDATE {$installer->getTable('emvemt/attribute')} SET `emv_attribute_type` = '".Emv_Emt_Constants::ATTRIBUTE_TYPE_EMV_DYN."'
16
  ");
17
+ */
18
 
19
  $installer->endSetup();
app/code/community/Emv/Emt/sql/emvemt_setup/mysql4-upgrade-0.2.0-0.3.0.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $installer Emv_Emt_Model_Resource_Setup */
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ $installer->run("
8
+ ALTER TABLE {$installer->getTable('emvemt/attribute')}
9
+ MODIFY COLUMN `mage_attribute` TEXT
10
+ ");
11
+
12
+ $installer->endSetup();
app/code/community/Emv/Emt/sql/emvemt_setup/mysql4-upgrade-0.3.0-0.4.0.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $installer Emv_Emt_Model_Resource_Setup */
3
+ $installer = $this;
4
+
5
+ $installer->startSetup();
6
+
7
+ $installer->run("
8
+ ALTER TABLE {$installer->getTable('emvemt/emt')}
9
+ ADD COLUMN `created_at` TIMESTAMP NULL,
10
+ ADD COLUMN `updated_at` TIMESTAMP NULL,
11
+ ADD COLUMN `emv_parameters` TEXT NULL,
12
+ MODIFY COLUMN mage_template_id VARCHAR(255) NOT NULL,
13
+
14
+ ADD INDEX `IDX_EMV_EMT_EMV_TEMPLATE_ID` (`emv_template_id`),
15
+ ADD INDEX `IDX_EMV_EMT_ACCOUNT_ID` (`emv_account_id`),
16
+ ADD INDEX `IDX_EMV_MAGE_TEMPLATE_ID` (`mage_template_id`),
17
+ ADD INDEX `IDX_EMV_MAGE_SEND_MAIL_MODE_ID` (`emv_send_mail_mode_id`)
18
+ ");
19
+
20
+ $gmtDate = Mage::getModel('core/date')->gmtDate();
21
+ $this->run("
22
+ UPDATE {$this->getTable('emvemt/emt')} SET created_at = '{$gmtDate}', updated_at = '{$gmtDate}';
23
+ ");
24
+
25
+ $installer->endSetup();
app/code/community/Emv/Emt/sql/emvemt_setup/mysql4-upgrade-0.4.0-0.4.1.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Emv_Emt_Model_Resource_Setup */
3
+ $this->startSetup();
4
+
5
+ // create a new log table
6
+ $this->run("
7
+ DROP TABLE IF EXISTS {$this->getTable('emvemt/log')};
8
+ CREATE TABLE IF NOT EXISTS {$this->getTable('emvemt/log')}
9
+ (
10
+ `id` INT(10) AUTO_INCREMENT NOT NULL,
11
+ `sending_mode` VARCHAR(10) NOT NULL,
12
+ `email` VARCHAR(255) NOT NULL,
13
+ `sending_type` VARCHAR(10) NOT NULL,
14
+ `store_id` SMALLINT(5) NULL,
15
+ `account_id` SMALLINT(5) NULL,
16
+ `magento_template_name` VARCHAR(255) NOT NULL,
17
+ `original_magento_template_name` VARCHAR(255) NOT NULL,
18
+
19
+ `rescheduled` TINYINT(1) NOT NULL,
20
+
21
+ `sent_sucess` TINYINT(1) NOT NULL,
22
+ `created_at` TIMESTAMP NULL,
23
+
24
+ `error` TEXT NULL,
25
+ `error_code` INT(10) NULL,
26
+
27
+ `emv_name` VARCHAR(255) NULL,
28
+ `emv_params` TEXT NULL,
29
+ `emv_content_variables` TEXT NULL,
30
+ `emv_dyn_variables` TEXT NULL,
31
+
32
+ INDEX `IDX_LOG_SENDING_MODE` (`sending_mode`),
33
+ INDEX `IDX_LOG_EMAIL` (`email`),
34
+ INDEX `IDX_LOG_MAGENTO_TEMPLATE_NAME` (`magento_template_name`),
35
+ INDEX `IDX_LOG_ORIGINAL_MAGENTO_TEMPLATE_NAME` (`original_magento_template_name`),
36
+ INDEX `IDX_LOG_ORIGINAL_EMV_NAME` (`emv_name`),
37
+
38
+ PRIMARY KEY (`id`)
39
+ )ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Log Sending';
40
+ ");
41
+
42
+ // queue message
43
+ $this->run("
44
+ DROP TABLE IF EXISTS {$this->getTable('emvemt/resending_queue_message')};
45
+ CREATE TABLE IF NOT EXISTS {$this->getTable('emvemt/resending_queue_message')}
46
+ (
47
+ `id` INT(10) AUTO_INCREMENT NOT NULL,
48
+ `sending_mode` VARCHAR(10) NOT NULL,
49
+ `email` VARCHAR(255) NOT NULL,
50
+ `store_id` SMALLINT(5) NULL,
51
+ `account_id` SMALLINT(5) NULL,
52
+ `log_id` SMALLINT(5) NULL,
53
+
54
+ `magento_template_name` VARCHAR(255) NULL,
55
+ `original_magento_template_name` VARCHAR(255) NULL,
56
+
57
+ `created_at` TIMESTAMP NULL,
58
+
59
+ `emv_name` VARCHAR(255) NOT NULL,
60
+ `emv_params` TEXT NOT NULL,
61
+ `emv_content_variables` TEXT NULL,
62
+ `emv_dyn_variables` TEXT NULL,
63
+
64
+ `sent_sucess` TINYINT(1) NULL,
65
+ `number_attempts` INT(4) NULL,
66
+ `first_attempt` TIMESTAMP NULL,
67
+ `last_attempt` TIMESTAMP NULL,
68
+
69
+ INDEX `IDX_LOG_SENDING_MODE` (`sending_mode`),
70
+ INDEX `IDX_LOG_EMAIL` (`email`),
71
+ INDEX `IDX_LOG_MAGENTO_TEMPLATE_NAME` (`magento_template_name`),
72
+ INDEX `IDX_LOG_ORIGINAL_MAGENTO_TEMPLATE_NAME` (`original_magento_template_name`),
73
+ INDEX `IDX_LOG_ORIGINAL_EMV_NAME` (`emv_name`),
74
+
75
+ PRIMARY KEY (`id`)
76
+ )ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Queue Message for sending';
77
+ ");
78
+
79
+ $this->endSetup();
app/code/community/Emv/Report/Block/Adminhtml/Conversion.php ADDED
@@ -0,0 +1,525 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Conversion block
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Report
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Report_Block_Adminhtml_Conversion extends Mage_Adminhtml_Block_Widget_Grid_Container
11
+ {
12
+ public function __construct()
13
+ {
14
+ $this->_controller = 'report_sales_sales';
15
+ $this->_headerText = Mage::helper('abandonment_report')->__('Total Abandoned Cart Report');
16
+
17
+ parent::__construct();
18
+
19
+ $this->setTemplate('report/grid/container.phtml');
20
+
21
+ $this->_removeButton('add');
22
+
23
+ $this->addButton('filter_form_submit', array(
24
+ 'label' => Mage::helper('reports')->__('Show Report'),
25
+ 'onclick' => 'filterFormSubmit()'
26
+ ));
27
+
28
+ $this->addButton('export_csv', array('onclick' => 'filterExportSubmit()',
29
+ 'label' => Mage::helper('abandonment')->__('Export CSV')));
30
+ }
31
+
32
+ /**
33
+ * @return string
34
+ */
35
+ public function getFilterUrl()
36
+ {
37
+ $this->getRequest()->setParam('filter', null);
38
+ return $this->getUrl('*/*/index', array('_current' => true));
39
+ }
40
+
41
+ /**
42
+ * @return string
43
+ */
44
+ public function getExportUrl()
45
+ {
46
+ $this->getRequest()->setParam('filter', null);
47
+ return $this->getUrl('*/*/exportCsv', array('_current' => true));
48
+ }
49
+
50
+ /**
51
+ * The number of sent emails for the first reminder
52
+ *
53
+ * @return float
54
+ */
55
+ public function getNbFirstReminderSent()
56
+ {
57
+ return Mage::getModel('abandonment/stats')->getResource()
58
+ ->getTotalFirstReminderSent($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
59
+ }
60
+
61
+ /**
62
+ * The number of sent emails for the second reminder
63
+ *
64
+ * @return float
65
+ */
66
+ public function getNbSecondReminderSent()
67
+ {
68
+ return Mage::getModel('abandonment/stats')->getResource()
69
+ ->getTotalSecondReminderSent($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
70
+ }
71
+
72
+ /**
73
+ * The number of sent emails for the third reminder
74
+ *
75
+ * @return float
76
+ */
77
+ public function getNbThirdReminderSent()
78
+ {
79
+ return Mage::getModel('abandonment/stats')->getResource()
80
+ ->getTotalThirdReminderSent($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
81
+ }
82
+
83
+ /**
84
+ * The number of converted abandoned carts for the first reminder
85
+ *
86
+ * @return float
87
+ */
88
+ public function getNbFirstReminderConverted()
89
+ {
90
+ return Mage::getModel('abandonment/orderflag')->getResource()
91
+ ->getNbFirstReminderConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
92
+ }
93
+
94
+ /**
95
+ * The number of converted abandoned carts for the second reminder
96
+ *
97
+ * @return float
98
+ */
99
+ public function getNbSecondReminderConverted()
100
+ {
101
+ return Mage::getModel('abandonment/orderflag')->getResource()
102
+ ->getNbSecondReminderConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
103
+ }
104
+
105
+ /**
106
+ * The number of converted abandoned carts for the third reminder
107
+ *
108
+ * @return float
109
+ */
110
+ public function getNbThirdReminderConverted()
111
+ {
112
+ return Mage::getModel('abandonment/orderflag')->getResource()
113
+ ->getNbThirdReminderConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
114
+ }
115
+
116
+ /**
117
+ * The percentage of converted abandoned carts for the first reminder
118
+ *
119
+ * @return float
120
+ */
121
+ public function getPercentageFirstConversion()
122
+ {
123
+ $percent = 0;
124
+ $nbSent = $this->getNbFirstReminderSent();
125
+ if ($nbSent) {
126
+ $nbConverted = $this->getNbFirstReminderConverted();
127
+ $percent = $nbConverted / $nbSent * 100;
128
+ }
129
+
130
+ return $percent;
131
+ }
132
+
133
+ /**
134
+ * The percentage of converted abandoned carts for the second reminder
135
+ *
136
+ * @return float
137
+ */
138
+ public function getPercentageSecondConversion()
139
+ {
140
+ $percent = 0;
141
+ $nbSent = $this->getNbSecondReminderSent();
142
+ if ($nbSent) {
143
+ $nbConverted = $this->getNbSecondReminderConverted();
144
+ $percent = $nbConverted / $nbSent * 100;
145
+ }
146
+
147
+ return $percent;
148
+ }
149
+
150
+ /**
151
+ * The percentage of converted abandoned carts for the third reminder
152
+ *
153
+ * @return float
154
+ */
155
+ public function getPercentageThirdConversion()
156
+ {
157
+ $percent = 0;
158
+ $nbSent = $this->getNbThirdReminderSent();
159
+ if ($nbSent) {
160
+ $nbConverted = $this->getNbThirdReminderConverted();
161
+ $percent = $nbConverted / $nbSent * 100;
162
+ }
163
+
164
+ return $percent;
165
+ }
166
+
167
+ /**
168
+ * Get total amount of all converted abandoned carts for the first reminder
169
+ *
170
+ * @param string $includeContainer
171
+ * @return float
172
+ */
173
+ public function getRevenueFirstConversion()
174
+ {
175
+ $sumAmount = Mage::getModel('abandonment/orderflag')->getResource()
176
+ ->getSumAmountFirstReminderConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
177
+
178
+ return $sumAmount;
179
+ }
180
+
181
+ /**
182
+ * Get total amount of all converted abandoned carts for the second reminder
183
+ *
184
+ * @param string $includeContainer
185
+ * @return float
186
+ */
187
+ public function getRevenueSecondConversion()
188
+ {
189
+ $sumAmount = Mage::getModel('abandonment/orderflag')->getResource()
190
+ ->getSumAmountSecondReminderConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
191
+
192
+ return $sumAmount;
193
+ }
194
+
195
+ /**
196
+ * Get total amount of all converted abandoned carts for the third reminder
197
+ *
198
+ * @param string $includeContainer
199
+ * @return float
200
+ */
201
+ public function getRevenueThirdConversion()
202
+ {
203
+ $sumAmount = Mage::getModel('abandonment/orderflag')->getResource()
204
+ ->getSumAmountThirdReminderConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
205
+
206
+ return $sumAmount;
207
+ }
208
+
209
+ /**
210
+ * Get average revenue of all converted abandoned carts for the first reminder
211
+ *
212
+ * @param string $includeContainer
213
+ * @return float
214
+ */
215
+ public function getAverageRevenueFirstConversion()
216
+ {
217
+ $average = 0;
218
+ $resource = Mage::getModel('abandonment/orderflag')->getResource();
219
+
220
+ $nbConvertedCarts= $resource->getNbFirstReminderConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
221
+ if ($nbConvertedCarts) {
222
+ $total = $resource->getSumAmountFirstReminderConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
223
+ $average = $total / $nbConvertedCarts;
224
+ }
225
+
226
+ return $average;
227
+ }
228
+
229
+ /**
230
+ * Get average revenue of all converted abandoned carts for the second reminder
231
+ *
232
+ * @param string $includeContainer
233
+ * @return float
234
+ */
235
+ public function getAverageRevenueSecondConversion()
236
+ {
237
+ $average = 0;
238
+ $resource = Mage::getModel('abandonment/orderflag')->getResource();
239
+
240
+ $nbConvertedCarts= $resource->getNbSecondReminderConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
241
+ if ($nbConvertedCarts) {
242
+ $total = $resource->getSumAmountSecondReminderConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
243
+ $average = $total / $nbConvertedCarts;
244
+ }
245
+
246
+ return $average;
247
+ }
248
+
249
+ /**
250
+ * Get average revenue of all converted abandoned carts for the third reminder
251
+ *
252
+ * @param string $includeContainer
253
+ * @return float
254
+ */
255
+ public function getAverageRevenueThirdConversion()
256
+ {
257
+ $average = 0;
258
+ $resource = Mage::getModel('abandonment/orderflag')->getResource();
259
+
260
+ $nbConvertedCarts= $resource->getNbThirdReminderConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
261
+ if ($nbConvertedCarts) {
262
+ $total = $resource->getSumAmountThirdReminderConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
263
+ $average = $total / $nbConvertedCarts;
264
+ }
265
+
266
+ return $average;
267
+ }
268
+
269
+ /**
270
+ * Get total revenue of all converted abandoned carts during a given period
271
+ *
272
+ * @param string $includeContainer
273
+ * @return string
274
+ */
275
+ public function getSumAmountConvertedCarts()
276
+ {
277
+ $sumAmount = Mage::getModel('abandonment/orderflag')->getResource()
278
+ ->getSumAmountConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
279
+ return $sumAmount;
280
+ }
281
+
282
+ /**
283
+ * Get total revenue of conversion for all converted abandoned carts
284
+ *
285
+ * @param string $includeContainer
286
+ * @return string
287
+ */
288
+ public function getTotalSumAmountConvertedCarts()
289
+ {
290
+ $sumAmount = Mage::getModel('abandonment/orderflag')->getResource()->getSumAmountConvertedCarts();
291
+ return $sumAmount;
292
+ }
293
+
294
+ /**
295
+ * Get the total number of converted abandoned carts during a specific period
296
+ *
297
+ * @return int
298
+ */
299
+ public function getSumNbConvertedCarts()
300
+ {
301
+ $nbFlaged = Mage::getModel('abandonment/orderflag')->getResource()
302
+ ->getSumNbConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
303
+ return $nbFlaged;
304
+ }
305
+
306
+ /**
307
+ * Get the total number of converted abandoned carts
308
+ * @return int
309
+ */
310
+ public function getTotalSumNbConvertedCarts()
311
+ {
312
+ $nbFlaged = Mage::getModel('abandonment/orderflag')->getResource()
313
+ ->getSumNbConvertedCarts();
314
+ return $nbFlaged;
315
+ }
316
+
317
+ /**
318
+ * Get the total number of sent emails during a specific period
319
+ *
320
+ * @return int
321
+ */
322
+ public function getSumNbReminderSent()
323
+ {
324
+ $nbSent = Mage::getModel('abandonment/stats')->getResource()
325
+ ->getSumReminderSent($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
326
+ return $nbSent;
327
+ }
328
+
329
+ /**
330
+ * Get the total number of sent emails
331
+ *
332
+ * @return int
333
+ */
334
+ public function getTotalSumNbReminderSent()
335
+ {
336
+ $nbSent = Mage::getModel('abandonment/stats')->getResource()
337
+ ->getSumReminderSent();
338
+ return $nbSent;
339
+ }
340
+
341
+ /**
342
+ * Get total pourcentage conversion during a specific period
343
+ *
344
+ * @return float
345
+ */
346
+ public function getPercentageConversion()
347
+ {
348
+ $percent = 0;
349
+
350
+ $numberSent = $this->getSumNbReminderSent();
351
+ if ($numberSent > 0) {
352
+ $nbConvertedCarts = $this->getSumNbConvertedCarts();
353
+ $percent = $nbConvertedCarts / $numberSent * 100;
354
+ }
355
+
356
+ return $percent;
357
+ }
358
+
359
+ /**
360
+ * Get total pourcentage conversion
361
+ *
362
+ * @return float
363
+ */
364
+ public function getTotalPercentageConversion()
365
+ {
366
+ $percent = 0;
367
+
368
+ $numberSent = $this->getTotalSumNbReminderSent();
369
+ if ($numberSent > 0) {
370
+ $nbConvertedCarts = $this->getTotalSumNbConvertedCarts();
371
+ $percent = $nbConvertedCarts / $numberSent * 100;
372
+ }
373
+
374
+ return $percent;
375
+ }
376
+
377
+ /**
378
+ * Get average revenue conversion for a given period
379
+ *
380
+ * @param string $includeContainer
381
+ * @return float
382
+ */
383
+ public function getAverageRevenueConversion()
384
+ {
385
+ $resource = Mage::getModel('abandonment/orderflag')->getResource();
386
+ $average = 0;
387
+
388
+ $nbConvertedCarts = $resource->getSumNbConvertedCarts($this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod());
389
+ if ($nbConvertedCarts > 0) {
390
+ $sumAmout = $resource->getSumAmountConvertedCarts(
391
+ $this->_getFilterStartingPeriod(), $this->_getFilterEndingPeriod()
392
+ );
393
+ $average = $sumAmout / $nbConvertedCarts;
394
+ }
395
+
396
+ return $average;
397
+ }
398
+
399
+ /**
400
+ * Get total average revenue conversion
401
+ *
402
+ * @param string $includeContainer
403
+ * @return float
404
+ */
405
+ public function getTotalAverageRevenueConversion()
406
+ {
407
+ $resource = Mage::getModel('abandonment/orderflag')->getResource();
408
+ $average = 0;
409
+
410
+ $nbConvertedCarts= $resource->getSumNbConvertedCarts();
411
+ if ($nbConvertedCarts) {
412
+ $average = $resource->getSumAmountConvertedCarts() / $nbConvertedCarts;
413
+ }
414
+
415
+ return $average;
416
+ }
417
+
418
+ /**
419
+ * @param string $alertId
420
+ * @return string
421
+ */
422
+ protected function _getDetailsAlertUrl($alertId)
423
+ {
424
+ $params = array('alertid' => $alertId);
425
+ if($this->_getFilterStartingPeriod() !== null) {
426
+ $params['from'] = $this->_getFilterStartingPeriod();
427
+ }
428
+ if($this->_getFilterEndingPeriod() !== null) {
429
+ $params['to'] = $this->_getFilterEndingPeriod();
430
+ }
431
+
432
+ return $this->getUrl('*/details/index', $params);
433
+ }
434
+
435
+ /**
436
+ * @return string - Varien_Date::DATETIME_INTERNAL_FORMAT
437
+ */
438
+ protected function _getFilterStartingPeriod()
439
+ {
440
+ $from = null;
441
+ if ($this->getFilterData()->getFrom()) {
442
+ $from = $this->getFilterData()->getFrom();
443
+ }
444
+ return $from;
445
+ }
446
+
447
+ /**
448
+ * @return string - Varien_Date::DATETIME_INTERNAL_FORMAT
449
+ */
450
+ protected function _getFilterEndingPeriod()
451
+ {
452
+ $to = null;
453
+ if ($this->getFilterData()->getTo()) {
454
+ $to = $this->getFilterData()->getTo() . ' 23:59:59';
455
+ }
456
+ return $to;
457
+ }
458
+
459
+ /**
460
+ * @return string
461
+ */
462
+ public function getDetailsFirstAlertUrl()
463
+ {
464
+ return $this->_getDetailsAlertUrl(Emv_CartAlert_Constants::FIRST_ALERT_REMINDER_ID);
465
+ }
466
+
467
+ /**
468
+ * @return string
469
+ */
470
+ public function getDetailsSecondAlertUrl()
471
+ {
472
+ return $this->_getDetailsAlertUrl(Emv_CartAlert_Constants::SECOND_ALERT_REMINDER_ID);
473
+ }
474
+
475
+ /**
476
+ * @return string
477
+ */
478
+ public function getDetailsThirdAlertUrl()
479
+ {
480
+ return $this->_getDetailsAlertUrl(Emv_CartAlert_Constants::THIRD_ALERT_REMINDER_ID);
481
+ }
482
+
483
+ /**
484
+ * @param string $templateIdStoreConfigPath
485
+ * @return string
486
+ */
487
+ protected function _getAlertTemplateSubject($templateIdStoreConfigPath)
488
+ {
489
+ $templateId = Mage::getStoreConfig($templateIdStoreConfigPath);
490
+ /* @var $template Emv_Emt_Model_Mage_Core_Email_Template */
491
+ $template = Mage::getModel('core/email_template');
492
+ if (is_numeric($templateId)) {
493
+ $template->load($templateId);
494
+ } else {
495
+ $localeCode = Mage::getStoreConfig('general/locale/code');
496
+ $template->loadDefault($templateId, $localeCode);
497
+ }
498
+
499
+ return $template->getTemplateSubject();
500
+ }
501
+
502
+ /**
503
+ * @return string
504
+ */
505
+ public function getFirstAlertTemplateSubject()
506
+ {
507
+ return $this->_getAlertTemplateSubject(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_TEMPLATE);
508
+ }
509
+
510
+ /**
511
+ * @return string
512
+ */
513
+ public function getSecondAlertTemplateSubject()
514
+ {
515
+ return $this->_getAlertTemplateSubject(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_TEMPLATE);
516
+ }
517
+
518
+ /**
519
+ * @return string
520
+ */
521
+ public function getThirdAlertTemplateSubject()
522
+ {
523
+ return $this->_getAlertTemplateSubject(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_TEMPLATE);
524
+ }
525
+ }
app/code/community/Emv/Report/Block/Adminhtml/Conversion/Form.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Conversion Form Block
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Report
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Report_Block_Adminhtml_Conversion_Form extends Mage_Adminhtml_Block_Widget_Form
11
+ {
12
+ protected function _prepareForm()
13
+ {
14
+ $actionUrl = $this->getUrl('*/*/sales');
15
+
16
+ $form = new Varien_Data_Form(
17
+ array('id' => 'filter_form', 'action' => $actionUrl, 'method' => 'get')
18
+ );
19
+ $htmlIdPrefix = 'sales_report_';
20
+ $form->setHtmlIdPrefix($htmlIdPrefix);
21
+ $fieldset = $form->addFieldset('base_fieldset', array('legend'=>Mage::helper('reports')->__('Filter')));
22
+
23
+ $dateFormatIso = Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT);
24
+
25
+ $fieldset->addField('from', 'date', array(
26
+ 'name' => 'from',
27
+ 'format' => $dateFormatIso,
28
+ 'image' => $this->getSkinUrl('images/grid-cal.gif'),
29
+ 'label' => Mage::helper('reports')->__('From'),
30
+ 'title' => Mage::helper('reports')->__('From'),
31
+ ));
32
+
33
+ $fieldset->addField('to', 'date', array(
34
+ 'name' => 'to',
35
+ 'format' => $dateFormatIso,
36
+ 'image' => $this->getSkinUrl('images/grid-cal.gif'),
37
+ 'label' => Mage::helper('reports')->__('To'),
38
+ 'title' => Mage::helper('reports')->__('To'),
39
+ ));
40
+
41
+ $form->setUseContainer(true);
42
+ $this->setForm($form);
43
+
44
+ return parent::_prepareForm();
45
+ }
46
+
47
+ /**
48
+ * (non-PHPdoc)
49
+ * @see Mage_Adminhtml_Block_Widget_Form::_initFormValues()
50
+ */
51
+ protected function _initFormValues()
52
+ {
53
+ $this->getForm()->addValues($this->getFilterData()->getData());
54
+ return parent::_initFormValues();
55
+ }
56
+ }
app/code/community/Emv/Report/Block/Adminhtml/Details.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Abandoned Cart Detail Grid Container
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Report
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Report_Block_Adminhtml_Details extends Mage_Adminhtml_Block_Widget_Grid_Container
11
+ {
12
+
13
+ /**
14
+ * Constructor
15
+ */
16
+ public function __construct()
17
+ {
18
+ $this->_controller = 'adminhtml_details';
19
+ $this->_blockGroup = 'abandonment_report';
20
+
21
+ $from = Mage::registry('from');
22
+ $to = Mage::registry('to');
23
+ $fromTo = '';
24
+
25
+ if ($from || $to) {
26
+ $fromTo = ' (';
27
+ if ($from) {
28
+ $from = new Zend_Date($from, Varien_Date::DATETIME_INTERNAL_FORMAT);
29
+ $format = Mage::app()->getLocale()->getDateTimeFormat(null);
30
+ $from = $from->toString($format);
31
+ } else {
32
+ $from = '/';
33
+ }
34
+ $fromTo .= $from;
35
+
36
+ if ($to) {
37
+ $to = new Zend_Date($to, Varien_Date::DATETIME_INTERNAL_FORMAT);
38
+ $format = Mage::app()->getLocale()->getDateTimeFormat(null);
39
+ $to = $to->toString($format);
40
+ } else {
41
+ $to = '/';
42
+ }
43
+ $fromTo .= ' - ' . $to . ')';
44
+ }
45
+
46
+ // build header text
47
+ $type = '';
48
+ $alertId = Mage::registry('abandonmentalertid');
49
+ switch ($alertId) {
50
+ case Emv_CartAlert_Constants::FIRST_ALERT_REMINDER_ID:
51
+ default :
52
+ $type = Mage::helper('abandonment_report')->__('the first reminders');
53
+ break;
54
+ case Emv_CartAlert_Constants::SECOND_ALERT_REMINDER_ID:
55
+ $type = Mage::helper('abandonment_report')->__('the second reminders');
56
+ break;
57
+ case Emv_CartAlert_Constants::THIRD_ALERT_REMINDER_ID:
58
+ $type = Mage::helper('abandonment_report')->__('the third reminders');
59
+ break;
60
+ }
61
+ $this->_headerText = Mage::helper('abandonment_report')->__('Converted Cart Report for %s', $type) . $fromTo;
62
+
63
+ parent::__construct();
64
+
65
+ // remove button add
66
+ $this->_removeButton('add');
67
+ }
68
+ }
app/code/community/Emv/Report/Block/Adminhtml/Details/Grid.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Abandoned Cart Detail Block
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Report
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Report_Block_Adminhtml_Details_Grid extends Mage_Adminhtml_Block_Widget_Grid
11
+ {
12
+
13
+ /**
14
+ * (non-PHPdoc)
15
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareCollection()
16
+ */
17
+ protected function _prepareCollection()
18
+ {
19
+ $alertId = Mage::registry('abandonmentalertid');
20
+ $from = Mage::registry('from');
21
+ $to = Mage::registry('to');
22
+
23
+ $collection = Mage::getModel('abandonment/orderflag')->getCollection();
24
+ $collection->filterByReminderFlag(Mage::helper('abandonment')->getReminderFlagFromId($alertId));
25
+ $collection->joinConvertedCartDetails($from, $to);
26
+
27
+ $this->setCollection($collection);
28
+ return parent::_prepareCollection();
29
+ }
30
+
31
+ /**
32
+ * (non-PHPdoc)
33
+ * @see Mage_Adminhtml_Block_Widget_Grid::_prepareColumns()
34
+ */
35
+ protected function _prepareColumns()
36
+ {
37
+ $this->addColumn('email', array(
38
+ 'header' => Mage::helper('abandonment_report')->__('Email'),
39
+ 'index' => 'customer_email',
40
+ 'type' => 'varchar',
41
+ ));
42
+
43
+ $this->addColumn('firstname', array(
44
+ 'header' => Mage::helper('abandonment_report')->__('First Name'),
45
+ 'index' => 'customer_firstname',
46
+ 'type' => 'varchar',
47
+ ));
48
+
49
+ $this->addColumn('lastname', array(
50
+ 'header' => Mage::helper('abandonment_report')->__('Last Name'),
51
+ 'index' => 'customer_lastname',
52
+ 'type' => 'varchar',
53
+ ));
54
+
55
+ $this->addColumn('date', array(
56
+ 'header' => Mage::helper('abandonment_report')->__('Purchase On'),
57
+ 'index' => 'created_at',
58
+ 'type' => 'date',
59
+ 'filter' => false
60
+ ));
61
+
62
+ $this->addColumn('incrementid', array(
63
+ 'header' => Mage::helper('abandonment_report')->__('Order #'),
64
+ 'index' => 'increment_id',
65
+ 'type' => 'varchar',
66
+ ));
67
+
68
+ $this->addColumn('quantity', array(
69
+ 'header' => Mage::helper('abandonment_report')->__('Ordered Quantity'),
70
+ 'index' => 'total_qty_ordered',
71
+ 'type' => 'number',
72
+ 'filter' => false
73
+ ));
74
+
75
+ $this->addColumn('coupon_code', array(
76
+ 'header' => Mage::helper('abandonment_report')->__('Coupon Code'),
77
+ 'index' => 'coupon_code',
78
+ 'type' => 'varchar',
79
+ 'filter' => false
80
+ ));
81
+
82
+ $this->addColumn('itemtotal', array(
83
+ 'header' => Mage::helper('abandonment_report')->__('Subtotal'),
84
+ 'index' => 'subtotal',
85
+ 'type' => 'price',
86
+ 'filter' => false
87
+ ));
88
+
89
+ $this->addColumn('shipping_amount', array(
90
+ 'header' => Mage::helper('abandonment_report')->__('Shipping'),
91
+ 'index' => 'shipping_amount',
92
+ 'type' => 'price',
93
+ 'filter' => false
94
+ ));
95
+
96
+ $this->addColumn('discount_amount', array(
97
+ 'header' => Mage::helper('abandonment_report')->__('Discount'),
98
+ 'index' => 'discount_amount',
99
+ 'type' => 'price',
100
+ 'filter' => false
101
+ ));
102
+
103
+ $this->addColumn('ordertotal', array(
104
+ 'header' => Mage::helper('abandonment_report')->__('Order Total'),
105
+ 'index' => 'grand_total',
106
+ 'type' => 'price',
107
+ 'filter' => false
108
+ ));
109
+
110
+ // prepare paramters for csv export detail
111
+ $param = array();
112
+ $param['alertId'] = Mage::registry('abandonmentalertid');
113
+ $param['_current'] = true;
114
+ $from = Mage::registry('from');
115
+ $to = Mage::registry('to');
116
+
117
+ if($from !== null && $to !== null)
118
+ {
119
+ $param['from'] = $from;
120
+ $param['to'] = $to;
121
+ }
122
+
123
+ $this->_exportTypes[] = new Varien_Object(
124
+ array(
125
+ 'url' => $this->getUrl('*/*/exportDetailsCsv', $param),
126
+ 'label' => Mage::helper('adminhtml')->__('Export CSV')
127
+ )
128
+ );
129
+
130
+ return parent::_prepareColumns();
131
+ }
132
+
133
+ /**
134
+ * Get row url (sale order view)
135
+ *
136
+ * @see Mage_Adminhtml_Block_Widget_Grid::getRowUrl()
137
+ * @return string
138
+ */
139
+ public function getRowUrl($row)
140
+ {
141
+ return $this->getUrl('adminhtml/sales_order/view', array('order_id' => $row->getEntityId()));
142
+ }
143
+ }
app/code/community/Emv/Report/Helper/Data.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Abandoned Cart Report Helper
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Report
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Report_Helper_Data extends Mage_Core_Helper_Abstract
11
+ {
12
+ }
app/code/community/Emv/Report/controllers/Adminhtml/ConversionController.php ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Abandoned Cart Conversion Controller
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Report
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Report_Adminhtml_ConversionController extends Mage_Adminhtml_Controller_Action
11
+ {
12
+
13
+ /**
14
+ * Initialise action
15
+ */
16
+ protected function _initAction()
17
+ {
18
+ $this->loadLayout();
19
+
20
+ $this->_setActiveMenu('emailvision/abandonment');
21
+
22
+ $this->_title(Mage::helper('abandonment_report')->__('SmartFocus'))
23
+ ->_title(Mage::helper('abandonment_report')->__('Abandoned Cart Conversion Report'));
24
+ }
25
+
26
+ /**
27
+ * Grid Action
28
+ */
29
+ public function indexAction()
30
+ {
31
+ $this->_initAction();
32
+
33
+ $blocks = $this->getLayout()->getAllBlocks();
34
+ $gridBlock = $this->getLayout()->getBlock('abandonment.report.grid.container');
35
+ $filterFormBlock = $this->getLayout()->getBlock('abandonment.report.grid.filter.form');
36
+
37
+ $this->_initReportAction(array($gridBlock, $filterFormBlock));
38
+
39
+ $this->renderLayout();
40
+ }
41
+
42
+ /**
43
+ * Export to Csv Action
44
+ */
45
+ public function exportCsvAction()
46
+ {
47
+ /* @var $block Emv_Report_Block_Adminhtml_Conversion */
48
+ $block = $this->getLayout()->createBlock('abandonment_report/adminhtml_conversion');
49
+ $this->_initReportAction($block);
50
+
51
+ $io = new Varien_Io_File();
52
+
53
+ // prepare path file
54
+ $path = Mage::getBaseDir('var') . DS . 'export' . DS;
55
+ $name = md5(microtime());
56
+ $file = $path . DS . $name . '.csv';
57
+
58
+ $io->setAllowCreateFolders(true);
59
+ $io->open(array('path' => $path));
60
+ $io->streamOpen($file, 'w+');
61
+ $io->streamLock(true);
62
+
63
+ $from = $block->getFilterData()->getFrom();
64
+ $to = $block->getFilterData()->getTo();
65
+ $fromTo = '';
66
+ if ($from || $to) {
67
+ $fromTo = ' (';
68
+ if ($from) {
69
+ $from = new Zend_Date($from, Varien_Date::DATETIME_INTERNAL_FORMAT);
70
+ $format = Mage::app()->getLocale()->getDateTimeFormat(null);
71
+ $from = $from->toString($format);
72
+ } else {
73
+ $from = '/';
74
+ }
75
+ $fromTo .= $from;
76
+
77
+ if ($to) {
78
+ $to = new Zend_Date($to, Varien_Date::DATETIME_INTERNAL_FORMAT);
79
+ $format = Mage::app()->getLocale()->getDateTimeFormat(null);
80
+ $to = $to->toString($format);
81
+ } else {
82
+ $to = '/';
83
+ }
84
+ $fromTo .= ' - ' . $to . ')';
85
+ }
86
+
87
+ // build data for file
88
+ $data = array(
89
+ array(
90
+ '',
91
+ Mage::helper('abandonment_report')->__('Sent'),
92
+ Mage::helper('abandonment_report')->__('Converted'),
93
+ Mage::helper('abandonment_report')->__('Conversion Rate'),
94
+ Mage::helper('abandonment_report')->__('Total Revenue'),
95
+ Mage::helper('abandonment_report')->__('Average Revenue'),
96
+ ),
97
+
98
+ array(
99
+ Mage::helper('abandonment_report')->__('SCA Email 1 - First Reminder') . $fromTo,
100
+ $block->getNbFirstReminderSent(),
101
+ $block->getNbFirstReminderConverted(),
102
+ Mage::helper('emvcore')->formatNumberInLocale($block->getPercentageFirstConversion()) . '%',
103
+ Mage::helper('core')->currency($block->getRevenueFirstConversion(), true, false),
104
+ Mage::helper('core')->currency($block->getAverageRevenueFirstConversion(), true, false)
105
+ ),
106
+ array(
107
+ Mage::helper('abandonment_report')->__('SCA Email 2 - Second Reminder') . $fromTo,
108
+ $block->getNbSecondReminderSent(),
109
+ $block->getNbSecondReminderConverted(),
110
+ Mage::helper('emvcore')->formatNumberInLocale($block->getPercentageSecondConversion()) . '%',
111
+ Mage::helper('core')->currency($block->getRevenueSecondConversion(), true, false),
112
+ Mage::helper('core')->currency($block->getAverageRevenueSecondConversion(), true, false)
113
+ ),
114
+ array(
115
+ Mage::helper('abandonment_report')->__('SCA Email 3 - Third Reminder') . $fromTo,
116
+ $block->getNbThirdReminderSent(),
117
+ $block->getNbThirdReminderConverted(),
118
+ Mage::helper('emvcore')->formatNumberInLocale($block->getPercentageThirdConversion()) . '%',
119
+ Mage::helper('core')->currency($block->getRevenueThirdConversion(), true, false),
120
+ Mage::helper('core')->currency($block->getAverageRevenueThirdConversion(), true, false)
121
+ ),
122
+ array(
123
+ Mage::helper('abandonment_report')->__('Shopping Cart Abandonment') . $fromTo,
124
+ $block->getSumNbReminderSent(),
125
+ $block->getSumNbConvertedCarts(),
126
+ Mage::helper('emvcore')->formatNumberInLocale($block->getPercentageConversion()) . '%',
127
+ Mage::helper('core')->currency($block->getSumAmountConvertedCarts(), true, false),
128
+ Mage::helper('core')->currency($block->getAverageRevenueConversion(), true, false)
129
+ ),
130
+
131
+ array(
132
+ Mage::helper('abandonment_report')->__('Total'),
133
+ $block->getTotalSumNbReminderSent(),
134
+ $block->getTotalSumNbConvertedCarts(),
135
+ Mage::helper('emvcore')->formatNumberInLocale($block->getTotalPercentageConversion()) . '%',
136
+ Mage::helper('core')->currency($block->getTotalSumAmountConvertedCarts(), true, false),
137
+ Mage::helper('core')->currency($block->getTotalAverageRevenueConversion(), true, false)
138
+ ),
139
+ );
140
+
141
+ foreach ($data as $line)
142
+ {
143
+ $io->streamWriteCsv($line);
144
+ }
145
+
146
+ $io->streamUnlock();
147
+ $io->streamClose();
148
+
149
+ $this->_prepareDownloadResponse('cart_conversion.csv', array( 'type' => 'filename', 'value' => $file, 'rm' => true ));
150
+ }
151
+
152
+ /**
153
+ * Initialise report action - prepare block objects
154
+ *
155
+ * @param array $blocks
156
+ * @return Emv_Report_Adminhtml_ConversionController
157
+ */
158
+ public function _initReportAction($blocks)
159
+ {
160
+ if (!is_array($blocks)) {
161
+ $blocks = array($blocks);
162
+ }
163
+
164
+ $params = $this->_extractParams();
165
+
166
+ foreach ($blocks as $block) {
167
+ if ($block) {
168
+ $block->setFilterData($params);
169
+ }
170
+ }
171
+
172
+ return $this;
173
+ }
174
+
175
+ /**
176
+ * Extract data from request
177
+ *
178
+ * @return Varien_Object
179
+ */
180
+ protected function _extractParams()
181
+ {
182
+ $requestData = Mage::helper('adminhtml')->prepareFilterString($this->getRequest()->getParam('filter'));
183
+ $requestData = $this->_filterDates($requestData, array('from', 'to'));
184
+ $params = new Varien_Object();
185
+
186
+ foreach ($requestData as $key => $value) {
187
+ if (!empty($value)) {
188
+ $params->setData($key, $value);
189
+ }
190
+ }
191
+
192
+ return $params;
193
+ }
194
+
195
+ /**
196
+ * Check menu access
197
+ *
198
+ * (non-PHPdoc)
199
+ * @see Mage_Adminhtml_Controller_Action::_isAllowed()
200
+ */
201
+ protected function _isAllowed()
202
+ {
203
+ return Mage::getSingleton('admin/session')->isAllowed('emailvision/abandonment');
204
+ }
205
+ }
app/code/community/Emv/Report/controllers/Adminhtml/DetailsController.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Abandoned Cart Detail Controller
4
+ *
5
+ * @category Emv
6
+ * @package Emv_Report
7
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
8
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
9
+ */
10
+ class Emv_Report_Adminhtml_DetailsController extends Mage_Adminhtml_Controller_Action
11
+ {
12
+
13
+ /**
14
+ * Intialise action - set active menu and build title
15
+ */
16
+ protected function _initAction()
17
+ {
18
+ $this->loadLayout();
19
+ $this->_setActiveMenu('emailvision/abandonment');
20
+
21
+ $this->_title(Mage::helper('abandonment_report')->__('SmartFocus'))
22
+ ->_title(Mage::helper('abandonment_report')->__('Converted Cart Report'));
23
+ }
24
+
25
+ /**
26
+ * Grid action
27
+ */
28
+ public function indexAction()
29
+ {
30
+ Mage::register('abandonmentalertid', $this->getRequest()->getParam('alertid', ''));
31
+ Mage::register('from', $this->getRequest()->getParam('from', null));
32
+ Mage::register('to', $this->getRequest()->getParam('to', null));
33
+
34
+ $this->_initAction();
35
+
36
+ $this->_addContent($this->getLayout()->createBlock('abandonment_report/adminhtml_details'));
37
+ $this->renderLayout();
38
+ }
39
+
40
+ /**
41
+ * Export converted cart detail grid to CSV format
42
+ */
43
+ public function exportDetailsCsvAction()
44
+ {
45
+ Mage::register('abandonmentalertid', $this->getRequest()->getParam('alertid', ''));
46
+ Mage::register('from', $this->getRequest()->getParam('from', null));
47
+ Mage::register('to', $this->getRequest()->getParam('to', null));
48
+
49
+ $fileName = 'converted_cart_details.csv';
50
+ $grid = $this->getLayout()->createBlock('abandonment_report/adminhtml_details_grid');
51
+ $this->_prepareDownloadResponse($fileName, $grid->getCsvFile());
52
+ }
53
+
54
+ /**
55
+ * Check menu access
56
+ *
57
+ * (non-PHPdoc)
58
+ * @see Mage_Adminhtml_Controller_Action::_isAllowed()
59
+ */
60
+ protected function _isAllowed()
61
+ {
62
+ return Mage::getSingleton('admin/session')->isAllowed('emailvision/abandonment');
63
+ }
64
+
65
+ }
app/code/community/Emv/Report/etc/adminhtml.xml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <menu>
4
+ <emailvision>
5
+ <children>
6
+ <abandonment translate="title" module="abandonment_report">
7
+ <title>Abandoned Cart Conversion Report</title>
8
+ <action>emv_report/conversion</action>
9
+ </abandonment>
10
+ </children>
11
+ </emailvision>
12
+ </menu>
13
+ <acl>
14
+ <resources>
15
+ <admin>
16
+ <children>
17
+ <emailvision translate="title" module="reports">
18
+ <children>
19
+ <abandonment translate="title">
20
+ <title>Abandoned Cart Conversion Report</title>
21
+ </abandonment>
22
+ </children>
23
+ </emailvision>
24
+ </children>
25
+ </admin>
26
+ </resources>
27
+ </acl>
28
+ </config>
app/code/community/Emv/Report/etc/config.xml ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <config>
2
+ <modules>
3
+ <Emv_Report>
4
+ <version>0.1.0</version>
5
+ </Emv_Report>
6
+ </modules>
7
+ <global>
8
+ <helpers>
9
+ <abandonment_report>
10
+ <class>Emv_Report_Helper</class>
11
+ </abandonment_report>
12
+ </helpers>
13
+ <blocks>
14
+ <abandonment_report>
15
+ <class>Emv_Report_Block</class>
16
+ </abandonment_report>
17
+ </blocks>
18
+ </global>
19
+ <admin>
20
+ <routers>
21
+ <abandonment_report>
22
+ <use>admin</use>
23
+ <args>
24
+ <module>Emv_Report_Adminhtml</module>
25
+ <frontName>emv_report</frontName>
26
+ </args>
27
+ </abandonment_report>
28
+ </routers>
29
+ </admin>
30
+ <adminhtml>
31
+ <layout>
32
+ <updates>
33
+ <abandonment_report>
34
+ <file>emailvision/abandonment_report.xml</file>
35
+ </abandonment_report>
36
+ </updates>
37
+ </layout>
38
+ <translate>
39
+ <modules>
40
+ <Emv_Report>
41
+ <files>
42
+ <default>Emv_Report.csv</default>
43
+ </files>
44
+ </Emv_Report>
45
+ </modules>
46
+ </translate>
47
+ </adminhtml>
48
+ </config>
app/code/community/Mage/SalesRule/Helper/Coupon.php ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento Enterprise Edition
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Magento Enterprise Edition License
8
+ * that is bundled with this package in the file LICENSE_EE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://www.magentocommerce.com/license/enterprise-edition
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_SalesRule
23
+ * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://www.magentocommerce.com/license/enterprise-edition
25
+ */
26
+
27
+ /**
28
+ * Helper for coupon codes creating and managing
29
+ *
30
+ * @category Mage
31
+ * @package Mage_SalesRule
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_SalesRule_Helper_Coupon extends Mage_Core_Helper_Abstract
35
+ {
36
+ /**
37
+ * Constants which defines all possible coupon codes formats
38
+ */
39
+ const COUPON_FORMAT_ALPHANUMERIC = 'alphanum';
40
+ const COUPON_FORMAT_ALPHABETICAL = 'alpha';
41
+ const COUPON_FORMAT_NUMERIC = 'num';
42
+
43
+ /**
44
+ * Defines type of Coupon
45
+ */
46
+ const COUPON_TYPE_SPECIFIC_AUTOGENERATED = 1;
47
+
48
+ /**
49
+ * XML paths to coupon codes generation options
50
+ */
51
+ const XML_PATH_SALES_RULE_COUPON_LENGTH = 'promo/auto_generated_coupon_codes/length';
52
+ const XML_PATH_SALES_RULE_COUPON_FORMAT = 'promo/auto_generated_coupon_codes/format';
53
+ const XML_PATH_SALES_RULE_COUPON_PREFIX = 'promo/auto_generated_coupon_codes/prefix';
54
+ const XML_PATH_SALES_RULE_COUPON_SUFFIX = 'promo/auto_generated_coupon_codes/suffix';
55
+ const XML_PATH_SALES_RULE_COUPON_DASH_INTERVAL = 'promo/auto_generated_coupon_codes/dash';
56
+
57
+ /**
58
+ * Config path for character set and separator
59
+ */
60
+ const XML_CHARSET_NODE = 'global/salesrule/coupon/charset/%s';
61
+ const XML_CHARSET_SEPARATOR = 'global/salesrule/coupon/separator';
62
+
63
+ /**
64
+ * Get all possible coupon codes formats
65
+ *
66
+ * @return array
67
+ */
68
+ public function getFormatsList()
69
+ {
70
+ return array(
71
+ self::COUPON_FORMAT_ALPHANUMERIC => $this->__('Alphanumeric'),
72
+ self::COUPON_FORMAT_ALPHABETICAL => $this->__('Alphabetical'),
73
+ self::COUPON_FORMAT_NUMERIC => $this->__('Numeric'),
74
+ );
75
+ }
76
+
77
+ /**
78
+ * Get default coupon code length
79
+ *
80
+ * @return int
81
+ */
82
+ public function getDefaultLength()
83
+ {
84
+ return (int)Mage::getStoreConfig(self::XML_PATH_SALES_RULE_COUPON_LENGTH);
85
+ }
86
+
87
+ /**
88
+ * Get default coupon code format
89
+ *
90
+ * @return int
91
+ */
92
+ public function getDefaultFormat()
93
+ {
94
+ return Mage::getStoreConfig(self::XML_PATH_SALES_RULE_COUPON_FORMAT);
95
+ }
96
+
97
+ /**
98
+ * Get default coupon code prefix
99
+ *
100
+ * @return string
101
+ */
102
+ public function getDefaultPrefix()
103
+ {
104
+ return Mage::getStoreConfig(self::XML_PATH_SALES_RULE_COUPON_PREFIX);
105
+ }
106
+
107
+ /**
108
+ * Get default coupon code suffix
109
+ *
110
+ * @return string
111
+ */
112
+ public function getDefaultSuffix()
113
+ {
114
+ return Mage::getStoreConfig(self::XML_PATH_SALES_RULE_COUPON_SUFFIX);
115
+ }
116
+
117
+ /**
118
+ * Get dashes occurrences frequency in coupon code
119
+ *
120
+ * @return int
121
+ */
122
+ public function getDefaultDashInterval()
123
+ {
124
+ return (int)Mage::getStoreConfig(self::XML_PATH_SALES_RULE_COUPON_DASH_INTERVAL);
125
+ }
126
+
127
+ /**
128
+ * Get Coupon's alphabet as array of chars
129
+ *
130
+ * @param string $format
131
+ * @return array|bool
132
+ */
133
+ public function getCharset($format)
134
+ {
135
+ return str_split((string) Mage::app()->getConfig()->getNode(sprintf(self::XML_CHARSET_NODE, $format)));
136
+ }
137
+
138
+ /**
139
+ * Retrieve Separator from config
140
+ *
141
+ * @return string
142
+ */
143
+ public function getCodeSeparator()
144
+ {
145
+ return (string) Mage::app()->getConfig()->getNode(Mage_SalesRule_Helper_Coupon::XML_CHARSET_SEPARATOR);
146
+ }
147
+ }
app/code/community/Mage/SalesRule/Model/Coupon/Massgenerator.php ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento Enterprise Edition
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Magento Enterprise Edition License
8
+ * that is bundled with this package in the file LICENSE_EE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://www.magentocommerce.com/license/enterprise-edition
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_SalesRule
23
+ * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://www.magentocommerce.com/license/enterprise-edition
25
+ */
26
+
27
+
28
+ /**
29
+ * SalesRule Mass Coupon Generator
30
+ *
31
+ * @method Mage_SalesRule_Model_Resource_Coupon getResource()
32
+ *
33
+ * @category Mage
34
+ * @package Mage_SalesRule
35
+ * @author Magento Core Team <core@magentocommerce.com>
36
+ */
37
+ class Mage_SalesRule_Model_Coupon_Massgenerator extends Mage_Core_Model_Abstract
38
+ implements Mage_SalesRule_Model_Coupon_CodegeneratorInterface
39
+ {
40
+ /**
41
+ * Maximum probability of guessing the coupon on the first attempt
42
+ */
43
+ const MAX_PROBABILITY_OF_GUESSING = 0.25;
44
+ const MAX_GENERATE_ATTEMPTS = 10;
45
+
46
+ /**
47
+ * Count of generated Coupons
48
+ * @var int
49
+ */
50
+ protected $_generatedCount = 0;
51
+
52
+ /**
53
+ * Initialize resource
54
+ */
55
+ protected function _construct()
56
+ {
57
+ $this->_init('salesrule/coupon');
58
+ }
59
+
60
+ /**
61
+ * Generate coupon code
62
+ *
63
+ * @return string
64
+ */
65
+ public function generateCode()
66
+ {
67
+ $format = $this->getFormat();
68
+ if (!$format) {
69
+ $format = Mage_SalesRule_Helper_Coupon::COUPON_FORMAT_ALPHANUMERIC;
70
+ }
71
+ $length = max(1, (int) $this->getLength());
72
+ $split = max(0, (int) $this->getDash());
73
+ $suffix = $this->getSuffix();
74
+ $prefix = $this->getPrefix();
75
+
76
+ $splitChar = $this->getDelimiter();
77
+ $charset = Mage::helper('salesrule/coupon')->getCharset($format);
78
+
79
+ $code = '';
80
+ $charsetSize = count($charset);
81
+ for ($i=0; $i<$length; $i++) {
82
+ $char = $charset[mt_rand(0, $charsetSize - 1)];
83
+ if ($split > 0 && ($i % $split) == 0 && $i != 0) {
84
+ $char = $splitChar . $char;
85
+ }
86
+ $code .= $char;
87
+ }
88
+
89
+ $code = $prefix . $code . $suffix;
90
+ return $code;
91
+ }
92
+
93
+ /**
94
+ * Retrieve delimiter
95
+ *
96
+ * @return string
97
+ */
98
+ public function getDelimiter()
99
+ {
100
+ if ($this->getData('delimiter')) {
101
+ return $this->getData('delimiter');
102
+ } else {
103
+ return Mage::helper('salesrule/coupon')->getCodeSeparator();
104
+ }
105
+ }
106
+
107
+ /**
108
+ * Generate Coupons Pool
109
+ *
110
+ * @return Mage_SalesRule_Model_Coupon_Massgenerator
111
+ */
112
+ public function generatePool()
113
+ {
114
+ $this->_generatedCount = 0;
115
+ $size = $this->getQty();
116
+
117
+ $maxProbability = $this->getMaxProbability() ? $this->getMaxProbability() : self::MAX_PROBABILITY_OF_GUESSING;
118
+ $maxAttempts = $this->getMaxAttempts() ? $this->getMaxAttempts() : self::MAX_GENERATE_ATTEMPTS;
119
+
120
+ /** @var $coupon Mage_SalesRule_Model_Coupon */
121
+ $coupon = Mage::getModel('salesrule/coupon');
122
+
123
+ $chars = count(Mage::helper('salesrule/coupon')->getCharset($this->getFormat()));
124
+ $length = (int) $this->getLength();
125
+ $maxCodes = pow($chars, $length);
126
+ $probability = $size / $maxCodes;
127
+ //increase the length of Code if probability is low
128
+ if ($probability > $maxProbability) {
129
+ do {
130
+ $length++;
131
+ $maxCodes = pow($chars, $length);
132
+ $probability = $size / $maxCodes;
133
+ } while ($probability > $maxProbability);
134
+ $this->setLength($length);
135
+ }
136
+
137
+ $now = $this->getResource()->formatDate(
138
+ Mage::getSingleton('core/date')->gmtTimestamp()
139
+ );
140
+
141
+ for ($i = 0; $i < $size; $i++) {
142
+ $attempt = 0;
143
+ do {
144
+ if ($attempt >= $maxAttempts) {
145
+ Mage::throwException(Mage::helper('salesrule')->__('Unable to create requested Coupon Qty. Please check settings and try again.'));
146
+ }
147
+ $code = $this->generateCode();
148
+ $attempt++;
149
+ } while ($this->getResource()->exists($code));
150
+
151
+ $expirationDate = $this->getToDate();
152
+ if ($expirationDate instanceof Zend_Date) {
153
+ $expirationDate = $expirationDate->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
154
+ }
155
+
156
+ $coupon->setId(null)
157
+ ->setRuleId($this->getRuleId())
158
+ ->setUsageLimit($this->getUsesPerCoupon())
159
+ ->setUsagePerCustomer($this->getUsesPerCustomer())
160
+ ->setExpirationDate($expirationDate)
161
+ ->setCreatedAt($now)
162
+ ->setType(Mage_SalesRule_Helper_Coupon::COUPON_TYPE_SPECIFIC_AUTOGENERATED)
163
+ ->setCode($code)
164
+ ->save();
165
+
166
+ $this->_generatedCount++;
167
+ }
168
+ return $this;
169
+ }
170
+
171
+ /**
172
+ * Validate input
173
+ *
174
+ * @param array $data
175
+ * @return bool
176
+ */
177
+ public function validateData($data)
178
+ {
179
+ return !empty($data) && !empty($data['qty']) && !empty($data['rule_id'])
180
+ && !empty($data['length']) && !empty($data['format'])
181
+ && (int)$data['qty'] > 0 && (int) $data['rule_id'] > 0
182
+ && (int) $data['length'] > 0;
183
+ }
184
+
185
+ /**
186
+ * Retrieve count of generated Coupons
187
+ *
188
+ * @return int
189
+ */
190
+ public function getGeneratedCount()
191
+ {
192
+ return $this->_generatedCount;
193
+ }
194
+ }
app/code/community/Mage/SalesRule/Model/System/Config/Source/Coupon/Format.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento Enterprise Edition
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Magento Enterprise Edition License
8
+ * that is bundled with this package in the file LICENSE_EE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://www.magentocommerce.com/license/enterprise-edition
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_SalesRule
23
+ * @copyright Copyright (c) 2012 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://www.magentocommerce.com/license/enterprise-edition
25
+ */
26
+
27
+ /**
28
+ * Options for Code Format Field in Auto Generated Specific Coupon Codes configuration section
29
+ *
30
+ * @category Mage
31
+ * @package Mage_SalesRule
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class Mage_SalesRule_Model_System_Config_Source_Coupon_Format
35
+ {
36
+ /**
37
+ * Options getter
38
+ *
39
+ * @return array
40
+ */
41
+ public function toOptionArray()
42
+ {
43
+ $formatsList = Mage::helper('salesrule/coupon')->getFormatsList();
44
+ $result = array();
45
+ foreach ($formatsList as $formatId => $formatTitle) {
46
+ $result[] = array(
47
+ 'value' => $formatId,
48
+ 'label' => $formatTitle
49
+ );
50
+ }
51
+
52
+ return $result;
53
+ }
54
+ }
app/design/adminhtml/default/default/layout/emailvision/abandonment_report.xml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout>
3
+ <abandonment_report_conversion_index>
4
+ <reference name="content">
5
+ <block type="abandonment_report/adminhtml_conversion" template="emailvision/abandonment/grid/container.phtml" name="abandonment.report.grid.container">
6
+ <block type="abandonment_report/adminhtml_conversion_form" name="abandonment.report.grid.filter.form">
7
+ </block>
8
+ </block>
9
+ </reference>
10
+ </abandonment_report_conversion_index>
11
+ </layout>
app/design/adminhtml/default/default/template/emailvision/abandonment/grid/container.phtml ADDED
@@ -0,0 +1,195 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Emv_Report_Block_Adminhtml_Conversion */
3
+ ?>
4
+
5
+ <div class="content-header">
6
+ <table cellspacing="0">
7
+ <tr>
8
+ <td style="<?php echo $this->getHeaderWidth() ?>"><?php echo $this->getHeaderHtml() ?></td>
9
+ <td class="form-buttons"><?php echo $this->getButtonsHtml() ?></td>
10
+ </tr>
11
+ </table>
12
+ </div>
13
+
14
+ <div>
15
+ <?php echo $this->getChildHtml('abandonment.report.grid.filter.form') ?>
16
+ </div>
17
+
18
+ <div class="clear"></div>
19
+
20
+ <div class="grid">
21
+ <div class="hor-scroll">
22
+ <table cellspacing="0" id="" class="data">
23
+ <colgroup>
24
+ <col width="100">
25
+ <col width="100">
26
+ <col width="100">
27
+ <col width="100">
28
+ <col width="100">
29
+ <col width="100">
30
+ </colgroup>
31
+ <thead>
32
+ <tr class="headings">
33
+ <th class=" no-link"><span class="nobr"></span></th>
34
+ <th class=" no-link"><span class="nobr"><?php echo Mage::helper('abandonment_report')->__('Sent')?></span></th>
35
+ <th class=" no-link"><span class="nobr"><?php echo Mage::helper('abandonment_report')->__('Converted')?></span></th>
36
+ <th class=" no-link"><span class="nobr"><?php echo Mage::helper('abandonment_report')->__('Conversion Rate')?></span></th>
37
+ <th class=" no-link"><span class="nobr"><?php echo Mage::helper('abandonment_report')->__('Total')?></span></th>
38
+ <th class=" no-link"><span class="nobr"><?php echo Mage::helper('abandonment_report')->__('Average')?></span></th>
39
+ </tr>
40
+ </thead>
41
+ <tfoot>
42
+ <tr class="totals">
43
+ <th class=""><?php echo Mage::helper('abandonment_report')->__('Total')?>&nbsp;</th>
44
+ <td class="a-right"><?php
45
+ echo Mage::helper('emvcore')
46
+ ->formatNumberInLocale($this->getSumNbReminderSent(), null, 0)
47
+ ?></td>
48
+ <td class="a-right"><?php
49
+ echo Mage::helper('emvcore')
50
+ ->formatNumberInLocale($this->getSumNbConvertedCarts(), null, 0)
51
+ ?></td>
52
+ <td class="a-right"><?php
53
+ echo Mage::helper('emvcore')
54
+ ->formatNumberInLocale($this->getPercentageConversion(), null, 2) . '%';
55
+ ?></td>
56
+ <td class="a-right"><?php
57
+ echo Mage::helper('core')
58
+ ->currency($this->getSumAmountConvertedCarts(), true, true);
59
+ ?></td>
60
+ <td class="a-right"><?php
61
+ echo Mage::helper('core')
62
+ ->currency($this->getAverageRevenueConversion(), true, true);
63
+ ?></td>
64
+ </tr>
65
+ </tfoot>
66
+ <tbody>
67
+ <tr title="<?php echo Mage::helper('abandonment_report')->__('SCA Email 1 - First Reminder')?>" class="even">
68
+ <th ><?php echo Mage::helper('abandonment_report')->__('SCA Email 1 - First Reminder')?></th>
69
+ <td class=" a-right ">
70
+ <?php
71
+ echo Mage::helper('emvcore')
72
+ ->formatNumberInLocale($this->getNbFirstReminderSent(), null, 0);
73
+ ?>
74
+ </td>
75
+ <td class=" a-right ">
76
+ <a href="<?php echo $this->getDetailsFirstAlertUrl();?>">
77
+ <?php echo Mage::helper('emvcore')
78
+ ->formatNumberInLocale($this->getNbFirstReminderConverted(), null, 0);
79
+ ?>
80
+ </a>
81
+ </td>
82
+ <td class=" a-right ">
83
+ <?php
84
+ echo Mage::helper('emvcore')->formatNumberInLocale($this->getPercentageFirstConversion(), null, 2) . '%';
85
+ ?>
86
+ </td>
87
+ <td class=" a-right ">
88
+ <?php
89
+ echo Mage::helper('core')->currency($this->getRevenueFirstConversion(), true, true);
90
+ ?>
91
+ </td>
92
+ <td class=" a-right last">
93
+ <?php
94
+ echo Mage::helper('core')->currency($this->getAverageRevenueFirstConversion(), true, true);
95
+ ?>
96
+ </td>
97
+ </tr>
98
+
99
+ <tr title="<?php echo Mage::helper('abandonment_report')->__('SCA Email 2 - Second Reminder') ?>" class="odd">
100
+ <th ><?php echo Mage::helper('abandonment_report')->__('SCA Email 2 - Second Reminder') ?></th>
101
+ <td class=" a-right ">
102
+ <?php
103
+ echo Mage::helper('emvcore')->formatNumberInLocale($this->getNbSecondReminderSent(), null, 0);
104
+ ?>
105
+ </td>
106
+ <td class=" a-right ">
107
+ <a href="<?php echo $this->getDetailsSecondAlertUrl();?>">
108
+ <?php
109
+ echo Mage::helper('emvcore')
110
+ ->formatNumberInLocale($this->getNbSecondReminderConverted(), null, 0);
111
+ ?>
112
+ </a>
113
+ </td>
114
+ <td class=" a-right ">
115
+ <?php
116
+ echo Mage::helper('emvcore')
117
+ ->formatNumberInLocale($this->getPercentageSecondConversion(), null, 2) . '%';
118
+ ?>
119
+ </td>
120
+ <td class=" a-right ">
121
+ <?php
122
+ echo Mage::helper('core')->currency($this->getRevenueSecondConversion(), true, true);
123
+ ?>
124
+ </td>
125
+ <td class=" a-right last">
126
+ <?php
127
+ echo Mage::helper('core')->currency($this->getAverageRevenueSecondConversion(), true, true);
128
+ ?>
129
+ </td>
130
+ </tr>
131
+
132
+ <tr title="<?php echo Mage::helper('abandonment_report')->__('SCA Email 3 - Third Reminder') ?>" class="even">
133
+ <th ><?php echo Mage::helper('abandonment_report')->__('SCA Email 3 - Third Reminder') ?></th>
134
+ <td class=" a-right ">
135
+ <?php
136
+ echo Mage::helper('emvcore')
137
+ ->formatNumberInLocale($this->getNbThirdReminderSent(), null, 0);
138
+ ?>
139
+ </td>
140
+ <td class=" a-right ">
141
+ <a href="<?php echo $this->getDetailsThirdAlertUrl();?>">
142
+ <?php
143
+ echo Mage::helper('emvcore')->formatNumberInLocale($this->getNbThirdReminderConverted(), null, 0);
144
+ ?>
145
+ </a>
146
+ </td>
147
+ <td class=" a-right ">
148
+ <?php
149
+ echo Mage::helper('emvcore')
150
+ ->formatNumberInLocale($this->getPercentageThirdConversion(), null, 2) . '%';
151
+ ?>
152
+ </td>
153
+ <td class=" a-right ">
154
+ <?php
155
+ echo Mage::helper('core')->currency($this->getRevenueThirdConversion(), true, true);
156
+ ?>
157
+ </td>
158
+ <td class=" a-right last">
159
+ <?php
160
+ echo Mage::helper('core')->currency($this->getAverageRevenueThirdConversion(), true, true);
161
+ ?>
162
+ </td>
163
+ </tr>
164
+ </tbody>
165
+ </table>
166
+ </div>
167
+ </div>
168
+ <div class="clear"></div>
169
+
170
+
171
+ <script type="text/javascript">
172
+ function filterFormSubmit() {
173
+ var filters = $$('#filter_form input');
174
+ var elements = [];
175
+ for(var i in filters){
176
+ if(filters[i].value && filters[i].value.length && !filters[i].disabled) elements.push(filters[i]);
177
+ }
178
+ var validator = new Validation('filter_form');
179
+ if (validator.validate()) {
180
+ setLocation('<?php echo $this->getFilterUrl(); ?>filter/'+encode_base64(Form.serializeElements(elements))+'/');
181
+ }
182
+ }
183
+
184
+ function filterExportSubmit() {
185
+ var filters = $$('#filter_form input');
186
+ var elements = [];
187
+ for(var i in filters){
188
+ if(filters[i].value && filters[i].value.length && !filters[i].disabled) elements.push(filters[i]);
189
+ }
190
+ var validator = new Validation('filter_form');
191
+ if (validator.validate()) {
192
+ setLocation('<?php echo $this->getExportUrl(); ?>filter/'+encode_base64(Form.serializeElements(elements))+'/');
193
+ }
194
+ }
195
+ </script>
app/design/adminhtml/default/default/template/emailvision/account/associated_urls.phtml ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var $this Emv_Core_Block_Adminhtml_Account_Edit_AssociatedUrls */
3
+ // add url button
4
+ ?>
5
+ <button id="<?php echo $this->getAddId() ?>" class="scalable add" type="button">
6
+ <span><?php echo Mage::helper('emvcore')->__('Add')?></span>
7
+ </button>
8
+
9
+ <?php
10
+ // retreive account
11
+ $account = $this->getData('account');
12
+ $emvUrls = (is_array($account->getEmvUrls())) ? $account->getEmvUrls() : array();
13
+ $index = 0;
14
+ $usedService = array();
15
+
16
+ $servicesAndLabels = Emv_Core_Model_Account::getUrlTypesAndLabels();
17
+ // build used urls
18
+ ?>
19
+ <div class="entry-edit custom-options bundle" id="<?php echo $this->getWebserviceDivId()?>">
20
+ <?php foreach($emvUrls as $type => $urlData) : ?>
21
+ <div id="service<?php echo $index; ?>" class="option-box">
22
+ <table class="option-header">
23
+ <thead>
24
+ <tr>
25
+ <th>&nbsp;</th>
26
+ <th class="opt-type"><?php echo Mage::helper('emvcore')->__('Service')?></th>
27
+ <th class="opt-req"><?php echo Mage::helper('emvcore')->__('Url')?> <span class="required">*</span></th>
28
+ </tr>
29
+ </thead>
30
+ <tbody>
31
+ <tr>
32
+ <td>&nbsp;
33
+ <button onclick="emvAccount.deleteService(<?php echo $index; ?>)"
34
+ id="remove<?php echo $index; ?>"
35
+ title="<?php echo Mage::helper('emvcore')->__('Remove')?>" type="button" class="scalable delete" style=""
36
+ >
37
+ <span><?php echo Mage::helper('emvcore')->__('Remove')?></span>
38
+ </button>
39
+ </td>
40
+ <td class="value">
41
+ <input type="text"
42
+ value="<?php echo isset($servicesAndLabels[$type]) ? $servicesAndLabels[$type] : 'service' ?>"
43
+ disabled="disabled" class="input-text required-entry webservice-type"
44
+ />
45
+ </td>
46
+ <td class="value">
47
+ <input type="text" class="input-text required-entry validate-url-emv"
48
+ name="emv_urls[<?php echo $type ?>][url]"
49
+ value="<?php echo $urlData['url'] ?>"
50
+ />
51
+ </td>
52
+ </tr>
53
+ </tbody>
54
+ </table>
55
+ </div>
56
+ <?php
57
+ $usedService[$index] = array(
58
+ 'value' => $type,
59
+ 'text' => isset($servicesAndLabels[$type]) ? $servicesAndLabels[$type] : 'service'
60
+ );
61
+ $index++;
62
+ ?>
63
+ <?php endforeach;?>
64
+ </div>
65
+
66
+ <script type="text/javascript">
67
+ // service template
68
+ var serviceTemplate = '<div class="option-box" id="service#{_id}">'
69
+ + '<table class="option-header">'
70
+ + ' <thead>'
71
+ + ' <tr>'
72
+ + ' <th>&nbsp;</th>'
73
+ + ' <th class="opt-type"><?php echo Mage::helper('emvcore')->__('Service')?></th>'
74
+ + ' <th class="opt-req"><?php echo Mage::helper('emvcore')->__('Url')?> <span class="required">*</span></th>'
75
+ + ' </tr>'
76
+ + ' </thead>'
77
+ + ' <tbody>'
78
+ + ' <tr>'
79
+ + ' <td>&nbsp;'
80
+ + ' <button style="" class="scalable delete" type="button" title="Remove" id="remove#{_id}" onClick="emvAccount.deleteService(#{_id})">'
81
+ + ' <span><?php echo Mage::helper('emvcore')->__('Remove')?></span>'
82
+ + ' </button>'
83
+ + ' </td>'
84
+ + ' <td class="value">'
85
+ + ' <input type="text" class="input-text required-entry webservice-type" disabled="disabled" value="#{_text}" />'
86
+ + ' </td>'
87
+ + ' <td class="value">'
88
+ + ' <input type="text" name="emv_urls[#{_value}][url]" class="input-text required-entry validate-url-emv" value="#{_url}" />'
89
+ + ' </td>'
90
+ + ' </tr>'
91
+ + ' </tbody>'
92
+ + '</table>'
93
+ + '</div>'
94
+
95
+ Emv = {};
96
+ Emv.Account = Class.create();
97
+ Emv.Account.prototype = {
98
+ divId : '<?php echo $this->getWebserviceDivId() ?>',
99
+ addId : '<?php echo $this->getAddId() ?>',
100
+ availableServicesId :'<?php echo $this->getAvailableServiceId()?>',
101
+ urlDefault : <?php echo $this->getDefaultUrls() ?>,
102
+
103
+ itemCount : <?php echo $index ?>,
104
+ usedServices : <?php echo Mage::helper('core')->jsonEncode($usedService) ?>,
105
+ template : new Template(serviceTemplate),
106
+
107
+ initialize : function() {
108
+ // bind add function
109
+ var button = $(this.addId);
110
+ Event.observe(button, 'click', this.addNewService.bind(this));
111
+ },
112
+
113
+ addNewService : function(event) {
114
+ var selectedServiceId = $(this.availableServicesId).selectedIndex;
115
+ if (selectedServiceId >=0) {
116
+ this.usedServices[this.itemCount] = {
117
+ 'text' : $(this.availableServicesId)[selectedServiceId].text,
118
+ 'value' : $(this.availableServicesId)[selectedServiceId].value
119
+ };
120
+
121
+ var urlDefault = '';
122
+ if (typeof(this.urlDefault[this.usedServices[this.itemCount].value]) != 'undefined') {
123
+ urlDefault = this.urlDefault[this.usedServices[this.itemCount].value];
124
+ }
125
+
126
+ // build new service from template text
127
+ var templateData = {
128
+ _id : this.itemCount,
129
+ _value : this.usedServices[this.itemCount].value,
130
+ _text : this.usedServices[this.itemCount].text,
131
+ _url : urlDefault
132
+ };
133
+ $(this.divId).insert(this.template.evaluate(templateData));
134
+
135
+ // remove selected service from the available list
136
+ $(this.availableServicesId).options[selectedServiceId].remove();
137
+
138
+ this.itemCount ++;
139
+ }
140
+ },
141
+
142
+ deleteService : function(indexService)
143
+ {
144
+ $('service' + indexService).remove();
145
+ this.restoreServiceInAvailableList(
146
+ this.usedServices[indexService].text,
147
+ this.usedServices[indexService].value
148
+ );
149
+ // remove used service from the list
150
+ delete this.usedServices[indexService];
151
+ },
152
+
153
+ restoreServiceInAvailableList : function (text, value)
154
+ {
155
+ var newOption = '<option value="' + value + '">' + text + '</option>';
156
+ $(this.availableServicesId).insert(newOption);
157
+ }
158
+ }
159
+
160
+ emvAccount = new Emv.Account();
161
+
162
+
163
+ Validation.add(
164
+ 'validate-url-emv',
165
+ 'Please enter a valid URL. Protocol is required (http://, https:// or ftp://)',
166
+ function(v) {
167
+ v = (v || '').replace(/^\s+/, '').replace(/\s+$/, '');
168
+ return Validation.get('IsEmpty').test(v) || /^(http|https|ftp):\/\/(([A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))(\.[A-Z0-9]([A-Z0-9_-]*[A-Z0-9]|))*)(:(\d+))?(\/[A-Z0-9~](([A-Z0-9_~-]|\.)*[A-Z0-9~]|))*\/?(.*)?$/i.test(v)
169
+ }
170
+ );
171
+ </script>
app/design/adminhtml/default/default/template/emailvision/datasync/system/config/form/field/array.phtml ADDED
@@ -0,0 +1,269 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Mapping table template (configuration)
4
+ * @see Emv_DataSync_Block_Adminhtml_System_Config_CustomerAttributes
5
+ */
6
+ ?>
7
+
8
+ <?php
9
+ $_htmlId = $this->getHtmlId() ? $this->getHtmlId() : '_' . uniqid();
10
+
11
+ $_colspan = 2;
12
+ if (!$this->_addAfter) {
13
+ $_colspan -= 1;
14
+ }
15
+ $_colspan = $_colspan > 1 ? 'colspan="' . $_colspan . '"' : '';
16
+ ?>
17
+
18
+ <div class="grid" id="grid<?php echo $_htmlId ?>">
19
+ <table cellpadding="0" cellspacing="0" class="border">
20
+ <tbody>
21
+
22
+ <tr class="headings" id="headings<?php echo $_htmlId ?>">
23
+ <?php foreach ($this->_columns as $columnName => $column):?>
24
+ <th><?php echo $column['label'] ?></th>
25
+ <?php endforeach;?>
26
+ <th <?php echo $_colspan?>></th>
27
+ </tr>
28
+
29
+ <tr id="addRow<?php echo $_htmlId ?>">
30
+ <td colspan="<?php echo count($this->_columns) ?>"></td>
31
+ <td <?php echo $_colspan?>>
32
+ <button style="" onclick="" class="scalable add" type="button" id="addToEndBtn<?php echo $_htmlId ?>">
33
+ <span><?php echo $this->_addButtonLabel ?></span>
34
+ </button>
35
+ </td>
36
+ </tr>
37
+
38
+ </tbody>
39
+ </table>
40
+ <input type="hidden" name="<?php echo $this->getElement()->getName() ?>[__empty]" value="" />
41
+ </div>
42
+ <div id="empty<?php echo $_htmlId ?>">
43
+ <button style="" onclick="" class="scalable add" type="button" id="emptyAddBtn<?php echo $_htmlId ?>">
44
+ <span><?php echo $this->_addButtonLabel ?></span>
45
+ </button>
46
+ </div>
47
+
48
+ <?php
49
+ $fieldstoJs = array();
50
+ $emailVisionFields = Mage::helper('emvdatasync')->getEmailVisionFieldsFromConfig();
51
+ foreach ($emailVisionFields as $field) {
52
+ $fieldstoJs[] = strtolower($field['name']);
53
+ }
54
+ ?>
55
+
56
+ <script type="text/javascript">
57
+ //<![CDATA[
58
+ var emailVisionFields = new Array(<?php echo "'" . implode("','", $fieldstoJs) . "'" ?>);
59
+ var usedEmailVisionFields = new Array();
60
+ var previous;
61
+ var index;
62
+ var customerMappingId = 'emvdatasync_customer_mapping_emailvision_entity_id';
63
+
64
+ // Add Array method to complete removing values from arrays
65
+ Array.prototype.remove = function(value) {
66
+ if (this.indexOf(value)!==-1) {
67
+ this.splice(this.indexOf(value), 1);
68
+ return true;
69
+ } else {
70
+ return false;
71
+ };
72
+ }
73
+
74
+ // Remove new used option and add the old one from other selects
75
+ function updateOptions() {
76
+ var selects;
77
+ var optionToRemove;
78
+ selects = $$('select.emailvision_select');
79
+ // Push the customer entity field in the selects concerned array
80
+ selects.push($(customerMappingId));
81
+
82
+ // Remove used options
83
+ for (var ii = 0; ii < usedEmailVisionFields.length; ii++) {
84
+ selects.each(function (select) {
85
+ // remove all options that have been used
86
+ for (var i=0; i < select.options.length; i++) {
87
+ if (i != select.selectedIndex) {
88
+ if (select.options[i].value == usedEmailVisionFields[ii]) {
89
+ select.options[i].remove();
90
+ }
91
+ }
92
+ }
93
+ });
94
+ }
95
+
96
+ var optionsToAdd = new Array();
97
+ // Add not used ones
98
+ for (var ii = 0; ii < emailVisionFields.length; ii++) {
99
+ selects.each(function (select) {
100
+ optionToAdd = select.select('option[value="'+ emailVisionFields[ii] +'"]').first();
101
+ if(optionToAdd == null) {
102
+ select.insert(new Element('option', {value: emailVisionFields[ii]}).update(emailVisionFields[ii].toUpperCase()));
103
+ }
104
+ });
105
+ }
106
+ }
107
+
108
+ // Observe window loaded to separate values that are already used in options and the others
109
+ Event.observe(window, 'load', function() {
110
+ updateOptions();
111
+ });
112
+
113
+ // Check use of first field
114
+ emailVisionFields.remove($(customerMappingId).value);
115
+ usedEmailVisionFields.push($(customerMappingId).value);
116
+
117
+ $(customerMappingId).observe('focus', function () {
118
+ previous = this.value;
119
+ }).observe('change', function() {
120
+ usedEmailVisionFields.remove(previous);
121
+ usedEmailVisionFields.push(this.value);
122
+ emailVisionFields.remove(this.value);
123
+ emailVisionFields.push(previous);
124
+ updateOptions();
125
+ });
126
+
127
+ // create row creator
128
+ var arrayRow<?php echo $_htmlId ?> = {
129
+ // define row prototypeJS template
130
+ template : new Template(
131
+ '<tr id="#{_id}">'
132
+ <?php foreach ($this->_columns as $columnName => $column):?>
133
+ +'<td>'
134
+ +'<?php echo $this->_renderCellTemplate($columnName)?>'
135
+ +'<\/td>'
136
+ <?php endforeach;?>
137
+ <?php if ($this->_addAfter):?>
138
+ +'<td><button onclick="" class="scalable add" type="button" id="addAfterBtn#{_id}"><span><?php echo Mage::helper('adminhtml')->__('Add after') ?><\/span><\/button><\/td>'
139
+ <?php endif;?>
140
+ +'<td><button onclick="arrayRow<?php echo $_htmlId ?>.del(\'#{_id}\')" class="scalable delete" type="button"><span><?php echo Mage::helper('adminhtml')->__('Delete') ?><\/span><\/button><\/td>'
141
+ +'<\/tr>'
142
+ ),
143
+
144
+ rowsCount : 0,
145
+
146
+ add : function(templateData, insertAfterId)
147
+ {
148
+ this.mustBeRefreshed = false;
149
+ if (emailVisionFields.length == 0) {
150
+ // if we don't have any emailvision
151
+ return false;
152
+ }
153
+
154
+ var newTemplate = false;
155
+ if ('' == templateData) {
156
+ // if template data is empty, indicate this is a new template
157
+ newTemplate = true;
158
+
159
+ var d = new Date();
160
+ // generate default template data
161
+ var templateData = {
162
+ <?php foreach ($this->_columns as $columnName => $column):?>
163
+ <?php echo $columnName ?> : '',
164
+ <?php endforeach;?>
165
+ _id : '_' + d.getTime() + '_' + d.getMilliseconds()
166
+ };
167
+ }
168
+
169
+ // insert before last row
170
+ if ('' == insertAfterId) {
171
+ Element.insert($('addRow<?php echo $_htmlId ?>'), {before: this.template.evaluate(templateData)});
172
+ }
173
+ // insert after specified row
174
+ else {
175
+ Element.insert($(insertAfterId), {after: this.template.evaluate(templateData)});
176
+ }
177
+
178
+ <?php if ($this->_addAfter):?>
179
+ Event.observe('addAfterBtn' + templateData._id, 'click', this.add.bind(this, '', templateData._id));
180
+ <?php endif;?>
181
+
182
+ // Select is in second td in tr
183
+ this.emailvisionSelect = $(templateData._id).down().next().down();
184
+
185
+ for(var ii = 0; ii < usedEmailVisionFields.length; ii++) {
186
+ // get option corresponding to a used value
187
+ this.optionSelected = this.emailvisionSelect.select('option:[value="'+ usedEmailVisionFields[ii] +'"]').first();
188
+
189
+ if (this.optionSelected && this.optionSelected.value == usedEmailVisionFields[ii]) {
190
+ if (newTemplate) {
191
+ this.optionSelected.remove();
192
+ }
193
+ this.mustBeRefreshed = true;
194
+ }
195
+ }
196
+ // Push and remove used and not used options
197
+ emailVisionFields.remove(this.emailvisionSelect.value);
198
+ usedEmailVisionFields.push(this.emailvisionSelect.value);
199
+
200
+ this.emailvisionSelect.observe('focus', function () {
201
+ previous = this.value;
202
+ }).observe('change', function() {
203
+ usedEmailVisionFields.remove(previous);
204
+ usedEmailVisionFields.push(this.value);
205
+ emailVisionFields.remove(this.value);
206
+ emailVisionFields.push(previous);
207
+ updateOptions();
208
+ });
209
+
210
+ if (this.mustBeRefreshed == true) {
211
+ updateOptions();
212
+ }
213
+
214
+ this.rowsCount += 1;
215
+ },
216
+
217
+ del : function(rowId)
218
+ {
219
+ var selectedValue = $(rowId).select('select.emailvision_select').first().value;
220
+
221
+ // Push and remove used and not used options
222
+ emailVisionFields.push(selectedValue);
223
+ usedEmailVisionFields.remove(selectedValue);
224
+
225
+ $(rowId).remove();
226
+ this.rowsCount -= 1;
227
+ if (0 == this.rowsCount) {
228
+ this.showButtonOnly();
229
+ }
230
+ updateOptions();
231
+ },
232
+
233
+ showButtonOnly : function()
234
+ {
235
+ $('grid<?php echo $_htmlId ?>').hide();
236
+ $('empty<?php echo $_htmlId ?>').show();
237
+ }
238
+ }
239
+
240
+ // bind add action to "Add" button in last row
241
+ Event.observe('addToEndBtn<?php echo $_htmlId ?>', 'click', arrayRow<?php echo $_htmlId ?>.add.bind(arrayRow<?php echo $_htmlId ?>, '', ''));
242
+ // add existing rows
243
+ <?php
244
+ $_addAfterId = "headings{$_htmlId}";
245
+ foreach ($this->getArrayRows() as $_rowId => $_row) {
246
+ echo "arrayRow{$_htmlId}.add(" . $_row->toJson() . ", '{$_addAfterId}');\n";
247
+ $_addAfterId = $_rowId;
248
+ }
249
+ ?>
250
+
251
+ // initialize standalone button
252
+ $('empty<?php echo $_htmlId ?>').hide();
253
+ Event.observe('emptyAddBtn<?php echo $_htmlId ?>', 'click', function () {
254
+ $('grid<?php echo $_htmlId ?>').show();
255
+ $('empty<?php echo $_htmlId ?>').hide();
256
+ arrayRow<?php echo $_htmlId ?>.add('', '');
257
+ });
258
+
259
+ // if no rows, hide grid and show button only
260
+ <?php if (!$this->getArrayRows()):?>
261
+ arrayRow<?php echo $_htmlId ?>.showButtonOnly();
262
+ <?php endif;?>
263
+
264
+ // toggle the grid, if element is disabled (depending on scope)
265
+ <?php if ($this->getElement()->getDisabled()):?>
266
+ toggleValueElements({checked:true}, $('grid<?php echo $_htmlId ?>').parentNode);
267
+ <?php endif;?>
268
+ //]]>
269
+ </script>
app/design/adminhtml/default/default/template/emailvision/datasync/system/config/getfields.phtml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @category Auguria
4
+ * @package Auguria_EmailVision
5
+ * @author Auguria
6
+ * @license http://opensource.org/licenses/gpl-3.0.html GNU General Public License version 3 (GPLv3)
7
+ *
8
+ * EmailVision getFields button to call the concerned controller action
9
+ */
10
+ ?>
11
+ <a href="<?php echo Mage::getSingleton('adminhtml/url')->getUrl('emv_datasync/dataSync/getMemberFields');?>">
12
+ <button class="scalable" type="button">
13
+ <span id="validation_result"><?php echo $this->__('Get SmartFocus member fields') ?></span>
14
+ </button>
15
+ </a>
app/design/adminhtml/default/default/template/emailvision/emt/template/common_js.phtml ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ // this block handles all javascript treatments for SmartFocus templates
3
+ ?>
4
+ <script type="text/javascript">
5
+ var classNameEmvTemplateSelect = '';
6
+
7
+ // handle the way of displaying form according to send mode
8
+ function hideField(mailMode)
9
+ {
10
+ if (
11
+ mailMode == '<?php echo Emv_Emt_Model_Mailmode::CLASSIC_MODE ?>'
12
+ || mailMode == '<?php echo Emv_Emt_Model_Mailmode::EMV_SEND ?>'
13
+ )
14
+ {
15
+ $("emv_template_id").parentNode.parentNode.style.display = "none";
16
+ $("emv_template_id").className = '';
17
+ $("to_date").parentNode.parentNode.style.display = "none";
18
+ $("from_date").parentNode.parentNode.style.display = "none";
19
+ $("get_emv_templates").parentNode.parentNode.style.display = "none";
20
+
21
+ $$('#attributes_EMV_DYN tbody').first().innerHTML = '';
22
+ $$('#attributes_EMV_CONTENT tbody').first().innerHTML = '';
23
+ } else {
24
+ if (mailMode == '<?php echo Emv_Emt_Model_Mailmode::EMV_CREATE ?>') {
25
+ $("emtTemplateButtonContainer").style.display = "";
26
+ $("emv_template_id").parentNode.parentNode.style.display = "";
27
+ $("emv_template_id").className = classNameEmvTemplateSelect;
28
+ $("get_emv_templates").parentNode.parentNode.style.display = "";
29
+ $("to_date").style.display = "";
30
+ $("from_date").style.display = "";
31
+ $("to_date").parentNode.parentNode.style.display = "";
32
+ $("from_date").parentNode.parentNode.style.display = "";
33
+ }
34
+ }
35
+ }
36
+
37
+ // try to track the send mail mode modification
38
+ var sendModeSelect = $('emv_send_mail_mode_id');
39
+ if (sendModeSelect) {
40
+ Event.observe(window, 'load', function() {
41
+ // get initial class name for emv_template_id select
42
+ classNameEmvTemplateSelect = $("emv_template_id").className;
43
+
44
+ var sendModeValue = sendModeSelect.options[sendModeSelect.selectedIndex].value;
45
+ hideField(sendModeValue);
46
+
47
+ Event.observe(sendModeSelect, 'change', function(event) {
48
+ if (confirm('<?php echo Mage::helper('emvemt')->__('Are you sure to change the sending mode ? All your mapped attributes will be deleted !')?>')) {
49
+ sendModeValue = this.options[this.selectedIndex].value;
50
+ hideField(sendModeValue);
51
+ } else {
52
+ sendModeSelect.value = sendModeValue;
53
+ }
54
+ });
55
+ });
56
+ }
57
+ </script>
58
+
59
+ <script type="text/javascript">
60
+ Emv = {};
61
+ Emv.BuildSelectOptions = Class.create();
62
+ Emv.BuildSelectOptions.prototype = {
63
+ initialize : function()
64
+ {
65
+ this.loading = false;
66
+ this.loader = new varienLoader(false);
67
+ this.elementId = '';
68
+ },
69
+ load : function (elementId, urlToLoad, params, forced) {
70
+ if ($(elementId) && this.loading == false || forced) {
71
+ this.loading = true;
72
+
73
+ if ($('messages')) {
74
+ // remove all existing messages
75
+ $('messages').innerHTML = '';
76
+ }
77
+ this.elementId = elementId;
78
+ this.loader.load(urlToLoad, params, this.proceedMessageReturn.bind(this));
79
+ }
80
+ },
81
+ proceedMessageReturn : function(serverResponse) {
82
+ this.loading = false;
83
+
84
+ if (serverResponse) {
85
+ // evaluate the server response in JSON format
86
+ data = eval('(' + serverResponse + ')');
87
+ if (typeof(data) != 'undefined') {
88
+ if (typeof(data.html) == 'object') {
89
+ for (elementId in data.html) {
90
+ var element = $(elementId);
91
+ if (element) {
92
+ element.innerHTML = data.html[elementId];
93
+ }
94
+ }
95
+ if (typeof(data.error_messages) != 'undefined' && data.error_messages) {
96
+ if ($('messages')) {
97
+ $('messages').innerHTML = '<ul class="messages"><li class="error-msg"><ul><li>'
98
+ + data.error_messages + '</li></ul></li></ul>';
99
+ }
100
+ }
101
+ }
102
+
103
+ if (this.elementId) {
104
+ this.hideAndRemoveMessage();
105
+ $(this.elementId).update('');
106
+
107
+ if (typeof(data.error) == 'string' && data.error != '') {
108
+ this.prepareErrorMessage(data.error);
109
+ } else if(typeof(data.error) == 'boolean' && data.error && typeof(data.message) == 'string' && data.message != '') {
110
+ this.prepareErrorMessage(data.message);
111
+ }
112
+
113
+ if (typeof(data.options) == 'object' && data.options.length >= 1) {
114
+ for (var i = 0; i < data.options.length; i++) {
115
+ var opt = document.createElement('option');
116
+ opt.text = data.options[i].label;
117
+ opt.value = data.options[i].value;
118
+ $(this.elementId).options.add(opt);
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
124
+ },
125
+ hideAndRemoveMessage : function()
126
+ {
127
+ var advices = $(this.elementId).parentNode.select('.validation-advice');
128
+ if (advices.length) {
129
+ advices.first().remove();
130
+ }
131
+ },
132
+ prepareErrorMessage : function(error)
133
+ {
134
+ $(this.elementId).parentNode.insert('<div class="validation-advice">' + error + '</div>');
135
+ }
136
+ }
137
+
138
+ buildSelectOption = new Emv.BuildSelectOptions();
139
+ </script>
140
+ <script type="text/javascript">
141
+ <!--
142
+ var lastEmvTemplate = '';
143
+
144
+ // function to get all SmartFocus attributes and refresh them
145
+ function getEmvAttribute() {
146
+ if (
147
+ $('emv_send_mail_mode_id').value == '<?php echo Emv_Emt_Model_Mailmode::EMV_CREATE ?>'
148
+ && $('emv_template_id').value
149
+ ) {
150
+ if (confirm('<?php echo Mage::helper('emvemt')->__('Are you sure to refresh all your mapped SmartFocus Attributes ?') ?>')) {
151
+ var params = {
152
+ account_id : $('emv_account_id').value,
153
+ emv_template_id : $('emv_template_id').value ,
154
+ id : $('id').value
155
+ }
156
+
157
+ lastEmvTemplate = emvTemplateSelect.value;
158
+ buildSelectOption.load(
159
+ '',
160
+ '<?php echo $this->getUrl('*/*/getEmvAttributesAjax'); ?>',
161
+ params,
162
+ true
163
+ );
164
+ } else {
165
+ emvTemplateSelect.value = lastEmvTemplate;
166
+ }
167
+ }
168
+ }
169
+
170
+ // track SmartFocus template changes
171
+ var emvTemplateSelect = $('emv_template_id');
172
+ if (emvTemplateSelect) {
173
+ Event.observe(emvTemplateSelect, 'change', function(event) {
174
+ getEmvAttribute();
175
+ });
176
+ }
177
+
178
+ // SmartFocus account handler
179
+ var mageTemplateUrl = '<?php echo $this->getUrl('*/*/getNotMappedMagentoTemplateSelectAjax'); ?>';
180
+ var accountSelect = $('emv_account_id');
181
+ if (accountSelect) {
182
+ Event.observe(accountSelect, 'change', function(event) {
183
+ var params = {
184
+ account_id : accountSelect.value
185
+ };
186
+ buildSelectOption.load('mage_template_id', mageTemplateUrl, params);
187
+ });
188
+ }
189
+
190
+ // get_emv_templates handler
191
+ var emvTemplateUrl = '<?php echo $this->getUrl('*/*/getEmvTemplateSelectAjax'); ?>';
192
+ var button = $('get_emv_templates');
193
+ if (button) {
194
+ Event.observe(button, 'click', function(event) {
195
+ var params = {
196
+ account_id : $('emv_account_id').value,
197
+ from: $('from_date').value ,
198
+ to :$('to_date').value
199
+ };
200
+ buildSelectOption.load('emv_template_id', emvTemplateUrl, params);
201
+ });
202
+ }
203
+ //-->
204
+ </script>
205
+
206
+ <script type="text/javascript">
207
+ <!--
208
+ // insert Magento variables
209
+ var variableLoader = new varienLoader(true);
210
+ var lastMageAttrId = '';
211
+ function setLastMageAttrId(id){
212
+ lastMageAttrId = id;
213
+ }
214
+ var variableRetreiveUrl = '<?php echo $this->getUrl('*/*/getVariablesForMageTemplate'); ?>';
215
+ function openVariableChooser()
216
+ {
217
+ if (lastMageAttrId && $(lastMageAttrId)) {
218
+ var params = {
219
+ mage_template_id : $('mage_template_id').value
220
+ }
221
+ variableLoader.load(variableRetreiveUrl, params, function(serverResponse){
222
+ var data = eval('(' + serverResponse + ')');
223
+ if (typeof(data.variables) == 'object') {
224
+ Variables.init(lastMageAttrId);
225
+ Variables.resetData();
226
+ Variables.openVariableChooser(data.variables);
227
+ }
228
+ });
229
+ }
230
+ }
231
+ //-->
232
+ </script>
233
+
234
+ <script type="text/javascript">
235
+ <!--
236
+ var templatePreviewForm;
237
+ Event.observe(window, 'load', function() {
238
+ templatePreviewForm = new varienForm('emv_template_preview_form');
239
+ });
240
+ function openPreview() {
241
+ $('preview_emv_account_id').value = $('emv_account_id').value;
242
+ $('preview_emv_template_id').value = $('emv_template_id').value;
243
+ $('preview_emv_send_mail_mode_id').value = $('emv_send_mail_mode_id').value;
244
+ $('preview_mage_template_id').value = $('mage_template_id').value;
245
+
246
+ var contentInput = '';
247
+ $$('#attributes_EMV_CONTENT tr, #attributes_EMV_DYN tr').each(function(element){
248
+ $(element).select('input,textarea').each(function(inputElm){
249
+ contentInput += '<input type="hidden"' + ' name="'+ inputElm.name +'"' + ' value="' + inputElm.value + '"'
250
+ + '/>' ;
251
+ });
252
+ })
253
+ $('preview-attribute-value').innerHTML = contentInput;
254
+
255
+ templatePreviewForm.submit();
256
+ return false;
257
+ }
258
+
259
+ //-->
260
+ </script>
app/design/adminhtml/default/default/template/emailvision/emt/template/edit.phtml ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php // buttons ?>
2
+ <div class="content-header">
3
+ <h3 class="icon-head head-products"><?php echo $this->getHeader() ?></h3>
4
+ <p class="content-buttons form-buttons"><?php echo $this->getBackButtonHtml() ?>
5
+
6
+ <?php echo $this->getCancelButtonHtml() ?>
7
+
8
+ <?php if ($this->getEmt()->getId()) :?>
9
+ <?php echo $this->getPreviewButtonHtml()?>
10
+ <?php echo $this->getEmvAttributeButtonHtml()?>
11
+ <?php echo $this->getInsertMageVariableButtonHtml()?>
12
+
13
+ <?php echo $this->getDeleteButtonHtml() ?>
14
+ <?php echo $this->getSaveAndEditButtonHtml() ?>
15
+ <?php endif; ?>
16
+ </p>
17
+ </div>
18
+
19
+ <form action="<?php echo $this->getPreviewUrl() ?>" method="post" id="emv_template_preview_form" target="_blank" >
20
+ <?php echo $this->getBlockHtml('formkey')?>
21
+ <div class="no-display">
22
+ <input type="hidden" id="preview_mage_template_id" name="mage_template_id" value="" />
23
+ <input type="hidden" id="preview_emv_send_mail_mode_id" name="emv_send_mail_mode_id" value="" />
24
+ <input type="hidden" id="preview_emv_template_id" name="emv_template_id" value="" />
25
+ <input type="hidden" id="preview_emv_account_id" name="emv_account_id" value="" />
26
+ <div id="preview-attribute-value"></div>
27
+ </div>
28
+ </form>
29
+
30
+ <?php // form place holder ?>
31
+ <form action="<?php echo $this->getSaveUrl() ?>" method="post" id="emv_template_edit_form" enctype="multipart/form-data">
32
+ <div style="display:none"></div>
33
+ <?php echo $this->getBlockHtml('formkey')?>
34
+ </form>
35
+
36
+
37
+
38
+ <script type="text/javascript">
39
+ //<![CDATA[
40
+ var campaignCommanderTemplateSyntax = /(^|.|\r|\n)({{(\w+)}})/;
41
+ var editForm = new varienForm('emv_template_edit_form', '');
42
+
43
+ function saveAndContinueEdit(urlTemplate) {
44
+ var template = new Template(urlTemplate, campaignCommanderTemplateSyntax);
45
+ var url = template.evaluate({tab_id:emv_template_tabsJsTabs.activeTab.id});
46
+ editForm.submit(url);
47
+ }
48
+ //]]>
49
+ </script>
app/design/adminhtml/default/default/template/emailvision/emt/template/mapped_attributes.phtml ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* @var Emv_Emt_Block_Adminhtml_Template_Edit_Tab_EmvDyn */
3
+ $this->prepareAttributes();
4
+ $availableAttributes = $this->getAvailableAttributes();
5
+ $invalidAttributes = $this->getInvalidAttributes();
6
+ ?>
7
+
8
+ <div class="entry-edit custom-options product-custom-options" id="<?php echo $this->getDivContentId() ?>">
9
+ <div class="entry-edit-head">
10
+ <h4><?php echo Mage::helper('emvemt')->__('Configuration') ?></h4>
11
+ </div>
12
+ <div class="box">
13
+
14
+ <?php // Available attribute block ?>
15
+ <div class="grid option-box emv_attributes">
16
+ <div class="content-header">
17
+ <h3><?php echo Mage::helper('emvemt')->__('Available Attributes') ?></h3>
18
+ </div>
19
+ <div class="hor-scroll">
20
+ <table cellspacing="0" id="<?php echo $this->getAttributesTableId() ?>" class="data">
21
+ <colgroup>
22
+ <col width="100">
23
+ <col width="">
24
+ </colgroup>
25
+ <thead>
26
+ <tr class="headings">
27
+ <th class="a-center va-middle"><?php echo Mage::helper('emvemt')->__('SmartFocus Attribute')?></th>
28
+ <th class="a-center va-middle"><?php echo Mage::helper('emvemt')->__('Personalized Content')?></th>
29
+ </tr>
30
+ </thead>
31
+ <tbody>
32
+ <?php foreach($availableAttributes as $attribute ) :?>
33
+ <?php
34
+ $index = $this->getNewIndexForAttributes();
35
+ $className = 'even';
36
+ if ($index%2) {
37
+ $className = 'odd';
38
+ }
39
+ if (isset($attribute['invalid']) && $attribute['invalid'] == true) {
40
+ $className .= ' invalid';
41
+ }
42
+ ?>
43
+ <tr class="<?php echo $className ?>">
44
+ <td class="a-center va-middle">
45
+ <?php echo $attribute['emv_attribute'];?>
46
+ </td>
47
+ <td class="a-center va-middle last">
48
+ <textarea
49
+ name="attributes[<?php echo $index;?>][mage_attribute]"
50
+ id="emv_attribute_<?php echo $index;?>_mage_attribute"
51
+ rows="<?php echo $this->getTextareaRows()?>"
52
+ onfocus="setLastMageAttrId('emv_attribute_<?php echo $index;?>_mage_attribute');"
53
+ ><?php
54
+ echo Mage::helper('core')->escapeHtml($attribute['mage_attribute'])
55
+ ?></textarea>
56
+
57
+ <input type="hidden" value="<?php echo $attribute['emv_attribute_type']?>"
58
+ name="attributes[<?php echo $index;?>][emv_attribute_type]"
59
+ />
60
+ <input type="hidden" value="<?php echo (isset($attribute['id'])) ? $attribute['id'] : ''?>"
61
+ name="attributes[<?php echo $index;?>][id]"
62
+ />
63
+ <input type="hidden" name="attributes[<?php echo $index;?>][delete]" value="" class="delete"/>
64
+ <input type="hidden" name="attributes[<?php echo $index;?>][emv_attribute]"
65
+ value="<?php echo $attribute['emv_attribute'] ?>"
66
+ />
67
+ </td>
68
+ </tr>
69
+ <?php endforeach;?>
70
+ </tbody>
71
+ </table>
72
+ </div>
73
+ </div>
74
+
75
+ <?php if (count($invalidAttributes)) :?>
76
+ <?php // Invalid attribute block - all invalid attributes will be deleted after ?>
77
+ <div class="grid option-box emv_attributes">
78
+ <div class="content-header">
79
+ <h3><?php echo Mage::helper('emvemt')->__('Invalid Attributes (from the last save)') ?></h3>
80
+ </div>
81
+ <div class="hor-scroll">
82
+ <table cellspacing="0" id="<?php echo $this->getInvalidAttributeTableId() ?>" class="data">
83
+ <colgroup>
84
+ <col width="100">
85
+ <col width="">
86
+ </colgroup>
87
+ <thead>
88
+ <tr class="headings">
89
+ <th class="a-center va-middle"><?php echo Mage::helper('emvemt')->__('SmartFocus Attribute')?></th>
90
+ <th class="a-center va-middle"><?php echo Mage::helper('emvemt')->__('Personalized Content')?></th>
91
+ </tr>
92
+ </thead>
93
+ <tbody>
94
+ <?php foreach($invalidAttributes as $attribute ) :?>
95
+ <?php
96
+ $index = $this->getNewIndexForAttributes();
97
+ $className = 'even';
98
+ if ($index%2) {
99
+ $className = 'odd';
100
+ }
101
+ if (isset($attribute['invalid']) && $attribute['invalid'] == true) {
102
+ $className .= ' invalid';
103
+ }
104
+ ?>
105
+ <tr class="<?php echo $className ?>">
106
+ <td class="a-center va-middle">
107
+ <?php echo $attribute['emv_attribute'];?>
108
+ </td>
109
+ <td class="a-center va-middle last">
110
+ <textarea
111
+ name="attributes[<?php echo $index;?>][mage_attribute]"
112
+ id="emv_attribute_<?php echo $index;?>_mage_attribute"
113
+ rows="<?php echo $this->getTextareaRows()?>"
114
+ disabled="disabled"
115
+ ><?php
116
+ echo Mage::helper('core')->escapeHtml($attribute['mage_attribute'])
117
+ ?></textarea>
118
+
119
+ <input type="hidden" value="<?php echo $attribute['emv_attribute_type']?>"
120
+ name="attributes[<?php echo $index;?>][emv_attribute_type]"
121
+ />
122
+ <input type="hidden" value="<?php echo (isset($attribute['id'])) ? $attribute['id'] : ''?>"
123
+ name="attributes[<?php echo $index;?>][id]"
124
+ />
125
+ <input type="hidden" name="attributes[<?php echo $index;?>][delete]" value="1" class="delete"/>
126
+ <input type="hidden" name="attributes[<?php echo $index;?>][emv_attribute]"
127
+ value="<?php echo $attribute['emv_attribute'] ?>"
128
+ />
129
+ </td>
130
+ </tr>
131
+ <?php endforeach; ?>
132
+ </tbody>
133
+ </table>
134
+ </div>
135
+ </div>
136
+ <?php endif; // end invalid attributes if ?>
137
+ </div>
138
+ </div>
app/design/adminhtml/default/default/template/emt/attributes.phtml DELETED
@@ -1,142 +0,0 @@
1
- <script type="text/javascript">
2
-
3
- Emv = {};
4
- Emv.Attribute = Class.create();
5
- Emv.Attribute.prototype = {
6
- idLabel : '<?php echo $this->getFieldId() ?>',
7
- top : '',
8
- templateSyntax : /(^|.|\r|\n)({{(\w+)}})/,
9
- templateText : '',
10
- templateEmvContentText : '',
11
- itemsCount : 0,
12
- initialize : function(template, templateEmvContent) {
13
- this.templateText = template;
14
- this.templateEmvContentText = templateEmvContent;
15
- this.top = $('emv_attribute_top');
16
- },
17
-
18
- addEmvDyn : function(data)
19
- {
20
- if(!data){
21
- data = {};
22
- }
23
- data.emv_attribute_type = '<?php echo Emv_Emt_Constants::ATTRIBUTE_TYPE_EMV_DYN; ?>';
24
- this.add(data);
25
- },
26
-
27
- addEmvContent : function(data)
28
- {
29
- if(!data){
30
- data = {};
31
- }
32
- data.emv_attribute_type = '<?php echo Emv_Emt_Constants::ATTRIBUTE_TYPE_EMV_CONTENT; ?>';
33
- this.add(data);
34
- },
35
-
36
- add : function(data) {
37
-
38
- if($('emv_template_id').value == null)
39
- {
40
- alert('<?php echo Mage::helper('emvemt')->__('Please select a campaign commander template')?>');
41
- return;
42
- }
43
-
44
- if(!data){
45
- data = {};
46
- }
47
- this.top = $('emv_attribute_top');
48
-
49
- data.index = this.itemsCount++;
50
-
51
- if(data.emv_attribute_type == '<?php echo Emv_Emt_Constants::ATTRIBUTE_TYPE_EMV_CONTENT; ?>')
52
- {
53
- this.template = new Template(this.templateEmvContentText, this.templateSyntax);
54
- }
55
- else
56
- {
57
- this.template = new Template(this.templateText, this.templateSyntax);
58
- }
59
- Element.insert(this.top, {'after':this.template.evaluate(data)});
60
- this.top = $(this.idLabel + '_' + data.index);
61
-
62
- var url = '<?php echo $this->getUrl('emvemt/emt/getEmvAttributesSelectAjax'); ?>';
63
- new Ajax.Updater('emv_attributes_col_'+data.index, url, {parameters:
64
- { accountId : $('emv_account_id').value,
65
- emvTemplateId: $('emv_template_id').value ,
66
- emv_attribute_type: data.emv_attribute_type ,
67
- index : data.index,
68
- default_value : data.emv_attribute
69
- },
70
- method: 'post'});
71
-
72
- //set selected type
73
- if (data.mage_attribute) {
74
- $(this.idLabel + '_'+data.index+'_mage_attribute').value = data.mage_attribute;
75
- }
76
-
77
- return data.index;
78
- },
79
-
80
- remove : function(event){
81
- var element = $(Event.findElement(event, 'div'));
82
- if(element){
83
- Element.select(element, '.delete').each(function(elem){elem.value='1'});
84
- Element.select(element, ['input', 'select']).each(function(elem){elem.hide(); elem.className = '';});
85
- Element.hide(element);
86
- }
87
- }
88
- }
89
-
90
- var attributesSelectBeginTemplate = '<div id="<?php echo $this->getFieldId() ?>_{{index}}" class="option-box"> ' +
91
- '<table class="option-header" style="width:auto;" cellpadding="0" cellspacing="0">' +
92
- '<thead>' +
93
- '<tr>' +
94
- '<th>&nbsp;</th>' +
95
- '<th class="opt-type"><?php echo Mage::helper('emvemt')->__('Attribute') ?></th>' +
96
- '<th class="opt-req"><?php echo Mage::helper('emvemt')->__('Campaign Commander Attribute') ?></th>' +
97
- '</tr>' +
98
- '</thead>' +
99
- '<tbody>' +
100
- '<tr>' +
101
- '<td>&nbsp;<?php echo $this->getDeleteButtonHtml() ?></td>' +
102
- '<td><?php echo $this->getMageAttributesInputHtml() ?>' +
103
- '<input type="hidden" name="<?php echo $this->getFieldName() ?>[{{index}}][delete]" value="" class="delete">';
104
-
105
- var attributesSelectEndTemplate = '</td>' +
106
- '<td id="emv_attributes_col_{{index}}"></td>' +
107
- '</tr>' +
108
- '</tbody>' +
109
- '</table>' +
110
- '</div>';
111
-
112
- var attributesSelectTemplate = attributesSelectBeginTemplate +
113
- '<input type="hidden" name="<?php echo $this->getFieldName() ?>[{{index}}][emv_attribute_type]" value="<?php echo Emv_Emt_Constants::ATTRIBUTE_TYPE_EMV_DYN; ?>">' +
114
- attributesSelectEndTemplate;
115
-
116
- var attributesEmvContentSelectTemplate = attributesSelectBeginTemplate +
117
- '<input type="hidden" name="<?php echo $this->getFieldName() ?>[{{index}}][emv_attribute_type]" value="<?php echo Emv_Emt_Constants::ATTRIBUTE_TYPE_EMV_CONTENT; ?>">' +
118
- attributesSelectEndTemplate;
119
-
120
- var selectEmvAttributes = '';
121
- var optionIndex = 0;
122
- emvAttribute = new Emv.Attribute(attributesSelectTemplate, attributesEmvContentSelectTemplate);
123
- </script>
124
-
125
- <div class="entry-edit custom-options bundle" id="emv_attributes_container">
126
- <div class="entry-edit-head">
127
- <h4><?php echo $this->__('Attributes') ?></h4>
128
- <div class="right"><?php echo $this->getAddButtonHtml() ?> &nbsp; <?php echo $this->getAddEmvContentButtonHtml() ?></div>
129
- </div>
130
-
131
- <div id="emv_attribute" class="box">
132
- <div id="emv_attribute_top"></div>
133
- </div>
134
- </div>
135
-
136
- <?php if($attributes = $this->getAttributesData()): ?>
137
- <script type="text/javascript">
138
- <?php foreach ($attributes as $data): ?>
139
- emvAttribute.add(<?php echo $this->_toJson($data) ?>);
140
- <?php endforeach; ?>
141
- </script>
142
- <?php endif; ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/{default/default/layout → base/default/layout/emailvision}/abandonment.xml RENAMED
@@ -17,7 +17,7 @@ Customer account home dashboard layout
17
  <abandonment_customer_manage>
18
  <update handle="customer_account"/>
19
  <reference name="my.account.wrapper">
20
- <block type="abandonment/customer_abandonment" name="customer_abandonment" as="info1" template="abandonment/customer.phtml"/>
21
  </reference>
22
  </abandonment_customer_manage>
23
  </layout>
17
  <abandonment_customer_manage>
18
  <update handle="customer_account"/>
19
  <reference name="my.account.wrapper">
20
+ <block type="abandonment/customer_abandonment" name="customer_abandonment" as="info1" template="emailvision/abandonment/customer.phtml"/>
21
  </reference>
22
  </abandonment_customer_manage>
23
  </layout>
app/design/frontend/{default/default/template → base/default/template/emailvision}/abandonment/customer.phtml RENAMED
File without changes
app/design/frontend/{emv/template → base/default/template/emailvision}/abandonment/reminder/items.phtml RENAMED
@@ -1,9 +1,12 @@
1
- <?php $cart = $this->getCart() ?>
2
- <?php $items = $cart->getItems() ?>
 
 
 
3
  <table width="680" border="0" align="left" cellpadding="0" cellspacing="0">
4
  <tbody>
5
- <?php for($i=0; $i < count($items); $i++): ?>
6
- <?php $item = $items[$i]; ?>
7
  <tr>
8
  <td align="center">
9
  <table width="680"
@@ -17,20 +20,20 @@
17
  <tr>
18
  <td width="85">
19
  <a
20
- href="<?php echo $item->getUrl() ?>"
21
  title="Checkout Now" target="_blank">
22
  <img
23
- alt="<?php echo htmlentities($item->getName()) ?>"
24
  border="0" style="display: block;"
25
- src="<?php echo $item->getImage() ?>"
26
  width="85" />
27
  </a>
28
  </td>
29
  <td width="8">&nbsp;</td>
30
  <td><a
31
- href="<?php echo $item->getUrl() ?>"
32
- title="<?php echo htmlentities($item->getName()) ?>"><font
33
- color="#000000"> <strong><?php echo htmlentities($item->getName()) ?></strong>
34
  </font>
35
  </a>
36
  </td>
@@ -38,14 +41,14 @@
38
  </tbody>
39
  </table>
40
  </td>
41
- <td width="80" height="25" align="center">$<?php echo number_format($item->getBasePrice(), 2) ?></td>
42
- <td width="59" height="25" align="center"><?php echo floor($item->getQuantity()) ?></td>
43
- <td width="80" height="25" align="center">$<?php echo number_format($item->getTotalPrice(), 2) ?></td>
44
  </tr>
45
  </tbody>
46
  </table>
47
  </td>
48
  </tr>
49
- <?php endfor; ?>
50
  </tbody>
51
  </table>
1
+ <?php
2
+ /*@var $cart Mage_Sales_Model_Quote */
3
+ $cart = $this->getCart();
4
+ ?>
5
+
6
  <table width="680" border="0" align="left" cellpadding="0" cellspacing="0">
7
  <tbody>
8
+ <?php foreach ($cart->getAllVisibleItems() as $item): ?>
9
+ <?php $itemLink = Mage::helper('abandonment')->getItemLink($cart, $cart->getReminderTemplate(), $item->getProductId());?>
10
  <tr>
11
  <td align="center">
12
  <table width="680"
20
  <tr>
21
  <td width="85">
22
  <a
23
+ href="<?php echo $itemLink?>"
24
  title="Checkout Now" target="_blank">
25
  <img
26
+ alt="<?php echo $this->escapeHtml($item->getName()) ?>"
27
  border="0" style="display: block;"
28
+ src="<?php echo Mage::helper('abandonment')->getProductImageUrl($item->getProductId()) ?>"
29
  width="85" />
30
  </a>
31
  </td>
32
  <td width="8">&nbsp;</td>
33
  <td><a
34
+ href="<?php echo $itemLink ?>"
35
+ title="<?php echo $this->escapeHtml($item->getName()) ?>"><font
36
+ color="#000000"> <strong><?php echo $this->escapeHtml($item->getName()) ?></strong>
37
  </font>
38
  </a>
39
  </td>
41
  </tbody>
42
  </table>
43
  </td>
44
+ <td width="80" height="25" align="center"><?php echo Mage::helper('checkout')->formatPrice($item->getBasePrice(), true, true) ?></td>
45
+ <td width="59" height="25" align="center"><?php echo floor($item->getQty()) ?></td>
46
+ <td width="80" height="25" align="center"><?php echo Mage::helper('checkout')->formatPrice($item->getBaseRowTotal(), true, true)?></td>
47
  </tr>
48
  </tbody>
49
  </table>
50
  </td>
51
  </tr>
52
+ <?php endforeach; ?>
53
  </tbody>
54
  </table>
app/design/frontend/enterprise/default/layout/abandonment.xml DELETED
@@ -1,23 +0,0 @@
1
- <?xml version="1.0"?>
2
- <layout version="0.1.0">
3
- <!--
4
- Category layered navigation layout
5
- -->
6
-
7
- <customer_account>
8
- <reference name="customer_account_navigation">
9
- <action method="addLink" translate="label" module="abandonment"><name>abandonment</name><path>abandonment/customer/manage</path><label>Cart Reminder Subscriptions</label></action>
10
- </reference>
11
- <remove name="left.abandonment" />
12
- </customer_account>
13
-
14
- <!--
15
- Customer account home dashboard layout
16
- -->
17
- <abandonment_customer_manage>
18
- <update handle="customer_account" />
19
- <reference name="my.account.wrapper">
20
- <block type="abandonment/customer_abandonment" name="customer_abandonment" as="info1" template="abandonment/customer.phtml"/>
21
- </reference>
22
- </abandonment_customer_manage>
23
- </layout>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/design/frontend/enterprise/default/template/abandonment/customer.phtml DELETED
@@ -1,23 +0,0 @@
1
- <div class="page-title">
2
- <h1><?php echo $this->__('Cart Reminder Subscription') ?></h1>
3
- </div>
4
- <?php echo $this->getMessagesBlock()->getGroupedHtml() ?>
5
- <?php echo $this->getChildHtml('form_before')?>
6
- <form action="<?php echo $this->getAction() ?>" method="post" id="form-validate">
7
- <div class="fieldset">
8
- <?php echo $this->getBlockHtml('formkey')?>
9
- <h2 class="legend"><?php echo $this->__('Cart Reminder Subscription') ?></h2>
10
- <ul class="form-list">
11
- <li class="control"><input type="checkbox" name="is_subscribed" id="subscription" value="1" title="<?php echo $this->__('Cart Reminder Email Subscription') ?>"<?php if($this->getIsSubscribed()): ?> checked="checked"<?php endif; ?> class="checkbox" /><label for="subscription"><?php echo $this->__('Cart Reminder Email Subscription') ?></label></li>
12
- </ul>
13
- </div>
14
- <div class="buttons-set">
15
- <p class="back-link"><a href="<?php echo $this->escapeUrl($this->getBackUrl()) ?>"><small>&laquo; </small><?php echo $this->__('Back') ?></a></p>
16
- <button type="submit" title="<?php echo $this->__('Save') ?>" class="button"><span><span><?php echo $this->__('Save') ?></span></span></button>
17
- </div>
18
- </form>
19
- <script type="text/javascript">
20
- //<![CDATA[
21
- var dataForm = new VarienForm('form-validate', true);
22
- //]]>
23
- </script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/etc/modules/Emv_DataSync.xml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <Emv_DataSync>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ <depends>
8
+ <Emv_Core />
9
+ </depends>
10
+ </Emv_DataSync>
11
+ </modules>
12
+ </config>
app/etc/modules/Emv_Report.xml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <Emv_Report>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ <depends>
8
+ <Emv_CartAlert />
9
+ </depends>
10
+ </Emv_Report>
11
+ </modules>
12
+ </config>
app/locale/en_US/Emv_CartAlert.csv CHANGED
@@ -6,12 +6,18 @@
6
  "An error occurred while saving your subscription.","An error occurred while saving your subscription."
7
  "The link cannot be used by registered customers.","The link cannot be used by registered customers."
8
  "The link is invalid.","The link is invalid."
9
- "Emailvision abandonment cart config","Emailvision abandonment cart config"
10
- "Emailvision section","Emailvision section"
11
- "Abandoned Cart 1","Abandoned Cart 1"
12
- "Abandoned Cart 2","Abandoned Cart 2"
13
- "Abandoned Cart 3","Abandoned Cart 3"
14
  "Abandonment Cart Alert","Abandonment Cart Alert"
 
 
 
 
 
 
 
 
 
 
15
  "First Alert Configuration","First Alert Configuration"
16
  "First Email Alert Enable","First Email Alert Enable"
17
  "First Email Alert Delay (in hour)","First Email Alert Delay (in hour)"
@@ -24,9 +30,10 @@
24
  "Third Email Alert Enable","Third Email Alert Enable"
25
  "Third Email Alert Delay (in hour)","Third Email Alert Delay (in hour)"
26
  "Third Email Alert Template","Third Email Alert Template"
27
- "Sender Identity","Sender Identity"
28
- "Email Sender","Email Sender"
29
- "Cart Reminder Subscription","Cart Reminder Subscription"
30
  "Cart Reminder Email Subscription","Cart Reminder Email Subscription"
31
  "Back","Back"
32
- "Save","Save"
 
 
 
 
6
  "An error occurred while saving your subscription.","An error occurred while saving your subscription."
7
  "The link cannot be used by registered customers.","The link cannot be used by registered customers."
8
  "The link is invalid.","The link is invalid."
9
+ "SmartFocus - Abandonment cart configs","SmartFocus - Abandonment cart configs"
 
 
 
 
10
  "Abandonment Cart Alert","Abandonment Cart Alert"
11
+ "Email Sender","Email Sender"
12
+ "Image Size","Image Size"
13
+ "Shopping Cart Prices Rule Id","Shopping Cart Prices Rule Id"
14
+ "Coupon Code Length","Coupon Code Length"
15
+ "Coupon Code Format","Coupon Code Format"
16
+ "Coupon Code Prefix","Coupon Code Prefix"
17
+ "Coupon Code Suffix","Coupon Code Suffix"
18
+ "Dash Every X Characters For Coupon Code","Dash Every X Characters For Coupon Code"
19
+ "If empty no separation.","If empty no separation."
20
+ "Excluding prefix, suffix and separators.","Excluding prefix, suffix and separators."
21
  "First Alert Configuration","First Alert Configuration"
22
  "First Email Alert Enable","First Email Alert Enable"
23
  "First Email Alert Delay (in hour)","First Email Alert Delay (in hour)"
30
  "Third Email Alert Enable","Third Email Alert Enable"
31
  "Third Email Alert Delay (in hour)","Third Email Alert Delay (in hour)"
32
  "Third Email Alert Template","Third Email Alert Template"
 
 
 
33
  "Cart Reminder Email Subscription","Cart Reminder Email Subscription"
34
  "Back","Back"
35
+ "Save","Save"
36
+ "Abandoned Cart 1","Abandoned Cart 1"
37
+ "Abandoned Cart 2","Abandoned Cart 2"
38
+ "Abandoned Cart 3","Abandoned Cart 3"
39
+ "General","General"
app/locale/en_US/Emv_Core.csv CHANGED
@@ -1,6 +1,4 @@
1
- "id","id"
2
- "No","No"
3
- "Yes","Yes"
4
  "Account Information","Account Information"
5
  "Account Name","Account Name"
6
  "API Information","API Information"
@@ -10,34 +8,53 @@
10
  "API Uses Proxy", "API Uses Proxy"
11
  "Proxy Host","Proxy Host"
12
  "Proxy Port","Proxy Port"
13
- "Configure Campaign Commander Account","Configure Campaign Commander Account"
 
 
 
 
 
14
  "Action","Action"
15
  "Edit","Edit"
16
- "Campaign Commander Accounts","Campaign Commander Accounts"
17
- "Campaign Commander account deleted.","Campaign Commander account deleted."
18
- "The Campaign Commander account has been saved.","The Campaign Commander account has been saved."
19
- "Account with the same name already exists.","Account with the same name already exists."
20
- "Account with the same login already exists.","Account with the same login already exists."
21
- "Account with the same API manager key already exists.","Account with the same API manager key already exists."
22
- "Proxy host and port are required.","Proxy host and port are required."
23
- "Campaign Commander Account","Campaign Commander Account"
24
- "Campaign Commander Section","Campaign Commander Section"
25
- "Edit Campaign Commander Account '%s'","Edit Campaign Commander Account '%s'"
26
- "New Campaign Commander Account","New Campaign Commander Account"
27
- "Proxy Information", "Proxy Information"
28
- "Account ID", "Account ID"
29
  "Edit Account","Edit Account"
 
30
  "Add New Account","Add New Account"
 
 
31
  "Unable to find an account to delete.","Unable to find an account to delete."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  "Name is required.","Name is required."
33
  "API login is required.","API login is required."
34
  "API password is required.","API password is required."
35
  "API Manager key is required.","API Manager key is required."
36
- "System","System"
37
- "This EMV account is invalid.","This Campaign Commander account is invalid."
38
- "Cound not connect to Campaign Commander WebService.","Cound not connect to Campaign Commander WebService."
39
- "--Please Select--","--Please Select--"
40
- "Transactional Service Adress","Transactional Service Adress"
41
- "Notification Service Adress","Notification Service Adress"
42
- "Campaign Commander Services","Campaign Commander Services"
43
- "Emailvision","Emailvision"
 
 
 
 
 
1
+ "Accounts","Accounts"
 
 
2
  "Account Information","Account Information"
3
  "Account Name","Account Name"
4
  "API Information","API Information"
8
  "API Uses Proxy", "API Uses Proxy"
9
  "Proxy Host","Proxy Host"
10
  "Proxy Port","Proxy Port"
11
+ "Associated Webservice Urls","Associated Webservice Urls"
12
+ "Available Webservices","Available Webservices"
13
+ "Edit SmartFocus Account '%s'","Edit SmartFocus Account '%s'"
14
+ "New SmartFocus Account","New SmartFocus Account"
15
+ "Account ID", "Account ID"
16
+ "SmartFocus Account","SmartFocus Account"
17
  "Action","Action"
18
  "Edit","Edit"
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  "Edit Account","Edit Account"
20
+ "SmartFocus Accounts","SmartFocus Accounts"
21
  "Add New Account","Add New Account"
22
+ "New Account","New Account"
23
+ "SmartFocus account deleted.","SmartFocus account deleted."
24
  "Unable to find an account to delete.","Unable to find an account to delete."
25
+ "The SmartFocus account has been saved.","The SmartFocus account has been saved."
26
+ "Your selected account does not exist anymore!","Your selected account does not exist anymore!"
27
+ "Could not verify the account. Network problems occured! Please Save again!","Could not verify the account. Network problems occured! Please Save again!"
28
+ "Your account ""%s"" is not allowed for %s !","Your account ""%s"" is not allowed for %s !"
29
+ "Please define a valid url for %s !","Please define a valid url for %s !"
30
+ "Could not enable ""%s"" process ! Please select an account in the list !","Could not enable ""%s"" process ! Please select an account in the list !"
31
+ "Please give a valid url for %s !","Please give a valid url for %s !"
32
+ "Network problems occured ! Please verify the service url or your network settings!","Network problems occured ! Please verify the service url or your network settings!"
33
+ "Your token has expired! Please retry your request again !","Your token has expired! Please retry your request again !"
34
+ "Your API credential is not valid ! Please correct it !","Your API credential is not valid ! Please correct it !"
35
+ "Your SmartFocus template is not found! Please select a new one!","Your SmartFocus template is not found! Please select a new one!"
36
+ "Unknown error with SmartFocus webservice","Unknown error with SmartFocus webservice"
37
+ "The given account does not have a valid url for Notification service","The given account does not have a valid url for Notification service"
38
+ "Can not create SmartFocus default sending template","Can not create SmartFocus default sending template"
39
+ "--Please Select--","--Please Select--"
40
+ "Transactional Service","Transactional Service"
41
+ "REST Notification Service","REST Notification Service"
42
+ "Batch Member Service","Batch Member Service"
43
+ "Member Service","Member Service"
44
  "Name is required.","Name is required."
45
  "API login is required.","API login is required."
46
  "API password is required.","API password is required."
47
  "API Manager key is required.","API Manager key is required."
48
+ "Account with the same name already exists.","Account with the same name already exists."
49
+ "Account with the same login already exists.","Account with the same login already exists."
50
+ "Account with the same API manager key already exists.","Account with the same API manager key already exists."
51
+ "Proxy host and port are required.","Proxy host and port are required."
52
+ "You need to enter at least one of the following service(s) : %s","You need to enter at least one of the following service(s) : %s"
53
+ "Connection problem. Could not check api credential, please try again","Connection problem. Could not check api credential, please try again"
54
+ "This SmartFocus account is invalid. Please check your API credential","This SmartFocus account is invalid. Please check your API credential"
55
+ "This SmartFocus account does not have any SmartFocus service url","This SmartFocus account does not have any SmartFocus service url"
56
+ "%s is unknown by SmartFocus platform.","%s is unknown by SmartFocus platform."
57
+ "Please enter a valid url for %s!","Please enter a valid url for %s!"
58
+ "Service","Service"
59
+ "Url","Url"
60
+ "Remove","Remove"
app/locale/en_US/Emv_DataSync.csv ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Please synchronize with SmartFocus webservice (see above)","Please synchronize with SmartFocus webservice (see above)"
2
+ "Not scheduled yet","Not scheduled yet"
3
+
4
+ "Please select an account for ""Triggered Exports"". Access to Member service is required","Please select an account for ""Triggered Exports"". Access to Member service is required"
5
+ "Retrieved successfully SmartFocus member fields","Retrieved successfully SmartFocus member fields"
6
+ "SmartFocus - Member Export Setting","SmartFocus - Member Export Setting"
7
+ "Subscriber Export","Subscriber Export"
8
+ "Error Email Recipient","Error Email Recipient"
9
+ "Error Email Sender","Error Email Sender"
10
+ "Error Email Template","Error Email Template"
11
+ "Triggered Export Settings","Triggered Export Settings"
12
+ "Scheduled Export Settings","Scheduled Export Settings"
13
+ "Cleaning of generated files","Cleaning of generated files"
14
+ "Enable the automatic update of your members data with apimember (Member Service)","Enable the automatic update of your members data with apimember (Member Service)"
15
+ "SmartFocus Account","SmartFocus Account"
16
+ "Enable the automatic update of your members data with apibatchmember (Batch Member Service)","Enable the automatic update of your members data with apibatchmember (Batch Member Service)"
17
+ "Allows you to reduce the number of members while building file. Default value should be quite balanced, if your server has limited RAM resources, you can lower it until encountering no more troubles","Allows you to reduce the number of items loaded while building file. Default value should be quite balanced, if your server has limited RAM resources, you can lower it until encountering no more troubles"
18
+ "Start Time (in Admin timezone)","Start Time (in Admin timezone)"
19
+ "Max number of fetched members per page","Max number of fetched members per page"
20
+ "Note: When using scheduled exports, the module will generate csv files. It's recommended to enable the file cleaning to delete them regularly","Note: When using scheduled exports, the module will generate csv files. It's recommended to enable the file cleaning to delete them regularly"
21
+ "Scheduled Customer Export (in Admin timezone)","Scheduled Customer Export (in Admin timezone)"
22
+ "Last Successful Synchronization","Last Successful Synchronization"
23
+ "Attribute Mapping","Attribute Mapping"
24
+ "Field Synchronization","Field Synchronization"
25
+ "Connect to SmartFocus apimember webservice and get the list of available fields","Connect to SmartFocus apimember webservice and get the list of available fields"
26
+ "Get SmartFocus member fields","Get SmartFocus member fields"
27
+ "Add Field","Add Field"
28
+ "Magento Fields","Magento Fields"
29
+ "SmartFocus Member Fields","SmartFocus Member Fields"
30
+ "Default field used to link a Magento newsletter subscriber to a SmartFocus member. CLIENTURN is selected by default.","Default field used to link a Magento newsletter subscriber to a SmartFocus member. CLIENTURN is selected by default."
31
+ "Warning: SmartFocus fields must not be mapped more than one time, including the entity field id. You can map any Magento field with as many disctinct SmartFocus ones as you want","Warning: SmartFocus fields must not be mapped more than one time, including the entity field id. You can map any Magento field with as many disctinct SmartFocus ones as you want"
32
+ "Unable to save the cron expression for triggered exports","Unable to save the cron expression for triggered exports"
33
+ "Unable to save the cron expression for scheduled exports","Unable to save the cron expression for scheduled exports"
34
+ "Every 15 minutes","Every 15 minutes"
35
+ "Every 30 minutes","Every 30 minutes"
36
+ "Hourly","Hourly"
37
+ "Every 2 hours","Every 2 hours"
38
+ "Every 4 hours","Every 4 hours"
39
+ "Every 6 hours","Every 6 hours"
40
+ "Every 12 hours","Every 12 hours"
41
+ "Daily","Daily"
42
+ "General","General"
43
+ "Enabled","Enabled"
44
+ "SmartFocus Entity Id","SmartFocus Entity Id"
app/locale/en_US/Emv_Emt.csv CHANGED
@@ -1,55 +1,111 @@
1
- "id","id"
2
- "Campaign Commander Transactional Emails","Campaign Commander Transactional Emails"
3
- "Add New Transactional Email","Add New Transactional Email"
4
- "System","System"
5
- "EMT ID","EMT ID"
 
 
6
  "Magento Template Name","Magento Template Name"
7
- "Mode","Mode"
8
- "Campaign Commander Template Name","Campaign Commander Template Name"
9
- "Campaign Commander Template Id And Name","Campaign Commander Template Id And Name"
 
 
 
10
  "Action","Action"
11
  "Edit","Edit"
12
- "New Campaign Commander Transactional Email","New Campaign Commander Transactional Email"
13
- "Edit Campaign Commander Transactional Email '%s'","Edit Campaign Commander Transactional Email '%s'"
14
- "Magento Template Name","Magento Template Name"
15
- "Magento Trigger","Magento Trigger"
16
- "Send Mail Mode","Send Mail Mode"
17
- "Attribute mapping","Attribute mapping"
18
- "Continue","Continue"
19
- "Get Campaign Commander template", "Get Campaign Commander template"
20
- "from","from"
21
- "to","to"
22
- "Campaign Commander Attribute","Campaign Commander Attribute"
23
- "Attribute","Attribute"
24
- "Attributes","Attributes"
25
- "Add New Attribute","Add New Attribute"
26
- "Add New EMV DYN Attribute","Add New EMV DYN Attribute"
27
- "Add New EMV CONTENT Attribute","Add New EMV CONTENT Attribute"
28
- "Remove","Remove"
29
- "Custom attribute, no mapping","Custom attribute, no mapping"
30
- "Attributes Mapping","Attributes Mapping"
31
- "EMT deleted.","EMT deleted."
32
- "Unable to find an emt to delete.","Unable to find an emt to delete."
33
- "There isn't any template in this period","There isn't any template in this period"
34
- "Error in dates format","Error in dates format"
35
- "Please select an Campaign Commander template","Please select a Campaign Commander template"
36
- "This Magento template is already mapped","This Magento template is already mapped"
37
- "This Campaign Commander template is already mapped.","This Campaign Commander template is already mapped."
38
- "Magento attribute '%s' is already mapped.","Magento attribute '%s' is already mapped."
39
- "Campaign Commander attribute '%s' is already mapped.","Campaign Commander attribute '%s' is already mapped."
40
- "Send mail mode is required.","Send mail mode is required."
41
- "Campaign Commander template is required.","Campaign Commander template is required."
42
- "Magento attribute is required.","Magento attribute is required."
43
- "Campaign Commander attribute is required.","Campaign Commander attribute is required."
44
- "This Campaign Commander template don't exists.","This Campaign Commander template don't exists."
45
- "This send mail mode don't exists.","This send mail mode don't exists."
46
- "An EMV account is required.","An Campaign Commander account is required."
47
- "A Magento template is required.","A Magento template is required."
48
- "This Magento template is already mapped.", "This Magento template is already mapped."
49
- "Please select a campaign commander template","Please select a campaign commander template"
50
- "Campaign Commander Templates","Campaign Commander Templates"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  "classic","Classic"
52
- "emv create","Campaign Commander Template"
53
- "emv send","EMV send"
54
- "There is no Magento templates not mapped with this account.","There is no Magento templates not mapped with this account."
55
- "A Campaign Commander account has not been set.","A Campaign Commander account has not been set."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Get SmartFocus templates","Get SmartFocus templates"
2
+ "Template Mapping Configuration","Template Mapping Configuration"
3
+ "Sending Mode","Sending Mode"
4
+ "From","From"
5
+ "To","To"
6
+ "Attribute Mapping","Attribute Mapping"
7
+ "There is no Magento email templates which can be used for this account !","There is no Magento email templates which can be used for this account !"
8
  "Magento Template Name","Magento Template Name"
9
+ "SmartFocus Account","SmartFocus Account"
10
+ "SmartFocus Template Name","SmartFocus Template Name"
11
+ "Edit '%s' Email Template","Edit '%s' Email Template"
12
+ "New Email Template","New Email Template"
13
+ Mode","Mode"
14
+ "SmartFocus Template Id And Name","SmartFocus Template Id And Name"
15
  "Action","Action"
16
  "Edit","Edit"
17
+ "Get Error","Get Error"
18
+ "ID","ID"
19
+ "Email","Email"
20
+ "Type","Type"
21
+ "Original Magento Template","Original Magento Template"
22
+ "Magento Template","Magento Template"
23
+ "Account Name","Account Name"
24
+ "SmartFocus Template","SmartFocus Template"
25
+ "Error","Error"
26
+ "Success","Success"
27
+ "Action","Action"
28
+ "Number of Attempts","Number of Attempts"
29
+ "First Attempt","First Attempt"
30
+ "Last Attempt","Last Attempt"
31
+ "SmartFocus Transactional Emails","SmartFocus Transactional Emails"
32
+ "Add New Transactional Email","Add New Transactional Email"
33
+ "Email Sending Logs","Email Sending Logs"
34
+ "Transactional Messages (NMP)","Transactional Messages (NMP)"
35
+ "Email Templates","Email Templates"
36
+ "Email Sending Logs","Email Sending Logs"
37
+ "Re-scheduled Email List","Re-scheduled Email List"
38
+ "Activate Sending Log","Activate Sending Log"
39
+ "Rescheduled Emails","Rescheduled Emails"
40
+ "By default, only error emails will be logged","By default, only error emails will be logged"
41
+ "Activate Sending Parameters Log","Activate Sending Parameters Log"
42
+ "All SmartFocus sending parameters will be logged","All SmartFocus sending parameters will be logged"
43
+ "Resending Mechanism Configuration","Resending Mechanism Configuration"
44
+ "Activate Resending Mechanism","Activate Resending Mechanism"
45
+ "First Delay (in minutes)","First Delay (in minutes)"
46
+ "Second Delay (in minutes)","Second Delay (in minutes)"
47
+ "Third Delay (in minutes)","Third Delay (in minutes)"
48
+ "Fourth Delay (in minutes)","Fourth Delay (in minutes)"
49
+ "SmartFocus template parameters are not valid !","SmartFocus template parameters are not valid !"
50
+ "Manage Email Templates","Manage Email Templates"
51
+ "SmartFocus account has not been set !","SmartFocus account has not been set !"
52
+ "New Template","New Template"
53
+ "Your SmartFocus account associated to this template does not exist anymore ! Please delete it !","Your SmartFocus account associated to this template does not exist anymore ! Please delete it !"
54
+ "Your selected Magento template does not exist. Please select a new one !","Your selected Magento template does not exist. Please select a new one !"
55
+ "There isn't any template in this period !","There isn't any template in this period !"
56
+ "There is no Magento templates not mapped with this account !","There is no Magento templates not mapped with this account !"
57
+ "The template was saved.","The template was saved."
58
+ "The template was deleted.","The template was deleted."
59
+ "Please select email template(s) !","Please select email template(s) !"
60
+ "Total of %d template(s) were deleted.","Total of %d template(s) were deleted."
61
+ "Not found template!","Not found template!"
62
+ "Please select email sending log(s) !","Please select email sending log(s) !"
63
+ "Total of %d record(s) were deleted.","Total of %d record(s) were deleted."
64
+ "Not found error log !","Not found error log !"
65
+ "Please select record(s) !","Please select record(s) !"
66
+ "Re-scheduled Email List","Re-scheduled Email List"
67
+ "Magento attribute is required !","Magento attribute is required !"
68
+ "SmartFocus attribute is required !","SmartFocus attribute is required !"
69
+ "Please provide the attribute type !","Please provide the attribute type !"
70
+ "Unknown attribute type !","Unknown attribute type !"
71
+ "Please select a SmartFocus template !'","Please select a SmartFocus template !'"
72
+ "SmartFocus account is required !","SmartFocus account is required !"
73
+ "Please select a SmartFocus account !","Please select a SmartFocus account !"
74
+ "Your selected SmartFocus account does not exist anymore ! Please select a new one !","Your selected SmartFocus account does not exist anymore ! Please select a new one !"
75
+ "Magento template is required !","Magento template is required !"
76
+ "Please select a Magento template !","Please select a Magento template !"
77
+ "This Magento template is already mapped !","This Magento template is already mapped !"
78
+ "Please select another Magento template !","Please select another Magento template !"
79
+ "Sending mode is required !","Sending mode is required !"
80
+ "Please select a sending mode !","Please select a sending mode !"
81
+ "This sending mode doesn't exists !","This sending mode doesn't exists !"
82
+ "Please select another sending mode !","Please select another sending mode !"
83
+ "SmartFocus template is required !","SmartFocus template is required !"
84
+ "Please select an SmartFocus template !","Please select an SmartFocus template !"
85
+ "Please select another SmartFocus template !","Please select another SmartFocus template !"
86
+ "SmartFocus attribute '%s' is already mapped !","SmartFocus attribute '%s' is already mapped !"
87
+ "Normal","Normal"
88
+ "Resending","Resending"
89
+ "Unknow Error","Unknow Error"
90
+ "Server Error","Server Error"
91
+ "Network Problem","Network Problem"
92
+ "Invalid SmartFocus Parameters","Invalid SmartFocus Parameters"
93
  "classic","Classic"
94
+ "emv create","SmartFocus Template"
95
+ "emv send","SmartFocus Routage"
96
+ "Refresh All Attributes","Refresh All Attributes"
97
+ "Insert Prepared Magento Variables","Insert Prepared Magento Variables"
98
+ "Please select a template","Please select a template"
99
+ "EMV DYN Attribute Mapping","EMV DYN Attribute Mapping"
100
+ "EMV CONTENT Attribute Mapping","EMV CONTENT Attribute Mapping"
101
+ "Configuration","Configuration"
102
+ "SmartFocus - Transactional Service Setting","SmartFocus - Transactional Service Setting"
103
+ "General","General"
104
+ "Available Attributes","Available Attributes"
105
+ "Invalid Attributes (from the last save)","Invalid Attributes (from the last save)"
106
+ "Personalized Content","Personalized Content"
107
+ "Preview","Preview"
108
+ "Template Information","Template Information"
109
+ "Are you sure to change the sending mode ? All your mapped attributes will be deleted !","Are you sure to change the sending mode ? All your mapped attributes will be deleted !"
110
+ "SmartFocus Attribute","SmartFocus Attribute"
111
+ "Are you sure to refresh all your mapped SmartFocus Attributes ?","Are you sure to refresh all your mapped SmartFocus Attributes ?"
app/locale/en_US/Emv_Report.csv ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Total Abandoned Cart Report","Total Abandoned Cart Report"
2
+ "the first reminders","the first reminders"
3
+ "the second reminders","the second reminders"
4
+ "the third reminders","the third reminders"
5
+ "Converted Cart Report for %s","Converted Cart Report for %s"
6
+ "Abandoned Cart Conversion Report","Abandoned Cart Conversion Report"
7
+ "Sent","Sent"
8
+ "Converted","Converted"
9
+ "Conversion Rate","Conversion Rate"
10
+ "Total Revenue","Total Revenue"
11
+ "Average Revenue","Average Revenue"
12
+ "SCA Email 1 - Second Reminder","SCA Email 1 - Second Reminder"
13
+ "SCA Email 2 - Second Reminder","SCA Email 2 - Second Reminder"
14
+ "SCA Email 3 - Third Reminder","SCA Email 3 - Third Reminder"
15
+ "Shopping Cart Abandonment","Shopping Cart Abandonment"
16
+ "Total","Total"
17
+ "Converted Cart Report","Converted Cart Report"
18
+ "First Name","First Name"
19
+ "Last Name","Last Name"
20
+ "Purchase On","Purchase On"
21
+ "Order #","Order #"
22
+ "Ordered Quantity","Ordered Quantity"
23
+ "Coupon Code","Coupon Code"
24
+ "Subtotal","Subtotal"
25
+ "Shipping","Shipping"
26
+ "Discount","Discount"
27
+ "Order Total","Order Total"
app/locale/en_US/template/email/abandonment/template1.html DELETED
@@ -1,41 +0,0 @@
1
- <!--@subject You've got a cart on our store @-->
2
-
3
- <!--@styles
4
- body{ color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; }
5
- @-->
6
-
7
- <body>
8
- <div>Hi {{var cart.getCustomerName()}},</div>
9
- <br />
10
-
11
- You have a cart on <a href="{{store url=" }}" title="Our store">our store</a>
12
- <br />
13
- <br />
14
-
15
- <a href="{{var cart.getCartLink()}}" title="COMPLETE YOUR ORDER NOW"
16
- target="_blank"><font color="#422C1E">View it now</font></a>
17
- <br />
18
- <br />
19
-
20
- Your Cart :
21
- <br />
22
- <table border="0">
23
- <tr>
24
- <td>{{block type="abandonment/cart_items" name="items" cart=$cart}}</td>
25
- </tr>
26
- <tr align="right">
27
- <td><strong>Your Order Total: ${{var cart.getTotalPrice(true)}}</strong></td>
28
- </tr>
29
- <tr>
30
- <td>&nbsp;</td>
31
- </tr>
32
- <tr>
33
- <td><a href="{{var cart.getCartLink()}}"
34
- title="COMPLETE YOUR ORDER NOW" target="_blank"><font
35
- color="#422C1E">GO TO CART</font></a> <br />
36
- <br />
37
- Click here to <a href="{{var cart.getUnsubLink()}}" title="Unsubscribe" target="_blank">unsubscribe</a> to these reminders
38
- </tr>
39
- </td>
40
- </table>
41
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/locale/en_US/template/email/abandonment/template2.html DELETED
@@ -1,41 +0,0 @@
1
- <!--@subject You've got a cart on our store, second chance to complete your order @-->
2
-
3
- <!--@styles
4
- body{ color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; }
5
- @-->
6
-
7
- <body>
8
- <div>Hi {{var cart.getCustomerName()}},</div>
9
- <br />
10
-
11
- You have a cart on <a href="{{store url=" }}" title="Our store">our store</a>
12
- <br />
13
- <br />
14
-
15
- <a href="{{var cart.getCartLink()}}" title="COMPLETE YOUR ORDER NOW"
16
- target="_blank"><font color="#422C1E">View it now</font></a>
17
- <br />
18
- <br />
19
-
20
- Your Cart :
21
- <br />
22
- <table border="0">
23
- <tr>
24
- <td>{{block type="abandonment/cart_items" name="items" cart=$cart}}</td>
25
- </tr>
26
- <tr align="right">
27
- <td><strong>Your Order Total: ${{var cart.getTotalPrice(true)}}</strong></td>
28
- </tr>
29
- <tr>
30
- <td>&nbsp;</td>
31
- </tr>
32
- <tr>
33
- <td><a href="{{var cart.getCartLink()}}"
34
- title="COMPLETE YOUR ORDER NOW" target="_blank"><font
35
- color="#422C1E">GO TO CART</font></a> <br />
36
- <br />
37
- Click here to <a href="{{var cart.getUnsubLink()}}" title="Unsubscribe" target="_blank">unsubscribe</a> to these reminders
38
- </tr>
39
- </td>
40
- </table>
41
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/locale/en_US/template/email/abandonment/template3.html DELETED
@@ -1,41 +0,0 @@
1
- <!--@subject You've got a cart on our store, last chance to complete your order @-->
2
-
3
- <!--@styles
4
- body{ color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; }
5
- @-->
6
-
7
- <body>
8
- <div>Hi {{var cart.getCustomerName()}},</div>
9
- <br />
10
-
11
- You have a cart on <a href="{{store url=" }}" title="Our store">our store</a>
12
- <br />
13
- <br />
14
-
15
- <a href="{{var cart.getCartLink()}}" title="COMPLETE YOUR ORDER NOW"
16
- target="_blank"><font color="#422C1E">View it now</font></a>
17
- <br />
18
- <br />
19
-
20
- Your Cart :
21
- <br />
22
- <table border="0">
23
- <tr>
24
- <td>{{block type="abandonment/cart_items" name="items" cart=$cart}}</td>
25
- </tr>
26
- <tr align="right">
27
- <td><strong>Your Order Total: ${{var cart.getTotalPrice(true)}}</strong></td>
28
- </tr>
29
- <tr>
30
- <td>&nbsp;</td>
31
- </tr>
32
- <tr>
33
- <td><a href="{{var cart.getCartLink()}}"
34
- title="COMPLETE YOUR ORDER NOW" target="_blank"><font
35
- color="#422C1E">GO TO CART</font></a> <br />
36
- <br />
37
- Click here to <a href="{{var cart.getUnsubLink()}}" title="Unsubscribe" target="_blank">unsubscribe</a> to these reminders
38
- </tr>
39
- </td>
40
- </table>
41
- </body>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
app/locale/en_US/template/email/emailvision/abandonment/template1.html ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--@subject You've got a cart on our store @-->
2
+ <!--@vars
3
+ {
4
+ "var cart.getStoreLink()":"Store Url",
5
+ "var logo_url":"Email Logo Image Url",
6
+ "var logo_alt":"Email Logo Image Alt",
7
+ "var cart.getCartLink()":"Cart Url",
8
+ "var cart.getCustomerPrefix()":"Customer Prefix",
9
+ "htmlescape var=$cart.getPreparedCustomerName()":"Customer Whole Name",
10
+ "htmlescape var=$cart.getCustomerFirstname()":"Customer First Name",
11
+ "htmlescape var=$cart.getCustomerMiddlename()":"Customer Middle Name",
12
+ "htmlescape var=$cart.getCustomerLastname()":"Customer Last Name",
13
+ "block type='abandonment/cart_items' name='items' cart=$cart":"Cart Item Grid",
14
+ "var promo_code|escape":"Promo Code",
15
+ "var cart.getUnsubLink()":"Unsubscription Url"
16
+ }
17
+ @-->
18
+ <!--@styles
19
+ body{ color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; }
20
+ @-->
21
+
22
+ <body>
23
+ <div>Hi {{var cart.getPreparedCustomerName()}},</div>
24
+ <br />
25
+
26
+ You have a cart on <a href="{{var cart.getStoreLink()}}" title="Our store">our store</a>
27
+ <br />
28
+ <br />
29
+
30
+ <a href="{{var cart.getCartLink()}}" title="COMPLETE YOUR ORDER NOW"
31
+ target="_blank"><font color="#422C1E">View it now</font></a>
32
+ <br />
33
+ <br />
34
+
35
+ Your Cart :
36
+ <br />
37
+ <table border="0">
38
+ <tr>
39
+ <td>{{block type="abandonment/cart_items" name="items" cart=$cart}}</td>
40
+ </tr>
41
+ <tr align="right">
42
+ <td><strong>Your Order Total: {{var cart.getPreparedGrandToTal()}}</strong></td>
43
+ </tr>
44
+ <tr>
45
+ <td>&nbsp;</td>
46
+ </tr>
47
+ <tr>
48
+ <td>
49
+ <a href="{{var cart.getCartLink()}}"
50
+ title="COMPLETE YOUR ORDER NOW" target="_blank"><font
51
+ color="#422C1E">GO TO CART {{if promo_code}}<strong> and apply the coupon "{{var promo_code|escape}}"</strong>{{/if}}</font>
52
+ </a>
53
+ <br />
54
+ <br />
55
+ Click here to <a href="{{var cart.getUnsubLink()}}" title="Unsubscribe" target="_blank">unsubscribe</a> to these reminders
56
+ </td>
57
+ </tr>
58
+
59
+ </table>
60
+ </body>
app/locale/en_US/template/email/emailvision/abandonment/template2.html ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--@subject You've got a cart on our store @-->
2
+ <!--@vars
3
+ {
4
+ "var cart.getStoreLink()":"Store Url",
5
+ "var logo_url":"Email Logo Image Url",
6
+ "var logo_alt":"Email Logo Image Alt",
7
+ "var cart.getCartLink()":"Cart Url",
8
+ "var cart.getCustomerPrefix()":"Customer Prefix",
9
+ "htmlescape var=$cart.getPreparedCustomerName()":"Customer Whole Name",
10
+ "htmlescape var=$cart.getCustomerFirstname()":"Customer First Name",
11
+ "htmlescape var=$cart.getCustomerMiddlename()":"Customer Middle Name",
12
+ "htmlescape var=$cart.getCustomerLastname()":"Customer Last Name",
13
+ "block type='abandonment/cart_items' name='items' cart=$cart":"Cart Item Grid",
14
+ "var promo_code|escape":"Promo Code",
15
+ "var cart.getUnsubLink()":"Unsubscription Url"
16
+ }
17
+ @-->
18
+ <!--@styles
19
+ body{ color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; }
20
+ @-->
21
+
22
+ <body>
23
+ <div>Hi {{var cart.getPreparedCustomerName()}},</div>
24
+ <br />
25
+
26
+ You have a cart on <a href="{{var cart.getStoreLink()}}" title="Our store">our store</a>
27
+ <br />
28
+ <br />
29
+
30
+ <a href="{{var cart.getCartLink()}}" title="COMPLETE YOUR ORDER NOW"
31
+ target="_blank"><font color="#422C1E">View it now</font></a>
32
+ <br />
33
+ <br />
34
+
35
+ Your Cart :
36
+ <br />
37
+ <table border="0">
38
+ <tr>
39
+ <td>{{block type="abandonment/cart_items" name="items" cart=$cart}}</td>
40
+ </tr>
41
+ <tr align="right">
42
+ <td><strong>Your Order Total: {{var cart.getPreparedGrandToTal()}}</strong></td>
43
+ </tr>
44
+ <tr>
45
+ <td>&nbsp;</td>
46
+ </tr>
47
+ <tr>
48
+ <td>
49
+ <a href="{{var cart.getCartLink()}}"
50
+ title="COMPLETE YOUR ORDER NOW" target="_blank"><font
51
+ color="#422C1E">GO TO CART {{if promo_code}}<strong> and apply the coupon "{{var promo_code|escape}}"</strong>{{/if}}</font>
52
+ </a>
53
+ <br />
54
+ <br />
55
+ Click here to <a href="{{var cart.getUnsubLink()}}" title="Unsubscribe" target="_blank">unsubscribe</a> to these reminders
56
+ </td>
57
+ </tr>
58
+
59
+ </table>
60
+ </body>
app/locale/en_US/template/email/emailvision/abandonment/template3.html ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--@subject You've got a cart on our store @-->
2
+ <!--@vars
3
+ {
4
+ "var cart.getStoreLink()":"Store Url",
5
+ "var logo_url":"Email Logo Image Url",
6
+ "var logo_alt":"Email Logo Image Alt",
7
+ "var cart.getCartLink()":"Cart Url",
8
+ "var cart.getCustomerPrefix()":"Customer Prefix",
9
+ "htmlescape var=$cart.getPreparedCustomerName()":"Customer Whole Name",
10
+ "htmlescape var=$cart.getCustomerFirstname()":"Customer First Name",
11
+ "htmlescape var=$cart.getCustomerMiddlename()":"Customer Middle Name",
12
+ "htmlescape var=$cart.getCustomerLastname()":"Customer Last Name",
13
+ "block type='abandonment/cart_items' name='items' cart=$cart":"Cart Item Grid",
14
+ "var promo_code|escape":"Promo Code",
15
+ "var cart.getUnsubLink()":"Unsubscription Url"
16
+ }
17
+ @-->
18
+ <!--@styles
19
+ body{ color:#2f2f2f; font:11px/1.35em Verdana, Arial, Helvetica, sans-serif; }
20
+ @-->
21
+
22
+ <body>
23
+ <div>Hi {{var cart.getPreparedCustomerName()}},</div>
24
+ <br />
25
+
26
+ You have a cart on <a href="{{var cart.getStoreLink()}}" title="Our store">our store</a>
27
+ <br />
28
+ <br />
29
+
30
+ <a href="{{var cart.getCartLink()}}" title="COMPLETE YOUR ORDER NOW"
31
+ target="_blank"><font color="#422C1E">View it now</font></a>
32
+ <br />
33
+ <br />
34
+
35
+ Your Cart :
36
+ <br />
37
+ <table border="0">
38
+ <tr>
39
+ <td>{{block type="abandonment/cart_items" name="items" cart=$cart}}</td>
40
+ </tr>
41
+ <tr align="right">
42
+ <td><strong>Your Order Total: {{var cart.getPreparedGrandToTal()}}</strong></td>
43
+ </tr>
44
+ <tr>
45
+ <td>&nbsp;</td>
46
+ </tr>
47
+ <tr>
48
+ <td>
49
+ <a href="{{var cart.getCartLink()}}"
50
+ title="COMPLETE YOUR ORDER NOW" target="_blank"><font
51
+ color="#422C1E">GO TO CART {{if promo_code}}<strong> and apply the coupon "{{var promo_code|escape}}"</strong>{{/if}}</font>
52
+ </a>
53
+ <br />
54
+ <br />
55
+ Click here to <a href="{{var cart.getUnsubLink()}}" title="Unsubscribe" target="_blank">unsubscribe</a> to these reminders
56
+ </td>
57
+ </tr>
58
+
59
+ </table>
60
+ </body>
app/locale/en_US/template/email/emailvision/datasync/cron_errors.html ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <!--@subject Emailvision synchronization by cron process errors @-->
2
+ <!--@vars
3
+ {"var errors":"Cron errors"}
4
+ @-->
5
+ {{var errors}}
app/locale/fr_FR/Emv_CartAlert.csv CHANGED
@@ -1,32 +1,40 @@
1
  "You are already unsubscribed from abandoned carts notifications.","Vous êtes déjà désinscrit des relances de paniers abandonnés."
2
  "You were successfully unsubscribed from abandoned carts notifications.","Vous avez été désinscrit des relances de paniers abandonnés avec succès"
3
- "Cart Reminder Subscription","Inscription Aux Relances Paniers Abandonnés"
4
  "The subscription has been saved.","L'inscription a été prise en compte."
5
  "The subscription has been removed.","La désinscription a été prise en compte"
6
  "An error occurred while saving your subscription.","Une erreur est apparue lors de l'inscription"
7
  "The link cannot be used by registered customers.","Le lien ne peut pas être utilisé par les utilisateurs enregistrés"
8
  "The link is invalid.","Le lien est invalide."
9
- "Emailvision abandonment cart config","Configuration Emailvision relance paniers abandonnés"
10
- "Emailvision section","Section Emailvision"
 
 
 
 
 
 
 
 
11
  "Abandoned Cart 1","Panier Abandonné 1"
12
  "Abandoned Cart 2","Panier Abandonné 2"
13
  "Abandoned Cart 3","Panier Abandonné 3"
14
- "Abandonment Cart Alert","Relance Panier Abandonné"
15
- "First Alert Configuration","Configuration Première Relance"
16
- "First Email Alert Enable","Activation Première Relance"
17
- "First Email Alert Delay (in hour)","Délai Première Relance (en heure)"
18
- "First Email Alert Template","Template Première Relance"
19
- "Second Alert Configuration","Configuration Deuxième Relance"
20
- "Second Email Alert Enable","Activation Deuxième Relance"
21
- "Second Email Alert Delay (in hour)","Délai Deuxième Relance (en heure)"
22
- "Second Email Template","Template Deuxième Relance"
23
- "Third Alert Configuration","Configuration Troisième Relance"
24
- "Third Email Alert Enable","Activation Troisième Relance"
25
- "Third Email Alert Delay (in hour)","Délai Troisième Relance (en heure)"
26
- "Third Email Alert Template","Template Troisième Relance"
27
  "Sender Identity","Identité de l'expéditeur"
28
  "Email Sender","Expéditeur Email"
29
- "Cart Reminder Subscription","Inscription Aux Relances Paniers Abandonnés"
30
- "Cart Reminder Email Subscription","Inscription Aux Emails Relances Paniers Abandonnés"
31
  "Back","Retour"
32
- "Save","Valider"
 
 
1
  "You are already unsubscribed from abandoned carts notifications.","Vous êtes déjà désinscrit des relances de paniers abandonnés."
2
  "You were successfully unsubscribed from abandoned carts notifications.","Vous avez été désinscrit des relances de paniers abandonnés avec succès"
3
+ "Cart Reminder Subscription","Inscription aux relances paniers abandonnés"
4
  "The subscription has been saved.","L'inscription a été prise en compte."
5
  "The subscription has been removed.","La désinscription a été prise en compte"
6
  "An error occurred while saving your subscription.","Une erreur est apparue lors de l'inscription"
7
  "The link cannot be used by registered customers.","Le lien ne peut pas être utilisé par les utilisateurs enregistrés"
8
  "The link is invalid.","Le lien est invalide."
9
+ "Cart Reminder Email Subscription","Inscription Aux Emails Relances Paniers Abandonnés"
10
+ "Image Size","Taille image"
11
+ "Shopping Cart Prices Rule Id","Id de règle de prix du panier"
12
+ "Coupon Code Length","Longueur du code coupon"
13
+ "Coupon Code Format","Format du code coupon"
14
+ "Coupon Code Prefix","Préfixe du code coupon"
15
+ "Coupon Code Suffix","Suffixe du code coupon"
16
+ "Dash Every X Characters For Coupon Code","Supprimer tous les caractères X dans le code coupon"
17
+ "If empty no separation.","Pas de séparation si vide."
18
+ "Excluding prefix, suffix and separators.","Exclure les préfixes, suffixes et séparateurs."
19
  "Abandoned Cart 1","Panier Abandonné 1"
20
  "Abandoned Cart 2","Panier Abandonné 2"
21
  "Abandoned Cart 3","Panier Abandonné 3"
22
+ "Abandonment Cart Alert","Relance panier abandonné"
23
+ "First Alert Configuration","Configuration première relance"
24
+ "First Email Alert Enable","Activation première relance"
25
+ "First Email Alert Delay (in hour)","Délai première relance (en heure)"
26
+ "First Email Alert Template","Template première relance"
27
+ "Second Alert Configuration","Configuration deuxième relance"
28
+ "Second Email Alert Enable","Activation deuxième relance"
29
+ "Second Email Alert Delay (in hour)","Délai deuxième relance (en heure)"
30
+ "Second Email Template","Template deuxième relance"
31
+ "Third Alert Configuration","Configuration troisième relance"
32
+ "Third Email Alert Enable","Activation troisième relance"
33
+ "Third Email Alert Delay (in hour)","Délai troisième relance (en heure)"
34
+ "Third Email Alert Template","Template troisième relance"
35
  "Sender Identity","Identité de l'expéditeur"
36
  "Email Sender","Expéditeur Email"
 
 
37
  "Back","Retour"
38
+ "Save","Valider"
39
+ "General","Général"
40
+ "SmartFocus - Abandonment cart configs","SmartFocus - Configurations de la relance panier abandoné"
app/locale/fr_FR/Emv_Core.csv CHANGED
@@ -1,6 +1,4 @@
1
- "id","id"
2
- "No","Non"
3
- "Yes","Oui"
4
  "Account Information","Information du compte"
5
  "Account Name","Nom du compte"
6
  "API Information","Informations API"
@@ -10,34 +8,54 @@
10
  "API Uses Proxy", "API Utilise un Proxy"
11
  "Proxy Host","Serveur Proxy"
12
  "Proxy Port","Port du Proxy"
13
- "Configure Campaign Commander Account","Configurer Compte Campaign Commander"
 
 
 
 
 
14
  "Action","Action"
15
  "Edit","Editer"
16
- "Campaign Commander Accounts","Comptes Campaign Commander"
17
- "Campaign Commander account deleted.","Compte Campaign Commander Supprimé."
18
- "The Campaign Commander account has been saved.","Le Compte Campaign Commander a été enregistré."
19
- "Account with the same name already exists.","Un compte avec un nom similaire existe déjà."
20
- "Account with the same login already exists.","Un compte avec un identifiant similaire existe déjà."
21
- "Account with the same API manager key already exists.","Un compte avec une clé Manager API similaire existe déjà."
22
- "Proxy host and port are required.","Le serveur Proxy et le port sont nécessaires."
23
- "Campaign Commander Account","Compte Campaign Commander"
24
- "Campaign Commander Section","Section Campaign Commander"
25
- "Edit Campaign Commander Account '%s'","Editer Compte Campaign Commander '%s'"
26
- "New Campaign Commander Account","Nouveau Compte Campaign Commander"
27
- "Proxy Information", "Informations sur le Proxy"
28
- "Account ID", "ID du Compte"
29
  "Edit Account","Editer Compte"
 
30
  "Add New Account","Ajouter Nouveau Compte"
31
- "Unable to find an account to delete.","Aucun compte trouvé pour suppression."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  "Name is required.","Le nom est obligatoire."
33
  "API login is required.","L'identifiant API est obligatoire."
34
- "API password is required.","Le Mot de Passe API est obligatoire."
35
  "API Manager key is required.","La clé API Manager est obligatoire."
36
- "System","Système"
37
- "This EMV account is invalid.","Ce Compte Campaign Commander est invalide."
38
- "Cound not connect to Campaign Commander WebService.","Connexion au webservice Campaign Commander impossible."
39
- "--Please Select--","--Votre choix--"
40
- "Transactional Service Adress","Adresse Service Transactionel"
41
- "Notification Service Adress","Adresse Service Notification"
42
- "Campaign Commander Services","Services Campaign Commander"
43
- "Emailvision","Emailvision"
 
 
 
 
 
 
 
 
1
+ "Accounts","Comptes"
 
 
2
  "Account Information","Information du compte"
3
  "Account Name","Nom du compte"
4
  "API Information","Informations API"
8
  "API Uses Proxy", "API Utilise un Proxy"
9
  "Proxy Host","Serveur Proxy"
10
  "Proxy Port","Port du Proxy"
11
+ "Associated Webservice Urls","Adresses des webservices associés"
12
+ "Available Webservices","Webservices disponibles"
13
+ "Edit SmartFocus Account '%s'","Editer compte SmartFocus '%s'"
14
+ "New SmartFocus Account","Nouveau compte SmartFocus"
15
+ "Account ID", "Account ID"
16
+ "SmartFocus Account","Compte SmartFocus"
17
  "Action","Action"
18
  "Edit","Editer"
 
 
 
 
 
 
 
 
 
 
 
 
 
19
  "Edit Account","Editer Compte"
20
+ "SmartFocus Accounts","Comptes SmartFocus"
21
  "Add New Account","Ajouter Nouveau Compte"
22
+ "SmartFocus account deleted.","Votre compte SmartFocus a été supprimé."
23
+ "Unable to find an account to delete.","Aucun compte n'a été trouvé pour suppression."
24
+ "Your selected account does not exist anymore!","Votre compte sélectionné n'existe plus!"
25
+ "Could not verify the account. Network problems occured! Please Save again!","Connexion au webservice SmartFocus impossible, veuillez ré-essayer à nouveau!"
26
+ "Your account ""%s"" is not allowed for %s !","Votre compte ""%s"" n'est pas autorisé pour %s !"
27
+ "Please define a valid url for %s !","Merci de renseigner un valid url pour %s!"
28
+ "Could not enable ""%s"" process ! Please select an account in the list !","Impossible d'activer ""%s"" process ! Veuillez sélectionner un compte dans la liste !"
29
+ "Please give a valid url for %s !","Merci de renseigner un valid url pour %s!"
30
+ "Network problems occured ! Please verify the service url or your network settings!","Connexion au webservice SmartFocus impossible. Veuillez bien vérifier votre url service ou les paramètres de votre réseau !"
31
+ "Your token has expired! Please retry your request again !","Votre session a expiré, veuillez ré-essayer à nouveau !"
32
+ "Your API credential is not valid ! Please correct it !","Votre compte est invalide ! Veuillez le corriger !"
33
+ "Your SmartFocus template is not found! Please select a new one!","Votre SmartFocus template n'existe plus ! Veuillez choisir un nouveau template !"
34
+ "Unknown error with SmartFocus webservice","Erreur inconnue avec SmartFocus service"
35
+ "The given account does not have a valid url for Notification service","Le compte séléctionné ne contient pas un url valide pour Notification service"
36
+ "Can not create SmartFocus default sending template","Impossible de créer Campagin Commander template par défaut "
37
+ "--Please Select--","--Veuillez sélectionner--"
38
+ "Transactional Service","Transactional Service"
39
+ "REST Notification Service","REST Notification Service"
40
+ "Batch Member Service","Batch Member Service"
41
+ "Member Service","Member Service"
42
  "Name is required.","Le nom est obligatoire."
43
  "API login is required.","L'identifiant API est obligatoire."
44
+ "API password is required.","Le mot de passe API est obligatoire."
45
  "API Manager key is required.","La clé API Manager est obligatoire."
46
+ "The SmartFocus account has been saved.","Le Compte SmartFocus a été enregistré."
47
+ "Account with the same name already exists.","Un compte avec un nom similaire existe déjà."
48
+ "Account with the same login already exists.","Un compte avec un identifiant similaire existe déjà."
49
+ "Account with the same API manager key already exists.","Un compte avec une clé Manager API similaire existe déjà."
50
+ "Proxy host and port are required.","Le serveur Proxy et le port sont nécessaires."
51
+ "You need to enter at least one of the following service(s) : %s","Vous devez entrer au moins un des services suivants: %s"
52
+ "Connection problem. Could not check api credential, please try again","Connexion au webservice SmartFocus impossible, veuillez ré-essayer à nouveau!"
53
+ "This SmartFocus account is invalid. Please check your API credential","Ce Compte SmartFocus est invalide. Merci de bien vérifier les détails de votre compte"
54
+ "This SmartFocus account does not have any SmartFocus service url","Ce Compte SmartFocus ne contient aucun SmartFocus service."
55
+ "%s is unknown by SmartFocus platform.","%s n'est pas réconnu par SmartFocus plateforme."
56
+ "Please enter a valid url for %s!","Merci de renseigner un valid url pour %s!"
57
+ "Service","Service"
58
+ "Url","Url"
59
+ "Add","Ajouter"
60
+ "Remove","Supprimer"
61
+ "General","Général"
app/locale/fr_FR/Emv_DataSync.csv ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Please synchronize with SmartFocus webservice (see above)","Vous devez importer les champs SmartFocus (voir ci-dessus)"
2
+ "Not scheduled yet","Pas encore planifié"
3
+ "Please select an account for ""Triggered Exports"". Access to Member service is required","Merci de sélectionner un compte pour l'export automatique. L'accès au ""Member service"" est obligatoire"
4
+ "Retrieved successfully SmartFocus member fields","Les champs membre ont été importés avec succès du SmartFocus webservice"
5
+ "SmartFocus - Member Export Setting","SmartFocus - Configuration d'export des abonnés"
6
+ "Subscriber Export","Export des abonnés à la newsletter"
7
+ "Error Email Recipient","Destinataire du mail d'erreur"
8
+ "Error Email Sender","Expéditeur du mail d'erreur"
9
+ "Error Email Template","Gabarit du mail d'erreur"
10
+ "Triggered Export Settings","Paramètres d'export automatique"
11
+ "Scheduled Export Settings","Paramètres d'export programmé"
12
+ "Cleaning of generated files","Nettoyage des fichiers générés"
13
+ "Enable the automatic update of your members data with apimember (Member Service)","Activer la mise à jour automatique des membres via l'apimember (Member Service)"
14
+ "SmartFocus Account","SmartFocus Compte"
15
+ "Enable the automatic update of your members data with apibatchmember (Batch Member Service)","Activer la mise à jour programmée des membres via l'apibatchmember (Batch Member Service)"
16
+ "Allows you to reduce the number of members loaded while building file. Default value should be quite balanced, if your server has limited RAM resources, you can lower it until encountering no more troubles","Permet de réduire le nombre d'abonnés chargés simultanément pendant l'écriture des fichiers. La valeur supporte la plupart des configuration matérielles, mais si votre serveur dispose de ressources mémoires limitées, vous pouvez réduire cette valeur jusqu'à ce que vous ne rencontriez plus de problèmes"
17
+ "Start Time (in Admin timezone)","Heure de départ (en fuseau horaire Admin)"
18
+ "Max number of fetched members per page","Le nombre maximum de membres récupérés par page"
19
+ "Note: When using scheduled exports, the module will generate csv files. It's recommended to enable the file cleaning to delete them regularly","Note: pour réaliser l'export massif, ce module génère des fichiers csv qui sont envoyés aux webservices SmartFocus. Il est recommandé d'activer le nettoyage des fichiers afin de les supprimer régulièrement"
20
+ "Scheduled Customer Export (in Admin timezone)","Exports programmés (en fuseau horaire Admin)"
21
+ "Last Successful Synchronization","Dernière synchronisation réussie"
22
+ "Attribute Mapping","Mapping des champs client"
23
+ "Field Synchronization","Synchronisation des champs"
24
+ "Connect to SmartFocus apimember webservice and get the list of available fields","Connecter à SmartFocus apimember webservice et récupérer la liste des champs disponibles"
25
+ "Get SmartFocus member fields","Importer les champs SmartFocus"
26
+ "Add Field","Ajouter un champ"
27
+ "Magento Fields","Champs Magento"
28
+ "SmartFocus Member Fields","Champs de la table membre SmartFocus"
29
+ "If enabled, Magento newsletter subscribers will be synced by their email address. By default, the SmartFocus Entity Id will be used.","Si activée, les abonnés à la newsletter Magento seront synchronisés par leur adresse e-mail. Par défaut, SmartFocus Id sera utilisé."
30
+ "SmartFocus Entity Id","SmartFocus id"
31
+ "Default field used to link a Magento newsletter subscriber to a SmartFocus member. CLIENTURN is selected by default.","Champ par défaut utilisé pour lier l'identifiant d'un abonné à la newsletter à un membre SmartFocus correspondant. CLIENTURN est utilisé par défaut."
32
+ "Warning: SmartFocus fields must not be mapped more than one time, including the entity field id. You can map any Magento field with as many disctinct SmartFocus ones as you want","Attention: les champs SmartFocus ne doivent pas être associés plus d'une fois, identifiant compris. Vous pouvez en revanche associer n'importe quel champ Magento avec autant de champs SmartFocus distincts que vous le souhaitez"
33
+ "Unable to save the cron expression for triggered exports","Impossible de sauvegarder l'expression cron pour l'export automatique"
34
+ "Unable to save the cron expression for scheduled exports","Impossible de sauvegarder l'expression cron pour l'export programmé"
35
+ "Hourly","Toutes les heures"
36
+ "Every 15 minutes","Toutes les 15 minutes"
37
+ "Every 30 minutes","Toutes les 30 minutes"
38
+ "Every 2 hours","Toutes les 2 heures"
39
+ "Every 4 hours","Toutes les 4 heures"
40
+ "Every 6 hours","Toutes les 6 heures"
41
+ "Every 12 hours","Toutes les 12 heures"
42
+ "Daily","Quotidiennement"
43
+ "General","Général"
44
+ "Enabled","Activé"
45
+ "Frequency","Fréquence"
app/locale/fr_FR/Emv_Emt.csv CHANGED
@@ -1,55 +1,111 @@
1
- "id","id"
2
- "Campaign Commander Transactional Emails","E-mails transactionnels Campaign Commander"
3
- "Add New Transactional Email","Ajouter nouveau E-mail transactionnel"
4
- "System","Système"
5
- "EMT ID","ID EMT"
 
 
6
  "Magento Template Name","Nom du modèle Magento"
7
- "Mode","Mode"
8
- "Campaign Commander Template Name","Nom du modèle Campaign Commander"
9
- "Campaign Commander Template Id And Name","ID et nom du modèle Campaign Commander"
 
 
 
10
  "Action","Action"
11
  "Edit","Editer"
12
- "New Campaign Commander Transactional Email","Nouveau E-mail transactionnel Campaign Commander"
13
- "Edit Campaign Commander Transactional Email '%s'","Editer E-mail transactionnel Campaign Commander '%s'"
14
- "Magento Template Name","Nom du modèle Magento"
15
- "Magento Trigger","Déclencheur Magento"
16
- "Send Mail Mode","Mode d'envoi de l'e-mail"
17
- "Attribute mapping","Mappage des attributs"
18
- "Continue","Continuer"
19
- "Get Campaign Commander template", "Obtenir les modèles Campaign Commander"
20
- "from","de"
21
- "to","à"
22
- "Campaign Commander Attribute","Attribut Campaign Commander"
23
- "Attribute","Attribut"
24
- "Attributes","Attributs"
25
- "Add New Attribute","Ajouter Attribut"
26
- "Add New EMV DYN Attribute","Ajouter Attribut EMV DYN"
27
- "Add New EMV CONTENT Attribute","Ajouter Attribut EMV CONTENT"
28
- "Remove","Supprimer"
29
- "Custom attribute, no mapping","Attribut spécifique, pas de mappage"
30
- "Attributes Mapping","Mappage des attributs"
31
- "EMT deleted.","EMT supprimé."
32
- "Unable to find an emt to delete.","Impossible de trouver un EMT à supprimer."
33
- "There isn't any template in this period","Il n'y a aucun modèle disponible sur cette période"
34
- "Error in dates format","Erreur sur le format de date"
35
- "Please select an Campaign Commander template","Veuillez sélectionner un modèle Campaign Commander"
36
- "This Magento template is already mapped","Ce modèle Magento est déjà mappé"
37
- "This Campaign Commander template is already mapped.","Ce modèle Campaign Commander est déjà mappé."
38
- "Magento attribute '%s' is already mapped.","L'attribut Magento '%s' est déjà mappé."
39
- "Campaign Commander attribute '%s' is already mapped.","L'attribut Campaign Commander '%s' est déjà mappé."
40
- "Send mail mode is required.","Le mode d'envoi de l'e-mail est nécessaire."
41
- "Campaign Commander template is required.","Campaign Commander template is required."
42
- "Magento attribute is required.","L'attribut Magento est nécessaire."
43
- "Campaign Commander attribute is required.","L'attribut Campaign Commander est obligatoire."
44
- "This Campaign Commander template don't exists.","Ce modèle Campaign Commander n'existe pas."
45
- "This send mail mode don't exists.","Ce mode d'envoi n'existe pas."
46
- "An EMV account is required.","Un compte Campaign Commander est nécessaire."
47
- "A Magento template is required.","Un modèle magento est nécessaire."
48
- "This Magento template is already mapped.", "Ce modèle Magento est déjà mappé."
49
- "Please select a campaign commander template","Veuillez sélectionner un modèle Campaign Commander"
50
- "Campaign Commander Templates","Modèles Campaign Commander"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  "classic","Classic"
52
- "emv create","Campaign Commander Template"
53
- "emv send","EMV send"
54
- "There is no Magento templates not mapped with this account.","Il n'y a aucun templates Magento non mappé avec ce compte."
55
- "A Campaign Commander account has not been set.","Il n'y a aucun compte Campaign Commander de configuré."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Get SmartFocus templates","Obtenir les modèles SmartFocus"
2
+ "Template Mapping Configuration","Configuration de mappage de template"
3
+ "Sending Mode","Mode d'envoi"
4
+ "From","De"
5
+ "To","A"
6
+ "Attribute Mapping","Mappage d'attribut"
7
+ "There is no Magento email templates which can be used for this account !","Aucun modèle Magento n'est disponbile pour ce compte"
8
  "Magento Template Name","Nom du modèle Magento"
9
+ "SmartFocus Account","Compte SmartFocus"
10
+ "SmartFocus Template Name","Nom du modèle SmartFocus"
11
+ "Edit '%s' Email Template","Editer email transactionnel '%s'"
12
+ "New Email Template","Nouveau modèle d'email"
13
+ Mode","Mode"
14
+ "SmartFocus Template Id And Name","ID et nom du modèle SmartFocus"
15
  "Action","Action"
16
  "Edit","Editer"
17
+ "Get Error","Visualiser les erreurs"
18
+ "ID","ID"
19
+ "Email","Email"
20
+ "Type","Type"
21
+ "Original Magento Template","Modèle original Magento"
22
+ "Magento Template","Modèle Magento utilisé"
23
+ "Account Name","Nom du compte"
24
+ "SmartFocus Template","Modèle SmartFocus"
25
+ "Error","Erreur"
26
+ "Success","Succès"
27
+ "Action","Action"
28
+ "Number of Attempts","Nombre de tentatives"
29
+ "First Attempt","Premierère tentative"
30
+ "Last Attempt","Dernière tentative"
31
+ "SmartFocus Transactional Emails","Emails transactionnels SmartFocus"
32
+ "Add New Transactional Email","Ajouter un nouveau email transactionnel"
33
+ "Email Sending Logs","Enregistrements d'envoi"
34
+ "Transactional Messages (NMP)","Messages Transactionels (NMP)"
35
+ "Email Templates","Modèles d'email"
36
+ "Email Sending Logs","Enregistrement des envois d'emails"
37
+ "Re-scheduled Email List","Liste des emails re-programmés"
38
+ "Activate Sending Log","Activer l'enregistrement d'envoi"
39
+ "Rescheduled Emails","Emails re-programmés"
40
+ "By default, only error emails will be logged","Par défaut, seuls les erreurs emails seront enregistrés"
41
+ "Activate Sending Parameters Log","Activer l'enregistrement de paramètres d'envoi"
42
+ "All SmartFocus sending parameters will be logged","Tous les paramètres d'envoi seront enregistrés"
43
+ "Resending Mechanism Configuration","Configuration du mécanisme de renvoi"
44
+ "Activate Resending Mechanism","Activer le mécanisme de renvoi"
45
+ "First Delay (in minutes)","Premier délai (en minutes)"
46
+ "Second Delay (in minutes)","Second délai (en minutes)"
47
+ "Third Delay (in minutes)","Troisième Delai (en minutes)"
48
+ "Fourth Delay (in minutes)","Quatrième Delai (en minutes)"
49
+ "SmartFocus template parameters are not valid !","Les paramètres du modèle SmartFocus sont invalides !"
50
+ "Manage Email Templates","Emails Transactionnels"
51
+ "SmartFocus account has not been set !","Il n'y a aucun compte SmartFocus configuré."
52
+ "New Template","Nouveau Modèle"
53
+ "Your SmartFocus account associated to this template does not exist anymore ! Please delete it !","Votre compte de SmartFocus associée à ce modèle n'existe plus! Veuillez le supprimer!"
54
+ "Your selected Magento template does not exist. Please select a new one !","Votre modèle Magento sélectionné n'existe plus. Veuillez choisir un nouveau!"
55
+ "There isn't any template in this period !","Il n'y a aucun modèle disponible sur cette période"
56
+ "There is no Magento templates not mapped with this account !","Aucun modèle Magento n'est disponible pour ce compte !"
57
+ "The template was saved.","Le modèle a été enregistré."
58
+ "The template was deleted.","Le modèle a été supprimé."
59
+ "Please select email template(s) !","Veuillez sélectionner au moins un modèle!"
60
+ "Total of %d template(s) were deleted.","Un total de %d modèles ont été supprimés."
61
+ "Not found template!","Aucun modèle n'a été trouvé !"
62
+ "Please select email sending log(s) !","Veuillez sélectioner au moins un enregistrement d'envoi!"
63
+ "Total of %d record(s) were deleted.","Un total de %d enregistrements ont été supprimés"
64
+ "Not found error log !","Aucun enregistrement d'erreur a été trouvé!"
65
+ "Please select record(s) !","Veuillez sélectionner des enregistrements!"
66
+ "Magento attribute is required !","Magento attribut est obligatoire!"
67
+ "SmartFocus attribute is required !","Attribut SmartFocus est obligatoire!"
68
+ "Please provide the attribute type !","Veuillez fournir le type d'attribut!"
69
+ "Unknown attribute type !","Type d'attribut incconu!"
70
+ "Please select a SmartFocus template !'","Veuillez sélectionner un modèle SmartFocus!"
71
+ "SmartFocus account is required !","Un compte SmartFocus est obligatoire!"
72
+ "Please select a SmartFocus account !","Veuillez sélectionner un compte SmartFocus!"
73
+ "Your selected SmartFocus account does not exist anymore ! Please select a new one !","Votre compte SmartFocus sélectionné n'existe plus! Veuillez choisir un nouveau!"
74
+ "Magento template is required !","Un modèle Magento est obligatoire!"
75
+ "Please select a Magento template !","Veuillez sélectionner un modèle Magento!"
76
+ "This Magento template is already mapped !","Ce modèle Magento est déjà mappé !"
77
+ "Please select another Magento template !","Veuillez sélectionner un autre modèle Magento!"
78
+ "Sending mode is required !","Le mode d'envoi de l'e-mail est nécessaire!"
79
+ "Please select a sending mode !","Veuillez sélectionner un mode d'envoi!"
80
+ "This sending mode doesn't exists !","Ce mode d'envoi n'existe pas!"
81
+ "Please select another sending mode !","Veuillez sélectionner un autre mode!"
82
+ "SmartFocus template is required !","Un modèle SmartFocus est obligatoire!"
83
+ "Please select an SmartFocus template !","Veuillez sélectionner un modèle SmartFocus!"
84
+ "Please select another SmartFocus template !","Veuillez sélectionner un autre modèle SmartFocus!"
85
+ "SmartFocus attribute '%s' is already mapped !","Attribut SmartFocus '%s' est déjà mappé!"
86
+ "Normal","Normal"
87
+ "Resending","Re-programmé"
88
+ "Unknow Error","Erreur inconnue"
89
+ "Server Error","Serveur problème"
90
+ "Network Problem","Problème de réseau"
91
+ "Invalid SmartFocus Parameters","Paramètres d'envoi invalides"
92
  "classic","Classic"
93
+ "emv create","SmartFocus Template"
94
+ "emv send","SmartFocus Routage"
95
+ "Refresh All Attributes","Actualiser tous les attributs"
96
+ "Insert Prepared Magento Variables","Insérer les variables Magento"
97
+ "Please select a template","Veuillez sélectionner un modèle"
98
+ "EMV DYN Attribute Mapping","Mappage des attributs EMV DYN"
99
+ "EMV CONTENT Attribute Mapping","Mappage des attributs EMV CONTENT"
100
+ "Configuration","Configuration"
101
+ "General","Général"
102
+ "SmartFocus - Transactional Service Setting","SmartFocus - Configuration du service transactionnel"
103
+ "Available Attributes","Les attributs disponibles"
104
+ "Invalid Attributes (from the last save)","Les attributs invalides (à partir de la dernière sauvegarde)"
105
+ "Personalized Content","Contenu personnalisé"
106
+ "Preview","Aperçu"
107
+ "Template Information","Information sur le modèle"
108
+ "Are you sure to change the sending mode ? All your mapped attributes will be deleted !","Etes-vous sûr de changer le mode d\'envoi? Tous vos attributs mappés seront supprimés!"
109
+ "SmartFocus Attribute","Attribut SmartFocus"
110
+ "Are you sure to refresh all your mapped SmartFocus Attributes ?","Etes-vous sûr de rafraîchir tous vos attributs SmartFocus mappés?"
111
+ ""Email Templates","Modèles d'email"
app/locale/fr_FR/Emv_Report.csv ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Total Abandoned Cart Report","Rapport de paniers abandonés"
2
+ "the first reminders","les premières relances"
3
+ "the second reminders","les secondes relances"
4
+ "the third reminders","les troisièmes relances"
5
+ "Converted Cart Report for %s","Taux de conversion pour %s"
6
+ "Abandoned Cart Conversion Report","Rapport de paniers abandonés"
7
+ "Sent","Envoyés"
8
+ "Converted","Convertis"
9
+ "Conversion Rate","Taux de conversion"
10
+ "Total Revenue","Chiffre d'affaires total"
11
+ "Average Revenue","Revenu moyen"
12
+ "SCA Email 1 - First Reminder","SCA Email 1 - Première relance"
13
+ "SCA Email 2 - Second Reminder","SCA Email 2 - Deuxième relance"
14
+ "SCA Email 3 - Third Reminder","SCA Email 3 - Troisième relance"
15
+ "Shopping Cart Abandonment","Paniers Abandonnés"
16
+ "Total","Total"
17
+ "Converted Cart Report","Aperçu sur les paniers converties"
18
+ "First Name","Prénom"
19
+ "Last Name","Nom"
20
+ "Purchase On","Acheté sur"
21
+ "Order #","Commande #"
22
+ "Ordered Quantity","Quantité commandée"
23
+ "Coupon Code","Code coupon"
24
+ "Subtotal","Sous-total"
25
+ "Shipping","Livraison"
26
+ "Discount","Montant de la remise"
27
+ "Order Total","Total"
lib/EmailVision/Api/BatchMemberService.php ADDED
@@ -0,0 +1,410 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Batch Member Service Api - Data member updates by flat files
4
+ *
5
+ * @category EmailVision
6
+ * @package EmailVision_Api
7
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
8
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
9
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License v. 3.0 (OSL-3.0)
10
+ */
11
+ class EmailVision_Api_BatchMemberService extends EmailVision_Api_Common
12
+ {
13
+ /**
14
+ * Default prepare file name method
15
+ */
16
+ const PREPARE_FILE_NAME_METHOD = 'prepareFileName';
17
+
18
+ /**
19
+ * CSV field delimiter and enclosure
20
+ */
21
+ const CSV_FIELD_DELIMITER = ',';
22
+ const CSV_FIELD_ENCLOSURE = '"';
23
+
24
+ /**
25
+ * Max file size in byte
26
+ */
27
+ const MAX_FILESIZE = 50000000;
28
+ const MAX_ROW = 150000;
29
+
30
+ /**
31
+ * File index
32
+ * @var int
33
+ */
34
+ protected $_fileIndex = 0;
35
+
36
+ /**
37
+ * Accomplished statuses
38
+ * @var array
39
+ */
40
+ public static $_accomplishedStatuses = array('ERROR','FAILURE','DONE', 'DONE WITH ERROR(S)');
41
+
42
+ /**
43
+ * Status OK
44
+ * @var string
45
+ */
46
+ public static $_statusOk = 'DONE';
47
+
48
+ /**
49
+ * Get all accomplished statuses for an upload
50
+ *
51
+ * @return array
52
+ */
53
+ public static function getAccomplishedStatuses()
54
+ {
55
+ return self::$_accomplishedStatuses;
56
+ }
57
+
58
+ /**
59
+ * Get status OK without error for an upload
60
+ *
61
+ * @return string
62
+ */
63
+ public static function getStatusOkWithoutError()
64
+ {
65
+ return self::$_statusOk;
66
+ }
67
+
68
+ /**
69
+ * Create csv files for a given list of members
70
+ * - you need
71
+ *
72
+ * @param Object $caller
73
+ * @param array $headers
74
+ * @param array $members
75
+ * @param string $delimiter
76
+ * @param string $enclosure
77
+ * @return array
78
+ * - file : array
79
+ * + filename
80
+ * + path
81
+ * + time
82
+ * - list_member
83
+ */
84
+ public function createCsvFiles(
85
+ $caller,
86
+ array $headers,
87
+ array $members,
88
+ $delimiter = self::CSV_FIELD_DELIMITER,
89
+ $enclosure = self::CSV_FIELD_ENCLOSURE
90
+ )
91
+ {
92
+ $generatedCsvData = array();
93
+
94
+ if (!method_exists($caller, self::PREPARE_FILE_NAME_METHOD)) {
95
+ $this->throwEmailVisionException('The caller needs to have ' . self::PREPARE_FILE_NAME_METHOD);
96
+ } else {
97
+ $result = $this->checkData($headers, $members);
98
+ if ($result) {
99
+ $rowCount = 0;
100
+ $csvTool = new EmailVision_Tools_File_Csv();
101
+ $fileData = null;
102
+ // file handler to write
103
+ $fileHandler = null;
104
+ $fileSizeInBytes = 0;
105
+
106
+ $listMember = array();
107
+ // the number of given members
108
+ $totalMemberCount = count($members);
109
+ try {
110
+ foreach ($members as $memberData) {
111
+ if (!$fileHandler) {
112
+ $this->_fileIndex++;
113
+ $fileData = call_user_func(
114
+ array($caller, self::PREPARE_FILE_NAME_METHOD),
115
+ $this->_fileIndex,
116
+ $memberData
117
+ );
118
+ $fileHandler = $this->getFileHandler($fileData['path']);
119
+
120
+ // write header fields into our file
121
+ $tmpLength = $csvTool->fputcsv($fileHandler, $headers, $delimiter, $enclosure);
122
+ if ($tmpLength) {
123
+ $fileSizeInBytes = $tmpLength;
124
+ }
125
+ $rowCount++;
126
+ }
127
+
128
+ $id = $memberData['id'];
129
+ $fields = $memberData['fields'];
130
+
131
+ $tmpLength = $csvTool->fputcsv($fileHandler, $fields, $delimiter, $enclosure);
132
+ if ($tmpLength) {
133
+ $fileSizeInBytes += $tmpLength;
134
+ }
135
+ $rowCount++;
136
+ $listMember[] = $id;
137
+
138
+ // If filesize approach max uploadable (48Mb), close file and set a new one on next turn
139
+ if (
140
+ $fileSizeInBytes > self::MAX_FILESIZE
141
+ || --$totalMemberCount == 0
142
+ || $rowCount >= self::MAX_ROW
143
+ ) {
144
+ fclose($fileHandler);
145
+ $fileHandler = null;
146
+ $generatedCsvData[] = array('file' => $fileData, 'list_member' => $listMember);
147
+ $rowCount = 0;
148
+ }
149
+ }
150
+ } catch (Exception $e) {
151
+ $this->throwEmailVisionException($e);
152
+ }
153
+ }
154
+ }
155
+
156
+ return $generatedCsvData;
157
+ }
158
+
159
+ /**
160
+ * @param array $headers
161
+ * @param array $members
162
+ * @return boolean
163
+ */
164
+ public function checkData(array $headers, array $members)
165
+ {
166
+ $result = true;
167
+ if (count($headers) == 0) {
168
+ $this->throwEmailVisionException('Please supply a list of header fields!');
169
+ }
170
+ if (count($members) && count($members[0]['fields']) != count($headers)) {
171
+ $this->throwEmailVisionException('Your members do not have the same fields as the header ones!');
172
+ }
173
+ return $result;
174
+ }
175
+
176
+ /**
177
+ * Get file handler for a given file path
178
+ * @param string $filePath
179
+ * @return resource
180
+ */
181
+ public function getFileHandler($filePath)
182
+ {
183
+ $streamHandler = @fopen($filePath, 'w');
184
+ if ($streamHandler === false) {
185
+ $this->throwEmailVisionException('Error write to file ' . $filePath);
186
+ }
187
+ return $streamHandler;
188
+ }
189
+
190
+ /**
191
+ * Prepare upload parameters and send file to webservice
192
+ *
193
+ * @param array $fileData
194
+ * @param array $mappingFields
195
+ * @param array $mergeCriteria
196
+ * @param string $closeApi
197
+ * @param string $skipFirstLine
198
+ * @param string $separator
199
+ * @return boolean
200
+ */
201
+ public function sendFileToWebservice(
202
+ array $fileData,
203
+ array $mappingFields,
204
+ $mergeCriteria = array(),
205
+ $closeApi = true,
206
+ $skipFirstLine = true,
207
+ $separator = self::CSV_FIELD_DELIMITER
208
+ )
209
+ {
210
+ $fileContent = false;
211
+ if (isset($fileData['path'])) {
212
+ $fileContent = file_get_contents($fileData['path']);
213
+ }
214
+
215
+ if ($fileContent === false) {
216
+ $this->throwEmailVisionException('Can not send file to Batch Member service. File content is empty');
217
+ }
218
+
219
+ $uploadId = false;
220
+ try {
221
+ $uploadParameters = array();
222
+ $uploadParameters['token'] = $this->openApiConnection();
223
+ $uploadParameters['mergeUpload']['fileName'] = $fileData['filename'];
224
+ $uploadParameters['mergeUpload']['fileEncoding'] = "UTF-8";
225
+ $uploadParameters['mergeUpload']['separator'] = $separator;
226
+ $uploadParameters['mergeUpload']['autoMapping'] = false;
227
+ $uploadParameters['mergeUpload']['skipFirstLine'] = $skipFirstLine;
228
+ $uploadParameters['mergeUpload']['dateFormat'] = 'MM/DD/YYYY HH24:MI:SS';
229
+ $uploadParameters['mergeUpload']['criteria'] = implode(',', $mergeCriteria);
230
+
231
+ $uploadParameters['file'] = $fileContent;
232
+
233
+ // prepare mapping fields
234
+ $colNum = 0;
235
+ $uploadParameters['mergeUpload']['mapping'] = array();
236
+ foreach ($mappingFields as $fieldName => $data) {
237
+ $uploadParameters['mergeUpload']['mapping'][] = array(
238
+ 'colNum' => ++$colNum,
239
+ 'fieldName' => strtoupper($fieldName),
240
+ 'toReplace' => $data['to_replace']
241
+ );
242
+ }
243
+
244
+ $wsResult = $this->soapCall('uploadFileMerge', $uploadParameters);
245
+ if (property_exists($wsResult, 'return')) {
246
+ $uploadId = $wsResult->return;
247
+ }
248
+ } catch (Exception $e) {
249
+ $this->decorateException($e);
250
+ $this->throwEmailVisionException($e);
251
+ }
252
+
253
+ if ($closeApi) {
254
+ $this->closeApiConnection();
255
+ }
256
+
257
+ return $uploadId;
258
+ }
259
+
260
+ /**
261
+ * This method provides the current status of an upload job.
262
+ * Pending status
263
+ * STORAGE: Upload file has been successfully uploaded and saved
264
+ * VALIDATED: Upload file has been successfully validated
265
+ * QUEUED: Upload has been queued for processing
266
+ * IMPORTING: Database import is starting
267
+ * Error status
268
+ * ERROR: File validation has failed
269
+ * FAILURE: Database import has failed
270
+ * Final status
271
+ * DONE: Upload is complete
272
+ * DONE WITH ERROR(S): Upload is complete but there were some errors
273
+
274
+ * @param string $uploadId
275
+ * @param string $closeApi
276
+ * @return boolean | string
277
+ */
278
+ public function getUploadStatus($uploadId, $closeApi = true)
279
+ {
280
+ $status = false;
281
+ try {
282
+ $params = array(
283
+ 'token' => $this->openApiConnection(),
284
+ 'uploadId' => $uploadId
285
+ );
286
+
287
+ $wsResult = $this->soapCall('getUploadStatus', $params);
288
+ if (property_exists($wsResult, 'return')) {
289
+ $status = array(
290
+ 'status' => '',
291
+ 'details' => ''
292
+ );
293
+ if (property_exists($wsResult->return, 'status')) {
294
+ $status['status'] = $wsResult->return->status;
295
+ }
296
+ if (property_exists($wsResult->return, 'details')) {
297
+ $status['details'] = $wsResult->return->details;
298
+ }
299
+ }
300
+ } catch (Exception $e) {
301
+ $this->decorateException($e);
302
+ $this->throwEmailVisionException($e);
303
+ }
304
+
305
+ if ($closeApi) {
306
+ $this->closeApiConnection();
307
+ }
308
+
309
+ return $status;
310
+ }
311
+
312
+ /**
313
+ * Get log file for an upload
314
+ *
315
+ * @param string $uploadId
316
+ * @param string $closeApi
317
+ * @return boolean -false | string
318
+ */
319
+ public function getLogFileForUpload($uploadId, $closeApi = true)
320
+ {
321
+ $logFile = false;
322
+ try {
323
+ $params = array(
324
+ 'token' => $this->openApiConnection(),
325
+ 'uploadId' => $uploadId
326
+ );
327
+
328
+ $wsResult = $this->soapCall('getLogFile', $params);
329
+ if (property_exists($wsResult, 'return')) {
330
+ $logFile = $wsResult->return;
331
+ }
332
+ } catch (Exception $e) {
333
+ if (stripos($e->getMessage(), 'READ_FILE_FAILED') === false) {
334
+ $this->decorateException($e);
335
+ $this->throwEmailVisionException($e);
336
+ }
337
+ }
338
+
339
+ if ($closeApi) {
340
+ $this->closeApiConnection();
341
+ }
342
+
343
+ return $logFile;
344
+ }
345
+
346
+ /**
347
+ * @param string $uploadId
348
+ * @param string $closeApi
349
+ * @return boolean - false | string - the file content
350
+ */
351
+ public function getBadFileForUpload($uploadId, $closeApi = true)
352
+ {
353
+ $badFile = false;
354
+ try {
355
+ $params = array(
356
+ 'token' => $this->openApiConnection(),
357
+ 'uploadId' => $uploadId
358
+ );
359
+
360
+ $wsResult = $this->soapCall('getBadFile', $params);
361
+ if (property_exists($wsResult, 'return')) {
362
+ $badFile = $wsResult->return;
363
+ }
364
+ } catch (Exception $e) {
365
+ if (stripos($e->getMessage(), 'READ_FILE_FAILED') === false) {
366
+ $this->decorateException($e);
367
+ $this->throwEmailVisionException($e);
368
+ }
369
+ }
370
+
371
+ if ($closeApi) {
372
+ $this->closeApiConnection();
373
+ }
374
+
375
+ return $badFile;
376
+ }
377
+
378
+ /**
379
+ * (non-PHPdoc)
380
+ * @see EmailVision_Api_Common::decorateException()
381
+ */
382
+ public function decorateException(Exception $e)
383
+ {
384
+ parent::decorateException($e);
385
+
386
+ if ($e instanceof EmailVision_Api_Exception) {
387
+ $messageException = $e->getMessage();
388
+ $message = '';
389
+
390
+ if (stripos($messageException, 'Too many uploads are still pending') !== false) {
391
+ $e->setCode(EmailVision_Api_Exception::EXCEED_UPLOAD_LIMIT);
392
+ }
393
+ if (stripos($messageException, 'Upload file is too big') !== false) {
394
+ $e->setCode(EmailVision_Api_Exception::EXCEED_UPLOAD_FILE_SIZE);
395
+ }
396
+ if (stripos($messageException, 'INVALID_PARAMETERS') !== false) {
397
+ $e->setCode(EmailVision_Api_Exception::INVALID_PARAMETER_UPLOAD);
398
+ }
399
+ if (stripos($messageException, 'GET_FLATUPLOAD_FAILED') !== false) {
400
+ $e->setCode(EmailVision_Api_Exception::INVALID_UPLOAD_ID);
401
+ $message = 'Your upload id does not exist on server!';
402
+ }
403
+
404
+ if ($message) {
405
+ $message .= ' - Details from server return : ' . $messageException;
406
+ $e->setMessage($message);
407
+ }
408
+ }
409
+ }
410
+ }
lib/EmailVision/Api/Common.php ADDED
@@ -0,0 +1,609 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Base Class for All APIs
4
+ *
5
+ * @category EmailVision
6
+ * @package EmailVision_Api
7
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
8
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
9
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License v. 3.0 (OSL-3.0)
10
+ */
11
+ class EmailVision_Api_Common
12
+ {
13
+ /**
14
+ * @var string
15
+ */
16
+ protected $_sessionId;
17
+
18
+ /**
19
+ * Stored last request method
20
+ *
21
+ * @var string
22
+ */
23
+ protected $_lastRequestMethod;
24
+
25
+ /**
26
+ * Stored last request data
27
+ *
28
+ * @var array
29
+ */
30
+ protected $_lastRequestData;
31
+
32
+ /**
33
+ * Api credential (login, pwd, key)
34
+ * @var array
35
+ */
36
+ protected $_apiCredentials = array();
37
+
38
+ /**
39
+ * Soap Client
40
+ *
41
+ * @var EmailVision_SoapClient
42
+ */
43
+ protected $_soapClient;
44
+
45
+ /**
46
+ * Retry limit for webservice call
47
+ */
48
+ const RETRY_LIMIT = 2;
49
+
50
+ /**
51
+ * Default Soap Client Class
52
+ */
53
+ const SOAP_CLIENT_CLASS = 'EmailVision_SoapClient';
54
+
55
+ /**
56
+ * Waiting time before every new webservice call
57
+ */
58
+ const WAITING_TIME = 2;
59
+
60
+ /**
61
+ * Webservice connection time out
62
+ */
63
+ const CONNECTION_TIME_OUT = 2;
64
+
65
+ /**
66
+ * Default options for API
67
+ *
68
+ * @var array
69
+ */
70
+ protected $_options = array(
71
+ 'soap_client' => self::SOAP_CLIENT_CLASS,
72
+ 'retry_limit' => self::RETRY_LIMIT,
73
+ 'debug' => false,
74
+
75
+ // SoapClient parameters
76
+ 'wsdl' => '',
77
+ 'location' => '',
78
+ 'proxy_host' => null,
79
+ 'proxy_port' => null,
80
+ 'soap_version' => SOAP_1_1,
81
+ 'compression' => true,
82
+ 'encoding' => 'UTF-8',
83
+ 'trace' => false,
84
+ 'exceptions' => true,
85
+ 'cache_wsdl' => WSDL_CACHE_BOTH,
86
+ 'user_agent' => 'EmailVision API',
87
+ 'connection_timeout' => self::CONNECTION_TIME_OUT,
88
+ );
89
+
90
+ public function __construct(array $options = array()) {
91
+ $this->_checkRequirements();
92
+ $this->setOptions($options);
93
+ }
94
+
95
+ /**
96
+ * Destructor
97
+ */
98
+ public function __destruct()
99
+ {
100
+ $this->closeApiConnection();
101
+ $this->_soapClient = null;
102
+ }
103
+
104
+ /**
105
+ * @param array $options
106
+ * @return EmailVision_Api_Abstract
107
+ */
108
+ protected function setOptions(array $options = array())
109
+ {
110
+ foreach ($options as $name => $value) {
111
+ $this->_setOption($name, $value);
112
+ }
113
+ return $this;
114
+ }
115
+
116
+ /**
117
+ * Check all requirements are valid to make a webservice call
118
+ *
119
+ * @return EmailVision_Api_Abstract
120
+ * @throws EmailVision_Api_Exception $e - in case of error
121
+ */
122
+ protected function _checkRequirements()
123
+ {
124
+ if (!extension_loaded('soap')) {
125
+ $this->throwEmailVisionException('SOAP extension is not loaded.');
126
+ }
127
+
128
+ if (!extension_loaded('openssl')) {
129
+ $this->throwEmailVisionException('OpenSSL extension is not loaded.');
130
+ }
131
+
132
+ return $this;
133
+ }
134
+
135
+ /**
136
+ * @param bool $value
137
+ * @return EmailVision_Api_Common
138
+ */
139
+ public function setDebug($value)
140
+ {
141
+ return $this->_setOption('debug', (bool) $value);
142
+ }
143
+
144
+ /**
145
+ * @return bool
146
+ */
147
+ public function getDebug()
148
+ {
149
+ return (bool) $this->_options['debug'];
150
+ }
151
+
152
+ /**
153
+ * @param string $name
154
+ * @param string $value
155
+ * @return EmailVision_Api_Abstract
156
+ */
157
+ protected function _setOption($name, $value)
158
+ {
159
+ if (array_key_exists($name, $this->_options)) {
160
+ // Some settings need checked
161
+ switch ($name) {
162
+ case 'soap_client':
163
+ if (!class_exists($value)) {
164
+ $this->throwEmailVisionException("Unable to load class: {$value} as SoapClient.");
165
+ }
166
+ break;
167
+ case 'soap_version':
168
+ if (!in_array($value, array(SOAP_1_1, SOAP_1_2))) {
169
+ $this->throwEmailVisionException('Invalid soap_version value specified. Use SOAP_1_1 or SOAP_1_2 constants.');
170
+ }
171
+ break;
172
+ case 'cache_wsdl':
173
+ if (!in_array($value, array(WSDL_CACHE_NONE, WSDL_CACHE_DISK, WSDL_CACHE_MEMORY, WSDL_CACHE_BOTH))) {
174
+ $this->throwEmailVisionException('Invalid cache_wsdl value specified.');
175
+ }
176
+ // If debug mode, ignore WSDL cache setting
177
+ if ($this->getDebug()) {
178
+ $value = WSDL_CACHE_NONE;
179
+ }
180
+ break;
181
+ case 'debug':
182
+ if ($value == true) {
183
+ $this->_options['trace'] = true;
184
+ $this->_options['cache_wsdl'] = WSDL_CACHE_NONE;
185
+ }
186
+ break;
187
+ }
188
+
189
+ $this->_options[$name] = $value;
190
+ }
191
+
192
+ return $this;
193
+ }
194
+
195
+ /**
196
+ * Get soap client - if soap client is null, try to create a new one with default configurations
197
+ *
198
+ * @return EmailVision_SoapClient
199
+ */
200
+ public function getSoapClient()
201
+ {
202
+ // create soap client with default options
203
+ if (is_null($this->_soapClient)) {
204
+ $this->_initSoapClient();
205
+ }
206
+
207
+ return $this->_soapClient;
208
+ }
209
+
210
+ /**
211
+ * @param SoapClient $soapClient
212
+ * @return EmailVision_Api_Abstract
213
+ */
214
+ public function setSoapClient(SoapClient $soapClient)
215
+ {
216
+ $this->_soapClient = $soapClient;
217
+ return $this;
218
+ }
219
+
220
+ /**
221
+ * Initialize soap client with available options
222
+ *
223
+ * @return EmailVision_Api_Abstract
224
+ */
225
+ protected function _initSoapClient()
226
+ {
227
+ // check wsdl or service location is valid
228
+ if (
229
+ (!isset($this->_options['wsdl']) || empty($this->_options['wsdl']))
230
+ && (!isset($this->_options['location']) || empty($this->_options['location']))
231
+ ) {
232
+ $this->throwEmailVisionException('Please provide WSDL emplacement or Server location in options');
233
+ }
234
+
235
+ // Retreive client class
236
+ $soapClientClass = $this->_options['soap_client'];
237
+ // Set compression option for soapclient
238
+ $this->_options['compression'] = SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_GZIP;
239
+
240
+ // Create soap client
241
+ $this->_soapClient = new $soapClientClass(
242
+ $this->_options['wsdl'],
243
+ array(
244
+ 'soap_version' => $this->_options['soap_version'],
245
+ 'compression' => $this->_options['compression'],
246
+ 'encoding' => $this->_options['encoding'],
247
+ 'trace' => $this->_options['trace'],
248
+ 'exceptions' => $this->_options['exceptions'],
249
+ 'cache_wsdl' => $this->_options['cache_wsdl'],
250
+ 'user_agent' => $this->_options['user_agent'],
251
+ 'connection_timeout' => $this->_options['connection_timeout'],
252
+ 'proxy_host' => $this->_options['proxy_host'],
253
+ 'proxy_port' => $this->_options['proxy_port'],
254
+ )
255
+ );
256
+ // Set soap service location
257
+ $this->_soapClient->__setLocation($this->_options['location']);
258
+
259
+ return $this;
260
+ }
261
+
262
+ /**
263
+ * Custom exception handling.
264
+ * Last Soap request and response will be added in the exception if debug mode is activated
265
+ *
266
+ * @param string|Exception $exception
267
+ * @param string $message
268
+ * @param string $code
269
+ * @throws EmailVision_Api_Exception
270
+ */
271
+ public function throwEmailVisionException($exception, $message = null, $code = null)
272
+ {
273
+ if ($exception instanceOf Exception) {
274
+ if (! $exception instanceOf EmailVision_Api_Exception) {
275
+ // Convert
276
+ $exception = new EmailVision_Api_Exception(
277
+ $exception->getMessage(),
278
+ $exception->getCode(),
279
+ null,
280
+ $exception
281
+ );
282
+ }
283
+ } else {
284
+ if (is_string($exception)) {
285
+ if (class_exists($exception, false)) {
286
+ $exception = new $exception($message, $code);
287
+ } else {
288
+ $exception = new EmailVision_Api_Exception($exception);
289
+ }
290
+ }
291
+ }
292
+
293
+ // For tracking request/response in debug mode
294
+ if ($this->getDebug() && $exception instanceof EmailVision_Api_Exception) {
295
+ /* @var $exception EmailVision_Api_Exception */
296
+ $exception->setRequest($this->getLastRequest());
297
+ $exception->setResponse($this->getLastResponse());
298
+ }
299
+
300
+ throw $exception;
301
+ }
302
+
303
+ /**
304
+ * Decorate exception with a new eventual error message and a new eventual error code
305
+ * @param Exception $e
306
+ */
307
+ public function decorateException(Exception $e)
308
+ {
309
+ if ($e instanceof EmailVision_Api_Exception) {
310
+ $messageException = $e->getMessage();
311
+ $message = '';
312
+ if ($e->isRecoverable()) {
313
+ $message = 'You have some problems to connect to EmailVision webservices. Please check your network settings or the webservice urls!';
314
+ } else {
315
+ if (stripos($messageException, 'OPEN_CONNECTION_FAILED') !== false) {
316
+ $message = 'Your API credential is invalid. Please correct it !';
317
+ // change error code to invalid credential
318
+ $e->setCode(EmailVision_Api_Exception::INVALID_CREDENTIAL);
319
+ } else if (stripos($messageException, 'Your session has expired due to timeout') !== false) {
320
+ // change error code to expired security token
321
+ $e->setCode(EmailVision_Api_Exception::EXPIRED_SECURITY_TOKEN);
322
+ } else {
323
+ $e->setCode(EmailVision_Api_Exception::APPLICATION_ERROR);
324
+ }
325
+ }
326
+
327
+ if ($message) {
328
+ $message .= ' - Details from server return : ' . $messageException;
329
+ $e->setMessage($message);
330
+ }
331
+ }
332
+ }
333
+
334
+ /**
335
+ * Retrieve request XML
336
+ *
337
+ * @return string
338
+ */
339
+ public function getLastRequest()
340
+ {
341
+ if ($this->_soapClient !== null) {
342
+ return $this->_soapClient->__getLastRequest();
343
+ }
344
+
345
+ return '';
346
+ }
347
+
348
+ /**
349
+ * Get response XML
350
+ *
351
+ * @return string
352
+ */
353
+ public function getLastResponse()
354
+ {
355
+ if ($this->_soapClient !== null) {
356
+ return $this->_soapClient->__getLastResponse();
357
+ }
358
+
359
+ return '';
360
+ }
361
+
362
+ /**
363
+ * Retrieve request headers
364
+ *
365
+ * @return string
366
+ */
367
+ public function getLastRequestHeaders()
368
+ {
369
+ if ($this->_soapClient !== null) {
370
+ return $this->getSoapClient()->__getLastRequestHeaders();
371
+ }
372
+
373
+ return '';
374
+ }
375
+
376
+ /**
377
+ * Retrieve response headers (as string)
378
+ *
379
+ * @return string
380
+ */
381
+ public function getLastResponseHeaders()
382
+ {
383
+ if ($this->_soapClient !== null) {
384
+ return $this->getSoapClient()->__getLastResponseHeaders();
385
+ }
386
+
387
+ return '';
388
+ }
389
+
390
+ /**
391
+ * Re-Initialize Api object
392
+ *
393
+ * @return EmailVision_Api_Abstract
394
+ */
395
+ public function reInit()
396
+ {
397
+ $this->_soapClient = null;
398
+ $this->_sessionId = null;
399
+
400
+ return $this;
401
+ }
402
+
403
+ /**
404
+ * Set api credentials - need to supply
405
+ * - login : login
406
+ * - pwd : password
407
+ * - key : Api key
408
+ *
409
+ * @param array $credentials
410
+ * @return EmailVision_Api_Abstract
411
+ */
412
+ public function setApiCredentials(array $credentials = array())
413
+ {
414
+ $this->_apiCredentials = $credentials;
415
+ return $this;
416
+ }
417
+
418
+ /**
419
+ * @return array
420
+ */
421
+ public function getApiCredentials()
422
+ {
423
+ return $this->_apiCredentials;
424
+ }
425
+
426
+ /**
427
+ * Verify whether all api credentials are valid
428
+ *
429
+ * @return EmailVision_Api_Abstract
430
+ * @throws EmailVision_Api_Exception $e - in case of invalid api credentials
431
+ */
432
+ protected function _verifyApiCredentials()
433
+ {
434
+ $isOk = false;
435
+
436
+ if (
437
+ is_array($this->_apiCredentials)
438
+ && count($this->_apiCredentials) == 3
439
+ && isset($this->_apiCredentials['login'])
440
+ && isset($this->_apiCredentials['pwd'])
441
+ && isset($this->_apiCredentials['key'])
442
+ ) {
443
+ $isOk = true;
444
+ }
445
+
446
+ if (!$isOk) {
447
+ $this->throwEmailVisionException('Please provide valid EmailVision Credentials (Login, Passsword, and Api Key)');
448
+ }
449
+
450
+ return $this;
451
+ }
452
+
453
+ /**
454
+ * @param string $method
455
+ * @param array $data
456
+ * @return EmailVision_Api_Abstract
457
+ */
458
+ protected function _beforeRequest($method, array $data = array())
459
+ {
460
+ // Do nothing;
461
+ return $this;
462
+ }
463
+
464
+ /**
465
+ * Perform arguments pre-processing
466
+ *
467
+ * My be overridden in descendant classes
468
+ *
469
+ * @param array $arguments
470
+ */
471
+ protected function _preProcessArguments($arguments)
472
+ {
473
+ // Do nothing
474
+ return $arguments;
475
+ }
476
+
477
+ /**
478
+ * Perform result pre-processing
479
+ *
480
+ * My be overridden in descendant classes
481
+ *
482
+ * @param array $arguments
483
+ */
484
+ protected function _preProcessResult($result)
485
+ {
486
+ // Do nothing
487
+ return $result;
488
+ }
489
+
490
+ /**
491
+ * @return string
492
+ */
493
+ public function getLastRequestMethod()
494
+ {
495
+ return $this->_lastRequestMethod;
496
+ }
497
+
498
+ /**
499
+ * @return array
500
+ */
501
+ public function getLastRequestData()
502
+ {
503
+ return $this->_lastRequestData;
504
+ }
505
+
506
+ /**
507
+ * Make a soap call to webservice with a given method, and an eventual array of parameters
508
+ *
509
+ * @param string $method
510
+ * @param array $param
511
+ */
512
+ public function soapCall($method, array $param = array())
513
+ {
514
+ $this->_beforeRequest($method, $param);
515
+
516
+ $maxAttemps = (int) $this->_options['retry_limit'];
517
+ $success = false;
518
+ $result = array();
519
+
520
+ for ($tries = 0; $tries <= $maxAttemps && !$success; $tries++) {
521
+ $error = false;
522
+
523
+ try {
524
+ // Store this request in case we need to retry later
525
+ $this->_lastRequestMethod = $method;
526
+ $this->_lastRequestData = $param;
527
+
528
+ // Prepare arguments
529
+ $param = $this->_preProcessArguments($param);
530
+ // call method with given parameters
531
+ $result = $this->getSoapClient()->$method($param);
532
+ } catch (Exception $e) {
533
+ $error = true;
534
+ $exception = new EmailVision_Api_Exception($e->getMessage(), $e->getCode(), $tries, $e);
535
+
536
+ if (!$exception->isRecoverable() || $tries === $maxAttemps) {
537
+ $this->throwEmailVisionException($exception);
538
+ } else {
539
+ // Waiting self::WAITING_TIME second before submitting a new request
540
+ sleep(self::WAITING_TIME);
541
+ }
542
+ }
543
+
544
+ if (!$error) {
545
+ $success = true;
546
+ }
547
+ }
548
+
549
+ return $this->_preProcessResult($result);
550
+ }
551
+
552
+ /**
553
+ * Login action.
554
+ *
555
+ * @return string session id
556
+ * @throws EmailVision_Api_Exception $exception
557
+ */
558
+ public function openApiConnection ()
559
+ {
560
+ if (null != $this->_sessionId) {
561
+ return $this->_sessionId;
562
+ }
563
+
564
+ // verify if api credentials are valid
565
+ $this->_verifyApiCredentials();
566
+
567
+ try {
568
+ $params = array(
569
+ 'login' => $this->_apiCredentials['login'],
570
+ 'pwd' => $this->_apiCredentials['pwd'],
571
+ 'key' => $this->_apiCredentials['key']
572
+ );
573
+ // use openApiConnection method
574
+ $wsResult = $this->soapCall('openApiConnection', $params);
575
+
576
+ } catch (Exception $e) {
577
+ // treat problem
578
+ $this->throwEmailVisionException($e);
579
+ }
580
+
581
+ if (!isset($wsResult->return)) {
582
+ $this->throwEmailVisionException('Unknown Error. Could not determine token from soap service return');
583
+ }
584
+
585
+ $this->_sessionId = $wsResult->return;
586
+
587
+ return $this->_sessionId;
588
+ }
589
+
590
+ /**
591
+ * Close the Api connection
592
+ *
593
+ * @param string $sessionId
594
+ * @throws EmailVision_Api_Exception $exception
595
+ */
596
+ public function closeApiConnection()
597
+ {
598
+ try {
599
+ if ($this->_sessionId) {
600
+ $this->soapCall('closeApiConnection', array('token' => $this->_sessionId));
601
+ $this->_sessionId = null;
602
+ }
603
+ } catch (Exception $e) {
604
+ $this->throwEmailVisionException($e);
605
+ }
606
+
607
+ return $this;
608
+ }
609
+ }
lib/EmailVision/Api/Exception.php ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EmailVision Api Exception
4
+ *
5
+ * @category EmailVision
6
+ * @package EmailVision_Api
7
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
8
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
9
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License v. 3.0 (OSL-3.0)
10
+ */
11
+ class EmailVision_Api_Exception extends Exception
12
+ {
13
+ /* Misc */
14
+ const HTTP_HEADER_ERROR = 98001; // Error Fetching http headers
15
+ const NO_XML_DOCUMENT = 98002;
16
+ const INVALID_URL = 98003;
17
+ const CONNECT_ERROR = 98004;
18
+ const WSDL_PARSE_ERROR = 98005; // SOAP-ERROR: Parsing WSDL
19
+ const REQUEST_ERROR = 98006;
20
+ const CONNECTION_RESET = 98007; // SSL: Connection reset by peer
21
+ const CONNECTION_FAILED = 98008; // Could not connect to host
22
+ const SERVICE_UNAVAILABLE = 98009; // Service Temporarily Unavailable
23
+ const SOAPCLIENT_ERROR = 98010; // SoapClient::__doRequest(): %s
24
+ const SERVER_ERROR = 98500; // Internal Server Error
25
+
26
+ const APPLICATION_ERROR = 98030;
27
+
28
+ /**
29
+ * Login problems
30
+ */
31
+ const INVALID_CREDENTIAL = 98040;
32
+ const EXPIRED_SECURITY_TOKEN = 98041;
33
+
34
+ /**
35
+ * Can't retreive the template
36
+ */
37
+ const INVALID_TEMPLATE_ID = 98050;
38
+
39
+ /**
40
+ * Error with sending parameters (random, encrypt, or email address) !
41
+ */
42
+ const INVALID_EMAIL_SENDING_PARAMETERS = 98060;
43
+
44
+ /**
45
+ * Exceed allowed rejoin member call limit
46
+ */
47
+ const EXCEED_REJOIN_MEMBER_LIMIT = 98070;
48
+
49
+ /**
50
+ * Error codes relative to batch member calls
51
+ */
52
+ const EXCEED_UPLOAD_LIMIT = 98081; // you have reached the limit of uploads at the same time
53
+ const EXCEED_UPLOAD_FILE_SIZE = 98082; // you have reached the limit of upload file size
54
+ const INVALID_PARAMETER_UPLOAD = 98083; // the upload parameters are invalid
55
+ const INVALID_UPLOAD_ID = 98084; // the upload id is invalid
56
+
57
+ /**
58
+ * Array of exceptions we can (maybe) recover from
59
+ * @var array
60
+ */
61
+ protected $_recoverable = array(
62
+ self::HTTP_HEADER_ERROR,
63
+ self::NO_XML_DOCUMENT,
64
+ self::CONNECT_ERROR,
65
+ self::WSDL_PARSE_ERROR,
66
+ self::CONNECTION_RESET,
67
+ self::CONNECTION_FAILED,
68
+ self::SERVICE_UNAVAILABLE,
69
+ self::SERVER_ERROR,
70
+ self::SOAPCLIENT_ERROR,
71
+ );
72
+
73
+ /**
74
+ * @var string
75
+ */
76
+ protected $_request;
77
+
78
+ /**
79
+ * @var string
80
+ */
81
+ protected $_response;
82
+
83
+ /**
84
+ * For PHP <5.3.0
85
+ *
86
+ * @var Exception
87
+ */
88
+ protected $_previous;
89
+
90
+ /**
91
+ * @param string $message
92
+ * @param string $code
93
+ * @param int $tries
94
+ * @param Exception $previous
95
+ */
96
+ public function __construct($message = '', $code = 0, $tries = null, Exception $previous = null)
97
+ {
98
+ if (empty($code)) {
99
+ // try to get error code from given message
100
+ $parts = explode(':', $message, 2);
101
+ if (is_array($parts)) {
102
+ $parts = array_map('trim', $parts);
103
+ }
104
+ if (isset($parts[0]) && is_numeric($parts[0])) {
105
+ $code = (int) $parts[0];
106
+ $message = (string) $parts[1];
107
+ }
108
+ }
109
+
110
+ if (empty($code)) {
111
+ // Handle some SoapFault exceptions
112
+ if (stripos($message, 'Error Fetching http headers') !== false) {
113
+ $code = self::HTTP_HEADER_ERROR;
114
+ } else if (stripos($message, 'looks like we got no XML document') !== false) {
115
+ $code = self::NO_XML_DOCUMENT;
116
+ } else if (stripos($message, 'Could not connect to host') !== false) {
117
+ $code = self::CONNECT_ERROR;
118
+ } else if (stripos($message, 'Parsing WSDL') !== false) {
119
+ $code = self::WSDL_PARSE_ERROR;
120
+ } else if (stripos($message, 'There was an error in your soap request') !== false) {
121
+ $code = self::REQUEST_ERROR;
122
+ } else if (stripos($message, 'Connection reset by peer') !== false) {
123
+ $code = self::CONNECTION_RESET;
124
+ } else if (stripos($message, 'Unable to parse URL') !== false) {
125
+ $code = self::INVALID_URL;
126
+ } else if (stripos($message, 'Service Temporarily Unavailable') !== false) {
127
+ $code = self::SERVICE_UNAVAILABLE;
128
+ } else if (stripos($message, 'Internal Server Error') !== false) {
129
+ $code = self::SERVER_ERROR;
130
+ } else if (stripos($message, 'SoapClient::__doRequest()') !== false) {
131
+ $code = self::SOAPCLIENT_ERROR;
132
+ }
133
+ }
134
+
135
+ if (!empty($code)) {
136
+ $message = "{$code} : {$message}";
137
+ }
138
+
139
+ if (!empty($tries) && $tries > 1) {
140
+ $message .= " [Tried: {$tries}]";
141
+ }
142
+
143
+ // manipulate detail code if not empty
144
+ if (empty($code) && $previous != null && $previous instanceof SoapFault) {
145
+ if (isset($previous->{'detail'})) {
146
+ $detail = $previous->{'detail'};
147
+ $message .= "\n" . ' with detail - ' . print_r($detail, true);
148
+ }
149
+ }
150
+
151
+ if (version_compare(PHP_VERSION, '5.3.0') >= 0) {
152
+ parent::__construct($message, $code, $previous);
153
+ } else {
154
+ $this->_previous = $previous;
155
+ parent::__construct($message, $code);
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Set error code
161
+ *
162
+ * @param int $code
163
+ * @return EmailVision_Api_Exception
164
+ */
165
+ public function setCode($code)
166
+ {
167
+ $this->code = $code;
168
+ return $this;
169
+ }
170
+ /**
171
+ * Is exception recoverable by verifying its code ?
172
+ *
173
+ * @return bool
174
+ */
175
+ public function isRecoverable()
176
+ {
177
+ if (!$this->getCode()) {
178
+ return false;
179
+ }
180
+ return in_array($this->getCode(), $this->_recoverable);
181
+ }
182
+
183
+ /**
184
+ * @param string $message
185
+ */
186
+ public function setMessage($message)
187
+ {
188
+ $this->message = $message;
189
+ }
190
+
191
+ /**
192
+ * @param string $text
193
+ */
194
+ public function appendToMessage($text)
195
+ {
196
+ $this->message .= " {$text}";
197
+ }
198
+
199
+ /**
200
+ * Set webservice request
201
+ *
202
+ * @param string $request
203
+ * @return EmailVision_Api_Exception
204
+ */
205
+ public function setRequest($request)
206
+ {
207
+ $this->_request = $request;
208
+ return $this;
209
+ }
210
+
211
+ /**
212
+ * Get webservice request
213
+ *
214
+ * @return string
215
+ */
216
+ public function getRequest()
217
+ {
218
+ return $this->_request;
219
+ }
220
+
221
+ /**
222
+ * Set server response for webservice call
223
+ *
224
+ * @param string $response
225
+ * @return EmailVision_Api_Exception
226
+ */
227
+ public function setResponse($response)
228
+ {
229
+ $this->_response = $response;
230
+ return $this;
231
+ }
232
+
233
+ /**
234
+ * Get response from webservice call
235
+ *
236
+ * @return string
237
+ */
238
+ public function getResponse()
239
+ {
240
+ return $this->_response;
241
+ }
242
+
243
+ /**
244
+ * Get previous exception
245
+ *
246
+ * For PHP <5.3.0
247
+ * @return Exception|null
248
+ */
249
+ public function getPreviousException()
250
+ {
251
+ if (method_exists($this, 'getPrevious')) {
252
+ return $this->getPrevious();
253
+ }
254
+ return $this->getPreviousException();
255
+ }
256
+
257
+ /**
258
+ * Get function calling trace for debugging
259
+ *
260
+ * @return array
261
+ */
262
+ public function getTraceSafe()
263
+ {
264
+ if (!isset($this->_trace)) {
265
+ $this->_trace = $this->getTrace();
266
+ if (empty($this->_trace)) {
267
+ $backtrace = debug_backtrace();
268
+ $this->_trace = array($backtrace[count($backtrace)-1]);
269
+ }
270
+ }
271
+ return $this->_trace;
272
+ }
273
+
274
+ /**
275
+ * @return string
276
+ */
277
+ public function getErrorClass()
278
+ {
279
+ $trace = $this->getTraceSafe();
280
+ return $trace[0]['class'];
281
+ }
282
+
283
+ /**
284
+ * @return string
285
+ */
286
+ public function getErrorMethod()
287
+ {
288
+ $trace = $this->getTraceSafe();
289
+ return $trace[0]['function'];
290
+ }
291
+ }
lib/EmailVision/Api/MemberService.php ADDED
@@ -0,0 +1,346 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Member Service Api - Data member updates
4
+ *
5
+ * @category EmailVision
6
+ * @package EmailVision_Api
7
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
8
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
9
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License v. 3.0 (OSL-3.0)
10
+ */
11
+ class EmailVision_Api_MemberService extends EmailVision_Api_Common
12
+ {
13
+ const LIMIT_CALL_PER_DAY = 500;
14
+ const LIMIT_CALL_REJOIN_PER_DAY = 50;
15
+
16
+ const SEPARATOR_FIELD_CONDITION_MEMBER_UID = ':';
17
+ const SEPARATOR_MEMBER_UID_FIELD = '|';
18
+
19
+ /**
20
+ * Describe the member table in SmartFocus platform
21
+ *
22
+ * @param booelan $closeApi - indicate if need to close api after query
23
+ * @return array - contains all the table field (each field is charactirised by name and type)
24
+ */
25
+ public function descMemberTable($closeApi = true)
26
+ {
27
+ $listFields = array();
28
+ try {
29
+ $params = array(
30
+ 'token' => $this->openApiConnection(),
31
+ );
32
+
33
+ $wsResult = $this->soapCall('descMemberTable', $params);
34
+ if (
35
+ property_exists($wsResult, 'return')
36
+ && property_exists($wsResult->return, 'fields')
37
+ && is_array($wsResult->return->fields)
38
+ ) {
39
+ foreach ($wsResult->return->fields as $field) {
40
+ $listFields[] = array(
41
+ 'name' => $field->name,
42
+ 'type' => $field->type
43
+ );
44
+ }
45
+ }
46
+ } catch (Exception $e) {
47
+ $this->decorateException($e);
48
+ $this->throwEmailVisionException($e);
49
+ }
50
+
51
+ if ($closeApi) {
52
+ $this->closeApiConnection();
53
+ }
54
+
55
+ return $listFields;
56
+ }
57
+
58
+ /**
59
+ * Prepare memberUID field for query
60
+ *
61
+ * @param array $listCriteria - associative array with :
62
+ * - key => the field for which the condition is verified
63
+ * - value => the condition
64
+ * @return string
65
+ */
66
+ public function prepareMemberUidForWebservice($listCriteria = array())
67
+ {
68
+ // create member uid
69
+ $memberUid = array();
70
+ foreach ($listCriteria as $field => $condition) {
71
+ // all fields need to be in UPPER CASE
72
+ $memberUid[] = strtoupper($field) . self::SEPARATOR_FIELD_CONDITION_MEMBER_UID . $condition;
73
+ }
74
+ return implode(self::SEPARATOR_MEMBER_UID_FIELD, $memberUid);
75
+ }
76
+
77
+ /**
78
+ * Get list of members (50 members at maximum are allowed to be returned)
79
+ * that match the given criteria
80
+ * - list of criteria needs to be associative array.
81
+ * Example : 'email' => 'test@sample.com', 'firstname' => 'john'...
82
+ *
83
+ * @param array $listCriteria
84
+ * @param string $closeApi
85
+ * @return array
86
+ */
87
+ public function getListMembersByObj($listCriteria = array(), $closeApi = true)
88
+ {
89
+ $listMembers = array();
90
+
91
+ $memberUid = $this->prepareMemberUidForWebservice($listCriteria);
92
+ if ($memberUid) {
93
+ try {
94
+ $params = array(
95
+ 'token' => $this->openApiConnection(),
96
+ 'member' => array(
97
+ 'dynContent' => '',
98
+ 'memberUID' => $memberUid
99
+ )
100
+ );
101
+
102
+ $wsResult = $this->soapCall('getListMembersByObj', $params);
103
+ $tmpList = array();
104
+ if (property_exists($wsResult, 'return')) {
105
+ // the return can be an array or an object
106
+ $tmpList = $wsResult->return;
107
+ if (!is_array($wsResult->return)) {
108
+ $tmpList = array($wsResult->return);
109
+ }
110
+
111
+ foreach($tmpList as $member) {
112
+ if (
113
+ property_exists($member, 'attributes')
114
+ && property_exists($member->attributes, 'entry')
115
+ && is_array($member->attributes->entry)
116
+ ) {
117
+ $memberFields = array();
118
+ foreach ($member->attributes->entry as $field) {
119
+ if (isset($field->key)) {
120
+ $memberFields[$field->key] = (isset($field->value))
121
+ ? $field->value : '';
122
+ }
123
+ }
124
+ if (count($memberFields)) {
125
+ $listMembers[] = $memberFields;
126
+ }
127
+ }
128
+ }
129
+ }
130
+ } catch (Exception $e) {
131
+ $this->decorateException($e);
132
+ $this->throwEmailVisionException($e);
133
+ }
134
+
135
+ if ($closeApi) {
136
+ $this->closeApiConnection();
137
+ }
138
+ }
139
+
140
+ return $listMembers;
141
+ }
142
+
143
+ /**
144
+ * Re-join members that match the given condition.
145
+ * - field can be email or SmartFocus member id
146
+ * - example :
147
+ * 1. field = 'email' , condition = 'test@sample.com'
148
+ * 2. field = 'id' , condtion = 12345678
149
+ * EmailVision imposes a limit of 50 calls per day
150
+ *
151
+ * @param string $field
152
+ * @param string $condition
153
+ * @param boolean $closeApi
154
+ * @return boolean | string - upload id
155
+ */
156
+ public function rejoinMember($field, $condition, $closeApi = true)
157
+ {
158
+ $result = false;
159
+ try {
160
+ $params = array(
161
+ 'token' => $this->openApiConnection()
162
+ );
163
+
164
+ $methodToCall = '';
165
+ $webserviceField = '';
166
+ switch($field)
167
+ {
168
+ case 'email' :
169
+ $methodToCall = 'rejoinMemberByEmail';
170
+ $webserviceField = 'email';
171
+ break;
172
+ default :
173
+ $methodToCall = 'rejoinMemberById';
174
+ $webserviceField = 'memberId';
175
+ break;
176
+ }
177
+ $params[$webserviceField] = $condition;
178
+
179
+ $wsResult = $this->soapCall($methodToCall, $params);
180
+ if (property_exists($wsResult, 'return')) {
181
+ $result = $wsResult->return;
182
+ }
183
+ } catch (Exception $e) {
184
+ $this->decorateException($e);
185
+ $this->throwEmailVisionException($e);
186
+ }
187
+
188
+ if ($closeApi) {
189
+ $this->closeApiConnection();
190
+ }
191
+
192
+ return $result;
193
+ }
194
+
195
+ /**
196
+ * Unjoin members that match the given condition
197
+ * - field can be : email, object (the only way to supply a multiple of conditions), or SmartFocus member's id
198
+ * - Example :
199
+ * 1. field = 'email' , condition = 'test@samples.com'
200
+ * 2. field = 'object', condition = array(
201
+ * 'email' => 'test@samples.com',
202
+ * 'firstname' => 'john'
203
+ * 'member_id' => 1234567 // SmartFocus member's id
204
+ * )
205
+ * 3. field = 'id' , condition = 1234567
206
+ *
207
+ * @param string $field
208
+ * @param string $condition
209
+ * @param boolean $closeApi
210
+ * @return boolean
211
+ */
212
+ public function unjoinMember($field, $condition, $closeApi = true)
213
+ {
214
+ $result = false;
215
+ try {
216
+ $params = array(
217
+ 'token' => $this->openApiConnection()
218
+ );
219
+
220
+ $methodToCall = '';
221
+ $webserviceField = '';
222
+ switch($field)
223
+ {
224
+ case 'email' :
225
+ $methodToCall = 'unjoinMemberByEmail';
226
+ $webserviceField = 'email';
227
+ break;
228
+
229
+ case 'object' :
230
+ $methodToCall = 'unjoinMemberByObj';
231
+ $webserviceField = 'member';
232
+
233
+ // the condition for method unjoinMemberByObj is totally different from another ones
234
+ if (!is_array($condition)) {
235
+ $condition = array();
236
+ }
237
+ $condition = $this->prepareMemberUidForWebservice($condition);
238
+ if ($condition) {
239
+ $condition = array(
240
+ 'dynContent' => '',
241
+ 'memberUID' => $condition
242
+ );
243
+ }
244
+ break;
245
+
246
+ default :
247
+ $methodToCall = 'unjoinMemberById';
248
+ $webserviceField = 'memberId';
249
+ break;
250
+ }
251
+
252
+ // only call the webservice if condition is not empty
253
+ if ($condition) {
254
+ $params[$webserviceField] = $condition;
255
+ $wsResult = $this->soapCall($methodToCall, $params);
256
+ if (property_exists($wsResult, 'return')) {
257
+ $result = true;
258
+ }
259
+ }
260
+ } catch (Exception $e) {
261
+ $this->decorateException($e);
262
+ $this->throwEmailVisionException($e);
263
+ }
264
+
265
+ if ($closeApi) {
266
+ $this->closeApiConnection();
267
+ }
268
+
269
+ return $result;
270
+ }
271
+
272
+ /**
273
+ * Prepare DynContent Array for api calls
274
+ *
275
+ * @param array $param
276
+ * @return array
277
+ */
278
+ public function prepareDynContentArray(array $param)
279
+ {
280
+ $preparedArray = array();
281
+ foreach($param as $key => $value) {
282
+ $preparedArray['entry'][] = array('key' => $key, 'value' => $value);
283
+ }
284
+ return $preparedArray;
285
+ }
286
+
287
+ /**
288
+ * @param array $listCriteria - criteria list for searching members
289
+ * @param array $param - list of fields and the value to update
290
+ * @param boolean $closeApi
291
+ */
292
+ public function insertOrUpdateMemberByObj(array $listCriteria, $param = array(), $closeApi = true)
293
+ {
294
+ $memberUid = $this->prepareMemberUidForWebservice($listCriteria);
295
+ $dynContent = $this->prepareDynContentArray($param);
296
+ $uploadId = false;
297
+
298
+ if ($memberUid) {
299
+ try {
300
+ $params = array(
301
+ 'token' => $this->openApiConnection(),
302
+ 'member' => array(
303
+ 'dynContent' => $dynContent,
304
+ 'memberUID' => $memberUid
305
+ )
306
+ );
307
+
308
+ $wsResult = $this->soapCall('insertOrUpdateMemberByObj', $params);
309
+ if (property_exists($wsResult, 'return')) {
310
+ $uploadId = $wsResult->return;
311
+ }
312
+ } catch (Exception $e) {
313
+ $this->decorateException($e);
314
+ $this->throwEmailVisionException($e);
315
+ }
316
+
317
+ if ($closeApi) {
318
+ $this->closeApiConnection();
319
+ }
320
+ }
321
+
322
+ return $uploadId;
323
+ }
324
+
325
+ /**
326
+ * (non-PHPdoc)
327
+ * @see EmailVision_Api_Common::decorateException()
328
+ */
329
+ public function decorateException(Exception $e)
330
+ {
331
+ parent::decorateException($e);
332
+
333
+ if ($e instanceof EmailVision_Api_Exception) {
334
+ $messageException = $e->getMessage();
335
+ $message = '';
336
+ if (stripos($messageException, 'the maximum number of rejoins') !== false) {
337
+ $e->setCode(EmailVision_Api_Exception::EXCEED_REJOIN_MEMBER_LIMIT);
338
+ }
339
+
340
+ if ($message) {
341
+ $message .= ' - Details from server return : ' . $messageException;
342
+ $e->setMessage($message);
343
+ }
344
+ }
345
+ }
346
+ }
lib/EmailVision/Api/NotificationService.php ADDED
@@ -0,0 +1,345 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Notification (Transactional Message Trigger) Api
4
+ *
5
+ * @category EmailVision
6
+ * @package EmailVision_Api
7
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
8
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
9
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License v. 3.0 (OSL-3.0)
10
+ */
11
+ class EmailVision_Api_NotificationService extends EmailVision_Api_Common
12
+ {
13
+ /**
14
+ * Default REST service url
15
+ */
16
+ const REST_SERVICE_URL = 'https://api.notificationmessaging.com/NMSXML';
17
+
18
+ /**
19
+ * Rest service url
20
+ *
21
+ * @var string
22
+ */
23
+ protected $_restServiceUrl = null;
24
+
25
+ /**
26
+ * HTTP response status codes for REST service
27
+ */
28
+ const REST_STATUS_OK = 200;
29
+ const NOT_FOUND_SERVICE = 404;
30
+ const INTERNAL_SERVER_ERROR = 500;
31
+
32
+ /**
33
+ * Curl status code
34
+ */
35
+ const CURLE_COULDNT_RESOLVE_PROXY = 5;
36
+ const CURLE_COULDNT_RESOLVE_HOST = 6;
37
+ const CURLE_COULDNT_CONNECT = 7;
38
+ const CURLE_OPERATION_TIMEDOUT = 28;
39
+
40
+ /**
41
+ * Connection time out for rest service - The number of seconds to wait while trying to connect.
42
+ */
43
+ const REST_CONNECTION_TIME = 1;
44
+
45
+ /**
46
+ * Time out for rest service - The maximum number of seconds to allow cURL functions to execute.
47
+ */
48
+ const REST_TIME_OUT = 2;
49
+
50
+ /**
51
+ * Convert an array of mapping into an array understandable by the webservice method sendObject
52
+ *
53
+ * @param array $attributes
54
+ * @return array
55
+ */
56
+ public function arrayToWebServiceRequest(array $attributes)
57
+ {
58
+ $wsArray = array();
59
+ foreach($attributes as $key => $value)
60
+ {
61
+ $wsArray[] = array('key' => $key, 'value' => $value);
62
+ }
63
+
64
+ return array('entry' => $wsArray);
65
+ }
66
+
67
+ /**
68
+ * Set rest service url
69
+ *
70
+ * @param string $url
71
+ * @return EmailVision_Api_NotificationService
72
+ */
73
+ public function setRestServiceUrl($url)
74
+ {
75
+ $this->_restServiceUrl = $url;
76
+ return $this;
77
+ }
78
+
79
+ /**
80
+ * Get rest service url
81
+ *
82
+ * @return string
83
+ */
84
+ public function getRestServiceUrl()
85
+ {
86
+ if ($this->_restServiceUrl == null) {
87
+ $this->_restServiceUrl = self::REST_SERVICE_URL;
88
+ }
89
+ return $this->_restServiceUrl;
90
+ }
91
+
92
+ /**
93
+ * Send email by EMV webservice
94
+ *
95
+ * @param string $encrypt - Security tag
96
+ * @param string $notificationId
97
+ * @param string $random - Unique Random Tag
98
+ * @param string $email
99
+ * @param array $content - need to be assiociative array - key => value
100
+ * @param array $variable - need to be assiociative array - key => value
101
+ * @param string $sendDate
102
+ * @return string
103
+ * @throws EmailVision_Api_Exception
104
+ */
105
+ public function sendTemplate(
106
+ $encrypt, $notificationId, $random,
107
+ $email, $content = array(), $variable = array(),
108
+ $sendDate = '1980-01-01T00:00:00'
109
+ )
110
+ {
111
+ $returnString = '';
112
+ try {
113
+ $returnString = '';
114
+ //send mail
115
+ $params = array(
116
+ 'arg0' => array(
117
+ 'content' => $this->arrayToWebServiceRequest($content),
118
+ 'dyn' => $this->arrayToWebServiceRequest($variable),
119
+ 'email' => $email,
120
+ 'encrypt' => $encrypt,
121
+ 'notificationId' => $notificationId,
122
+ 'random' => $random,
123
+ 'senddate' => $sendDate,
124
+ 'synchrotype' => 'NOTHING',
125
+ 'uidkey' => 'EMAIL',
126
+ )
127
+ );
128
+
129
+ // use method sendObject of the webservice
130
+ $wsResult = $this->soapCall('sendObject', $params);
131
+ if (isset($wsResult->return)) {
132
+ $returnString .= $email . ' : ' . $wsResult->return;
133
+ }
134
+
135
+ } catch (Exception $e) {
136
+ $this->decorateException($e);
137
+ $this->throwEmailVisionException($e);
138
+ }
139
+
140
+ return $returnString;
141
+ }
142
+
143
+ /**
144
+ * Decorate exception with a new eventual message and eventual error code
145
+ * @param Exception $e
146
+ */
147
+ public function decorateException(Exception $e)
148
+ {
149
+ parent::decorateException($e);
150
+
151
+ if ($e instanceof EmailVision_Api_Exception) {
152
+ $messageException = $e->getMessage();
153
+ $message = '';
154
+
155
+ if (stripos($messageException, 'CREATE_SENDREQUEST_FAILED') !== false) {
156
+ $message = 'Error with sending parameters (random, encrypt, or email address) !';
157
+ $e->setCode(EmailVision_Api_Exception::INVALID_EMAIL_SENDING_PARAMETERS);
158
+ }
159
+
160
+ if ($message) {
161
+ $message .= ' - Details from server return : ' . $messageException;
162
+ $e->setMessage($message);
163
+ }
164
+ }
165
+ }
166
+
167
+ /**
168
+ * Send email by Rest service
169
+ *
170
+ * @param string $encrypt
171
+ * @param string $notificationId
172
+ * @param string $random
173
+ * @param string $mail
174
+ * @param array $content - need to be assiociative array - key => value
175
+ * @param array $variable - need to be assiociative array - key => value
176
+ * @param string $sendDate
177
+ * @param string $proxyHost - proxy host
178
+ * @param string $proxyPort - proxy port
179
+ * @return boolean
180
+ * @throws EmailVision_Api_Exception
181
+ */
182
+ public function sendRest(
183
+ $encrypt, $notificationId, $random,
184
+ $mail, $content = array(), $variable = array(),
185
+ $sendDate = '2013-01-01T00:00:00',
186
+ $proxyHost = null, $proxyPort = null
187
+ )
188
+ {
189
+ // prepare dynamic variable
190
+ $dyn = '<dyn>';
191
+ foreach ($variable as $key => $value) {
192
+ $dyn .= '<entry>';
193
+ $dyn .= '<key><![CDATA[' . $key . ']]></key>';
194
+ $dyn .= '<value><![CDATA[' . $value . ']]></value>';
195
+ $dyn .= '</entry>';
196
+ }
197
+ $dyn .= '</dyn>';
198
+
199
+ // prepare dynamic content
200
+ $dynContent = '<content>';
201
+ // prepare Data
202
+ foreach ($content as $key => $value) {
203
+ $dynContent .= '<entry>';
204
+ $dynContent .= '<key><![CDATA[' . $key . ']]></key>';
205
+ $dynContent .= '<value><![CDATA[' . $value . ']]></value>';
206
+ $dynContent .= '</entry>';
207
+ }
208
+ $dynContent .= '</content>';
209
+
210
+ // template id
211
+ $encrypt = '<encrypt><![CDATA[' . $encrypt . ']]></encrypt>';
212
+ $random = '<random><![CDATA[' . $random . ']]></random>';
213
+ $sendDate = '<senddate><![CDATA[' . $sendDate . ']]></senddate>';
214
+ $mail = '<email><![CDATA[' . $mail . ']]></email>';
215
+
216
+ // prepare raw data for sending
217
+ $rawData = '<MultiSendRequest><sendrequest>';
218
+ $rawData .= $dyn . $dynContent . $mail . $encrypt . $random . $sendDate;
219
+ // refer to EmailVision documentation, do not do anything synchronization
220
+ $rawData .= '
221
+ <synchrotype><![CDATA[NOTHING]]></synchrotype>
222
+ <uidkey></uidkey>
223
+ ';
224
+ $rawData .= '</sendrequest></MultiSendRequest>';
225
+
226
+ $reason = '';
227
+ $reasonCode = null;
228
+ $httpCode = null;
229
+ try {
230
+ $ch = curl_init();
231
+
232
+ // set service url
233
+ curl_setopt($ch, CURLOPT_URL, $this->getRestServiceUrl());
234
+
235
+ // set option to have status code and response from server
236
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
237
+ curl_setopt ($ch, CURLOPT_VERBOSE , 1 );
238
+ // set header to http request
239
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array(
240
+ "Content-Type"=>"application/xml; charset=UTF-8",
241
+ "Connection"=>"Keep-Alive",
242
+ "Accept-Encoding"=>"*",
243
+ ));
244
+
245
+ // timeout
246
+ curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::REST_CONNECTION_TIME);
247
+ curl_setopt($ch, CURLOPT_TIMEOUT, self::REST_TIME_OUT);
248
+
249
+ // send by post
250
+ curl_setopt($ch, CURLOPT_POST, true);
251
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $rawData);
252
+
253
+ if ($proxyHost) {
254
+ $preparedProxy = $proxyHost;
255
+ // set proxy information if proxy is set
256
+ if ($proxyPort) {
257
+ $preparedProxy .= ':' . $proxyPort;
258
+ }
259
+ curl_setopt($ch, CURLOPT_PROXY, $preparedProxy);
260
+ }
261
+
262
+ // send data to webservice and get sever response
263
+ // the server response will be returned by curl_exec
264
+ $reason = curl_exec($ch);
265
+ if ($reason === false) {
266
+ // in case of error, try to get error number
267
+ $reasonCode = curl_errno($ch);
268
+ } else {
269
+ // get httpd code
270
+ $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
271
+ }
272
+
273
+ // close connection
274
+ curl_close($ch);
275
+ } catch(Exception $e) {
276
+ $this->throwEmailVisionException($e);
277
+ }
278
+
279
+ // in case of error, the status should be 200
280
+ if ($httpCode != self::REST_STATUS_OK) {
281
+ $code = EmailVision_Api_Exception::APPLICATION_ERROR;
282
+
283
+ // treat reason code when we don't have a response from server
284
+ if ($reasonCode) {
285
+ switch ($reasonCode) {
286
+ case self::CURLE_COULDNT_RESOLVE_HOST:
287
+ case self::CURLE_COULDNT_RESOLVE_PROXY:
288
+ case self::CURLE_OPERATION_TIMEDOUT :
289
+ case self::CURLE_COULDNT_CONNECT :
290
+ $code = EmailVision_Api_Exception::CONNECT_ERROR;
291
+ break;
292
+ }
293
+ } elseif ($httpCode) {
294
+ // treat http code if defined
295
+ switch ($httpCode) {
296
+ case self::NOT_FOUND_SERVICE :
297
+ $code = EmailVision_Api_Exception::CONNECT_ERROR;
298
+ break;
299
+ case self::INTERNAL_SERVER_ERROR :
300
+ if (
301
+ $reason
302
+ && (
303
+ stripos($reason,'Random') !== false
304
+ || stripos($reason,'encrypt') !== false
305
+ || stripos($reason,'email') !== false
306
+ )
307
+ ) {
308
+ $code = EmailVision_Api_Exception::INVALID_EMAIL_SENDING_PARAMETERS;
309
+ // remove the response received from SmartFocus
310
+ $reason = false;
311
+ }
312
+ break;
313
+ }
314
+ }
315
+
316
+ if (!$reason) {
317
+ $reason = 'Unknown error !';
318
+ switch ($code) {
319
+ case EmailVision_Api_Exception::CONNECT_ERROR :
320
+ $reason = 'Could not connect to Notification service. Please check your network setting, and service url!';
321
+ break;
322
+ case EmailVision_Api_Exception::INVALID_EMAIL_SENDING_PARAMETERS :
323
+ $reason = 'Your sending parameters are invalid. Please verify them again !';
324
+ break;
325
+ case EmailVision_Api_Exception::APPLICATION_ERROR :
326
+ $reason = 'Error occured at SmartFocus server';
327
+ break;
328
+ }
329
+ }
330
+
331
+ $message = array(
332
+ 'Error while sending content to SmartFocus api - reason : ' . $reason,
333
+ );
334
+ if ($httpCode) {
335
+ $message[] = 'HTTP status code : ' . $httpCode;
336
+ }
337
+ $message = implode("\n", $message);
338
+
339
+ $exception = new EmailVision_Api_Exception($message, $code);
340
+ $this->throwEmailVisionException($exception);
341
+ } // end error treatment
342
+
343
+ return true;
344
+ }
345
+ }
lib/EmailVision/Api/TransactionalService.php ADDED
@@ -0,0 +1,433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Transactional Message Api
4
+ *
5
+ * @category EmailVision
6
+ * @package EmailVision_Api
7
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
8
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
9
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License v. 3.0 (OSL-3.0)
10
+ */
11
+ class EmailVision_Api_TransactionalService extends EmailVision_Api_Common
12
+ {
13
+ /**
14
+ * Default Campagin Commander template type
15
+ */
16
+ const DEFAULT_EMV_TEMPLATE_TYPE = 'TRANSACTIONAL';
17
+
18
+ /**
19
+ * Default send template name
20
+ */
21
+ const DEFAULT_TEMPLATE_SEND = 'emv_send_temporary_template';
22
+
23
+ /**
24
+ * Default template type
25
+ */
26
+ const DEFAULT_TEMPLATE_TYPE = 'TRANSACTIONAL';
27
+
28
+ /**
29
+ * How many templates per page
30
+ */
31
+ const LIST_SIZE = 15;
32
+
33
+ /**
34
+ * (non-PHPdoc)
35
+ * @see EmailVision_Api_Common::decorateException()
36
+ */
37
+ public function decorateException(Exception $e)
38
+ {
39
+ parent::decorateException($e);
40
+
41
+ if ($e instanceof EmailVision_Api_Exception) {
42
+ $messageException = $e->getMessage();
43
+ $message = '';
44
+
45
+ if (stripos($messageException, 'GET_TEMPLATE_FAILED') !== false) {
46
+ $e->setCode(EmailVision_Api_Exception::INVALID_TEMPLATE_ID);
47
+ }
48
+
49
+ if ($message) {
50
+ $message .= ' - Details from server return : ' . $messageException;
51
+ $e->setMessage($message);
52
+ }
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Get Transactional template by id
58
+ *
59
+ * @param string $id
60
+ * @param boolean $closeApi
61
+ * @return NULL | stdClass
62
+ * @throws EmailVision_Api_Exception
63
+ */
64
+ public function getTemplateById($id, $closeApi = true)
65
+ {
66
+ try {
67
+ $params = array(
68
+ 'token' => $this->openApiConnection(),
69
+ 'id' => $id,
70
+ );
71
+
72
+ $wsResult = $this->soapCall('getTemplate', $params);
73
+ } catch (Exception $e) {
74
+ $this->decorateException($e);
75
+ $this->throwEmailVisionException($e);
76
+ }
77
+
78
+ if ($closeApi) {
79
+ $this->closeApiConnection();
80
+ }
81
+
82
+ if (isset($wsResult->return)) {
83
+ return $wsResult->return;
84
+ } else {
85
+ return null;
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Create default emv send template and return template id
91
+ *
92
+ * @param string $templateName
93
+ * @param boolean $closeApi
94
+ * @return NULL | string
95
+ * @throws EmailVision_Api_Exception
96
+ */
97
+ public function createDefaultEmvSendTemplate($templateName = self::DEFAULT_TEMPLATE_SEND, $closeApi = true)
98
+ {
99
+ $templateId = null;
100
+ try {
101
+ $params = array(
102
+ 'token' => $this->openApiConnection(),
103
+ 'name' => $templateName,
104
+ 'subject' => '[EMV DYN]SUBJECT[EMV /DYN]',
105
+ 'description' => 'DO NOT DELETE',
106
+ 'from' => '[EMV DYN]FROM[EMV /DYN]',
107
+ 'fromEmail' => '[EMV DYN]FROM_EMAIL[EMV /DYN]',
108
+ 'to' => '[EMV DYN]TO[EMV /DYN]',
109
+
110
+ 'body' => '[EMV HTMLPART]
111
+ <html>
112
+ <body>
113
+ [EMV CONTENT]1[EMV /CONTENT]
114
+ </body>
115
+ </html>
116
+ [EMV TEXTPART]
117
+ [EMV CONTENT]2[EMV /CONTENT]',
118
+
119
+ 'encoding' => 'UTF-8',
120
+ 'replyTo' => '[EMV DYN]REPLY[EMV /DYN]',
121
+ 'replyToEmail' => '[EMV DYN]REPLY_EMAIL[EMV /DYN]',
122
+ 'type' => 'TRANSACTIONAL',
123
+ );
124
+
125
+ // use createTemplate method
126
+ $wsResult = $this->soapCall('createTemplate', $params);
127
+ if (isset($wsResult->return)) {
128
+ $templateId = $wsResult->return;
129
+ }
130
+ } catch (Exception $e) {
131
+ $this->decorateException($e);
132
+ $this->throwEmailVisionException($e);
133
+ }
134
+
135
+ if ($closeApi) {
136
+ $this->closeApiConnection();
137
+ }
138
+
139
+ return $templateId;
140
+ }
141
+
142
+ /**
143
+ * Get default template send
144
+ * @return NULL | stdClass
145
+ * @throws EmailVision_Api_Exception
146
+ */
147
+ public function getDefaultTemplateSend($defaultName = self::DEFAULT_TEMPLATE_SEND, $closeApi = true)
148
+ {
149
+ $defaultTemplate = null;
150
+
151
+ $defaultTemplateId = $this->getTemplatesByField($defaultName, 'name', 1, self::DEFAULT_EMV_TEMPLATE_TYPE, false);
152
+ if (is_array($defaultTemplateId) && count($defaultTemplateId) >= 1) {
153
+ $defaultTemplate = $this->getTemplateById($defaultTemplateId[0], false);
154
+ }
155
+
156
+ if ($closeApi) {
157
+ $this->closeApiConnection();
158
+ }
159
+
160
+ return $defaultTemplate;
161
+ }
162
+
163
+ /**
164
+ * Get templates by field
165
+ *
166
+ * @param string $value
167
+ * @param string $field
168
+ * @param int $limit
169
+ * @param string $type
170
+ * @param boolean $closeApi
171
+ * @return array
172
+ * @throws EmailVision_Api_Exception
173
+ */
174
+ public function getTemplatesByField($value, $field = 'name', $limit = 1, $type = self::DEFAULT_EMV_TEMPLATE_TYPE, $closeApi = true)
175
+ {
176
+ $listTemplates = array();
177
+ try {
178
+ $params = array(
179
+ 'token' => $this->openApiConnection(),
180
+ 'type' => self::DEFAULT_TEMPLATE_TYPE,
181
+ 'field' => $field,
182
+ 'value' => $value,
183
+ 'limit' => $limit,
184
+ );
185
+
186
+ // use getTemplatesByField method
187
+ $wsResult = $this->soapCall('getTemplatesByField', $params);
188
+
189
+ if (property_exists($wsResult, 'return')) {
190
+ if (is_array($wsResult->return)) {
191
+ $listTemplates = $wsResult->return;
192
+ } elseif (is_numeric($wsResult->return)) {
193
+ $listTemplates[] = $wsResult->return;
194
+ }
195
+ }
196
+ } catch (Exception $e) {
197
+ $this->decorateException($e);
198
+ $this->throwEmailVisionException($e);
199
+ }
200
+
201
+ if ($closeApi) {
202
+ $this->closeApiConnection();
203
+ }
204
+
205
+ return $listTemplates;
206
+ }
207
+
208
+ /**
209
+ * Get template by period
210
+ *
211
+ * @param $from string date with format 'YYYY-MM-DD HH:MM:SS'
212
+ * @param $to string date with format 'YYYY-MM-DD HH:MM:SS'
213
+ * @return array
214
+ * @throws EmailVision_Api_Exception
215
+ */
216
+ public function getTemplatesByPeriod($from, $to, $closeApi = true)
217
+ {
218
+ $listTemplates = array();
219
+ try {
220
+ $params = array(
221
+ 'token' => $this->openApiConnection(),
222
+ 'type' => self::DEFAULT_TEMPLATE_TYPE,
223
+ 'dateBegin' => $from,
224
+ 'dateEnd' => $to,
225
+ );
226
+
227
+ // use getTemplatesByPeriod method
228
+ $wsResult = $this->soapCall('getTemplatesByPeriod', $params);
229
+ if (property_exists($wsResult, 'return')) {
230
+ if (is_array($wsResult->return)) {
231
+ $listTemplates = $wsResult->return;
232
+ } elseif (is_numeric($wsResult->return)) {
233
+ $listTemplates[] = $wsResult->return;
234
+ }
235
+ }
236
+ } catch (Exception $e) {
237
+ $this->decorateException($e);
238
+ $this->throwEmailVisionException($e);
239
+ }
240
+
241
+ if ($closeApi) {
242
+ $this->closeApiConnection();
243
+ }
244
+
245
+ return $listTemplates;
246
+ }
247
+
248
+ /**
249
+ * Get template summary list
250
+ *
251
+ * @param int $page
252
+ * @param int $size
253
+ * @param string $closeApi
254
+ * @param array $search
255
+ * - from : date with format 'YYYY-MM-DDTHH:MM:SS'
256
+ * - to : date with format 'YYYY-MM-DDTHH:MM:SS'
257
+ * - name : template name
258
+ * @return array :
259
+ * - total_templates : how many templates in SmartFocus account
260
+ * - total_retreived : how many templates has been retrieved
261
+ * - next_page : the eventual page number
262
+ * - page_size : how many templates per page
263
+ * - actual_page : the current page
264
+ * - list_retreived : retreived template id
265
+ */
266
+ public function getTemplateSummmaryList($page = 1, $size = self::LIST_SIZE, $search = array(), $closeApi = true)
267
+ {
268
+ $result = array(
269
+ 'total_templates' => 0,
270
+ 'total_retreived' => 0,
271
+ 'next_page' => 0,
272
+ 'page_size' => $size,
273
+ 'actual_page' => $page,
274
+ 'list_retreived' => array()
275
+ );
276
+
277
+ try {
278
+ $params = array(
279
+ 'token' => $this->openApiConnection(),
280
+ 'listOptions' => array(
281
+ 'page' => $page,
282
+ 'pageSize' => $size
283
+ ),
284
+ );
285
+
286
+ // prepare search parameters
287
+ if (count($search)) {
288
+ $paramSearch = array();
289
+ if (isset($search['from']) && $search['from']) {
290
+ $paramSearch['minCreationDate'] = $search['from'];
291
+ }
292
+ if (isset($search['to']) && $search['to']) {
293
+ $paramSearch['maxCreationDate'] = $search['to'];
294
+ }
295
+ if (isset($search['name']) && $search['name']) {
296
+ $paramSearch['name'] = $search['name'];
297
+ }
298
+
299
+ if (count($paramSearch)) {
300
+ $params['listOptions']['search'] = $paramSearch;
301
+ }
302
+ }
303
+
304
+ // use getTemplatesByPeriod method
305
+ $wsResult = $this->soapCall('getTemplateSummaryList', $params);
306
+
307
+ // handle server return
308
+ if (property_exists($wsResult, 'return')) {
309
+ if (
310
+ property_exists($wsResult->return, 'templateSummaryList')
311
+ && property_exists($wsResult->return->templateSummaryList, 'templateSummary')
312
+ ) {
313
+ if (is_array($wsResult->return->templateSummaryList->templateSummary)) {
314
+ $result['list_retreived'] = $wsResult->return->templateSummaryList->templateSummary;
315
+ $result['total_retreived'] = count($result['list_retreived']);
316
+ }
317
+ }
318
+ if (isset($wsResult->return->nbTotalItems)) {
319
+ $result['total_templates'] = $wsResult->return->nbTotalItems;
320
+ }
321
+ if (isset($wsResult->return->nextPage) && $wsResult->return->nextPage > 0) {
322
+ $result['next_page'] = $wsResult->return->nextPage;
323
+ }
324
+ }
325
+
326
+ } catch (Exception $e) {
327
+ $this->decorateException($e);
328
+ $this->throwEmailVisionException($e);
329
+ }
330
+
331
+ if ($closeApi) {
332
+ $this->closeApiConnection();
333
+ }
334
+
335
+ return $result;
336
+ }
337
+
338
+ /**
339
+ * Get template preview
340
+ *
341
+ * @param string $templateId
342
+ * @param string $part
343
+ * @param string $closeApi
344
+ *
345
+ * @return false - in case of errors | string
346
+ */
347
+ public function getTemplatePreview($templateId, $part='HTML', $closeApi = true)
348
+ {
349
+ $result = false;
350
+
351
+ try {
352
+ $params = array(
353
+ 'token' => $this->openApiConnection(),
354
+ 'id' => $templateId,
355
+ 'part' => $part
356
+ );
357
+ // use getTemplatesByPeriod method
358
+ $wsResult = $this->soapCall('getTemplatePreview', $params);
359
+ if (property_exists($wsResult, 'return')) {
360
+ $result = $wsResult->return;
361
+ }
362
+ } catch (Exception $e) {
363
+ $this->decorateException($e);
364
+ $this->throwEmailVisionException($e);
365
+ }
366
+
367
+ if ($closeApi) {
368
+ $this->closeApiConnection();
369
+ }
370
+
371
+ return $result;
372
+ }
373
+
374
+ /**
375
+ * Get template preview HTML with eventual Dyn and Content variables
376
+ *
377
+ * @param string $templateId
378
+ * @param array $variables
379
+ * variable contains two supported types (EMV_DYN and EMV_CONTENT)
380
+ * @param string $part
381
+ * @param string $closeApi
382
+ * @return boolean
383
+ */
384
+ public function getTemplatePreviewWithDynContent($templateId, $variables = array(), $part='HTML', $closeApi = true)
385
+ {
386
+ $result = false;
387
+
388
+ try {
389
+ $params = array(
390
+ 'token' => $this->openApiConnection(),
391
+ 'templatePerso' => array(
392
+ 'contentItemList' => array(),
393
+ 'persoItemList' => array(),
394
+ 'templateId' => $templateId
395
+ ),
396
+ 'part' => $part
397
+ );
398
+
399
+ // prepare Dyn variables
400
+ if (isset($variables['EMV_DYN'])) {
401
+ foreach ($variables['EMV_DYN'] as $key => $value) {
402
+ $params['templatePerso']['persoItemList']['persoItem'][] = array(
403
+ 'label' => $key,
404
+ 'value' => $value
405
+ );
406
+ }
407
+ }
408
+ if (isset($variables['EMV_CONTENT'])) {
409
+ foreach ($variables['EMV_CONTENT'] as $key => $value) {
410
+ $params['templatePerso']['contentItemList']['contentItem'][] = array(
411
+ 'label' => $key,
412
+ 'value' => $value
413
+ );
414
+ }
415
+ }
416
+
417
+ // use getTemplatesByPeriod method
418
+ $wsResult = $this->soapCall('getTemplatePreviewByObj', $params);
419
+ if (property_exists($wsResult, 'return')) {
420
+ $result = $wsResult->return;
421
+ }
422
+ } catch (Exception $e) {
423
+ $this->decorateException($e);
424
+ $this->throwEmailVisionException($e);
425
+ }
426
+
427
+ if ($closeApi) {
428
+ $this->closeApiConnection();
429
+ }
430
+
431
+ return $result;
432
+ }
433
+ }
lib/EmailVision/SoapClient.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * EmailVision Soap Client
4
+ *
5
+ * @category EmailVision
6
+ * @package EmailVision
7
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
8
+ * @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
9
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License v. 3.0 (OSL-3.0)
10
+ */
11
+ class EmailVision_SoapClient extends SoapClient
12
+ {
13
+ /**
14
+ * Overriding __doRequest :
15
+ * - To replace known invalid xml characters.
16
+ * - To support Mtom supporting server (extract a unique soap envelop from a mutlipart
17
+ * response) Carefull! This method won't work with multiple soap envelops returned in a unique response.
18
+ *
19
+ * @see http://www.w3.org/TR/xml/#charsets
20
+ * @return string
21
+ */
22
+ public function __doRequest($request, $location, $action, $version, $one_way = 0) {
23
+ $response = parent::__doRequest($request, $location, $action, $version);
24
+
25
+ // Only replace unicode characters if PCRE version is less than 8.30
26
+ if (version_compare(strstr(constant('PCRE_VERSION'), ' ', true), '8.30', '<')) {
27
+ $response = preg_replace('/[\x{0}-\x{8}\x{B}-\x{C}\x{E}-\x{1F}\x{D800}-\x{DFFF}]/u', '', $response);
28
+ }
29
+
30
+ $start = strpos($response, '<soap');
31
+ $end = strrpos($response, '>');
32
+ $response = substr($response, $start, $end-$start+1);
33
+
34
+ return $response;
35
+ }
36
+ }
lib/EmailVision/Tools/File/Csv.php ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Csv file tool class
4
+ *
5
+ * @category EmailVision
6
+ * @package EmailVision_File
7
+ * @author Minh Quang VO <minhquang.vo@smartfocus.com>
8
+ * @copyright Varien Inc. (Varien_File_Csv)
9
+ * @license http://opensource.org/licenses/OSL-3.0 Open Software License v. 3.0 (OSL-3.0)
10
+ */
11
+ class EmailVision_Tools_File_Csv
12
+ {
13
+ protected $_lineLength= 0;
14
+ protected $_delimiter = ',';
15
+ protected $_enclosure = '"';
16
+
17
+ /**
18
+ * Set max file line length
19
+ *
20
+ * @param int $length
21
+ * @return EmailVision_File_Csv
22
+ */
23
+ public function setLineLength($length)
24
+ {
25
+ $this->_lineLength = $length;
26
+ return $this;
27
+ }
28
+
29
+ /**
30
+ * Set CSV column delimiter
31
+ *
32
+ * @param string $delimiter
33
+ * @return EmailVision_File_Csv
34
+ */
35
+ public function setDelimiter($delimiter)
36
+ {
37
+ $this->_delimiter = $delimiter;
38
+ return $this;
39
+ }
40
+
41
+ /**
42
+ * Set CSV column value enclosure
43
+ *
44
+ * @param string $enclosure
45
+ * @return EmailVision_File_Csv
46
+ */
47
+ public function setEnclosure($enclosure)
48
+ {
49
+ $this->_enclosure = $enclosure;
50
+ return $this;
51
+ }
52
+
53
+ /**
54
+ * Retrieve CSV file data as array
55
+ *
56
+ * @param string $file
57
+ * @return array
58
+ */
59
+ public function getData($file)
60
+ {
61
+ $data = array();
62
+ if (!file_exists($file)) {
63
+ throw new Exception('File "'.$file.'" do not exists');
64
+ }
65
+
66
+ $fh = fopen($file, 'r');
67
+ while ($rowData = fgetcsv($fh, $this->_lineLength, $this->_delimiter, $this->_enclosure)) {
68
+ $data[] = $rowData;
69
+ }
70
+ fclose($fh);
71
+ return $data;
72
+ }
73
+
74
+ /**
75
+ * Retrieve CSV file data as pairs
76
+ *
77
+ * @param string $file
78
+ * @param int $keyIndex
79
+ * @param int $valueIndex
80
+ * @return array
81
+ */
82
+ public function getDataPairs($file, $keyIndex=0, $valueIndex=1)
83
+ {
84
+ $data = array();
85
+ $csvData = $this->getData($file);
86
+ foreach ($csvData as $rowData) {
87
+ if (isset($rowData[$keyIndex])) {
88
+ $data[$rowData[$keyIndex]] = isset($rowData[$valueIndex]) ? $rowData[$valueIndex] : null;
89
+ }
90
+ }
91
+ return $data;
92
+ }
93
+
94
+ /**
95
+ * Saving data row array into file
96
+ *
97
+ * @param string $file
98
+ * @param array $data
99
+ * @return EmailVision_File_Csv
100
+ */
101
+ public function saveData($file, $data)
102
+ {
103
+ $fh = fopen($file, 'w');
104
+ foreach ($data as $dataRow) {
105
+ $this->fputcsv($fh, $dataRow, $this->_delimiter, $this->_enclosure);
106
+ }
107
+ fclose($fh);
108
+ return $this;
109
+ }
110
+
111
+ /**
112
+ * Write fields to file
113
+ *
114
+ * @param resource $handle - file handler
115
+ * @param array $fields
116
+ * @param string $delimiter
117
+ * @param string $enclosure
118
+ * @return number - the number of bytes have been written || boolean
119
+ */
120
+ public function fputcsv(&$handle, $fields = array(), $delimiter = ',', $enclosure = '"') {
121
+ $str = '';
122
+ $escapeChar = '\\';
123
+ foreach ($fields as $value) {
124
+ if (
125
+ strpos($value, $delimiter) !== false
126
+ || strpos($value, $enclosure) !== false
127
+ || strpos($value, "\n") !== false
128
+ || strpos($value, "\r") !== false
129
+ || strpos($value, "\t") !== false
130
+ || strpos($value, ' ') !== false
131
+ ) {
132
+ $str2 = $enclosure;
133
+ $escaped = 0;
134
+ $len = strlen($value);
135
+ for ($i=0;$i<$len;$i++) {
136
+ if ($value[$i] == $escapeChar) {
137
+ $escaped = 1;
138
+ } else if (!$escaped && $value[$i] == $enclosure) {
139
+ $str2 .= $enclosure;
140
+ } else {
141
+ $escaped = 0;
142
+ }
143
+ $str2 .= $value[$i];
144
+ }
145
+ $str2 .= $enclosure;
146
+ $str .= $str2 . $delimiter;
147
+ } else {
148
+ $str .= $enclosure . $value . $enclosure . $delimiter;
149
+ }
150
+ }
151
+ $str = substr($str,0,-1);
152
+ $str .= "\n";
153
+
154
+ return fwrite($handle, $str);
155
+ }
156
+
157
+ }
package.xml CHANGED
@@ -1,18 +1,33 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Campaign_Commander_Transactional_Email_1_5</name>
4
- <version>2.0.3</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.opensource.org/licenses/academic.php">Academic Free License (AFL)</license>
7
  <channel>community</channel>
8
  <extends/>
9
- <summary>Send your transactional e-mails through the Campaign Commander NMP platform</summary>
10
- <description>Send your transactional e-mails through the Campaign Commander NMP platform.</description>
11
- <notes>Send your transactional e-mails through the Campaign Commander NMP platform</notes>
12
- <authors><author><name>emailvision</name><user>auto-converted</user><email>EMVIntegrationsDevelopment@emailvision.com</email></author></authors>
13
- <date>2012-09-26</date>
14
- <time>12:55:39</time>
15
- <contents><target name="magelocale"><dir name="en_US"><dir name="template"><dir name="email"><dir name="abandonment"><file name="template1.html" hash="25e61ef30c06a9b1126d4137a8dcf104"/><file name="template2.html" hash="fc203b790cd1bcdeb0ac71a7b5464813"/><file name="template3.html" hash="a29290cb0e4e50a321347f151a3e9590"/></dir></dir></dir><file name="Emv_Core.csv" hash="9f42f92ffc0ebebdcbbd2f78495aab0c"/><file name="Emv_Emt.csv" hash="9550fdad59ad6d262f3da8aa09e5b88e"/><file name="Emv_CartAlert.csv" hash="00c5ee1ce9989ce60afc830261a3b4ec"/></dir><dir name="fr_FR"><file name="Emv_Core.csv" hash="3635d815c6f762945147552f3a92febd"/><file name="Emv_Emt.csv" hash="42e00b78ebb2c8ac9181f98566015506"/><file name="Emv_CartAlert.csv" hash="084921a6278f8c582c90fd57888da7ae"/></dir></target><target name="mageetc"><dir name="modules"><file name="Emv_Core.xml" hash="e25dd0ea40fad09e0d1f6260f46e65ac"/><file name="Emv_Emt.xml" hash="d1e26edb25bce0b78e6c14792c07ac03"/><file name="Emv_CartAlert.xml" hash="7c23ed23c48254c30e4aad7c11db1b62"/></dir></target><target name="magecommunity"><dir name="Emv"><dir name="Core"><dir name="Block"><dir name="Adminhtml"><dir name="Account"><dir name="Edit"><file name="Form.php" hash="9e090720d3b7fc7406d2e4d4f95dbc90"/></dir><file name="Edit.php" hash="34bc1566c3693acccaa4c8e40b31cb5c"/><file name="Grid.php" hash="3d175f0e1b7ccc7dec1c9ffa30cacb76"/></dir><file name="Accounts.php" hash="3f35eecb2bf23417c0fab4746bda6d0c"/></dir></dir><dir name="Helper"><file name="Config.php" hash="455cd67728b1e6876e9fd8d55ca3253b"/><file name="Data.php" hash="896b9955cc2d6b27b9eca4d2508b7169"/></dir><dir name="Model"><dir name="Mysql4"><dir name="Account"><file name="Collection.php" hash="39c1a08471b3bdd0563f3002a32a4db8"/></dir><file name="Account.php" hash="cea2093a18291b7dd24e25b6f8ce0da0"/></dir><dir name="Resource"><file name="Setup.php" hash="6fc36453ff6c01ac0534731816355bd0"/></dir><dir name="Service"><dir name="Soap"><file name="Api.php" hash="27d9e266d1e822594dfe1bcc6b4fe9a9"/><file name="Config.php" hash="c001b05e0004994b2555b7be224ab014"/><file name="SoapClient.php" hash="32117ab80f05f6e15b03edc879f806c1"/></dir></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="Account.php" hash="cbc4ee876efd1abcdaa5c57cc08714c2"/></dir></dir></dir><file name="Account.php" hash="a8a6c2c45ab0979666d09732e8d3eda2"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="AccountController.php" hash="91447d74999979c278b65dd85f5c06d8"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="2e84807c5c503bd91ed673dfb5f579bd"/><file name="config.xml" hash="7bc75acc341d88e151534b02c86512ac"/><file name="system.xml" hash="1785905f6dd6a2bc367318a86391daca"/></dir><dir name="sql"><dir name="emvcore_setup"><file name="mysql4-install-0.1.0.php" hash="7bc6d6e7c03398c40008d89ed86e27bc"/></dir></dir><file name="Exception.php" hash="227e1046ebceb99af7bc2b441bb4997d"/></dir><dir name="Emt"><dir name="Block"><dir name="Adminhtml"><dir name="Emt"><dir name="Edit"><file name="Attributes.php" hash="cc2a88773ca64fe7e88b0f460b3b05fc"/><file name="Form.php" hash="400920f5c2778c9cdda7f70137cd885e"/></dir><dir name="Grid"><dir name="Renderer"><file name="Emvname.php" hash="c520b56f6a806c551336fc67d8c5a487"/></dir></dir><dir name="New"><file name="Form.php" hash="f2f06b70d36dc2eefe9d4bf7f49ab633"/></dir><file name="Edit.php" hash="be44792b12374f6d6f4c5687fd5e04b0"/><file name="Grid.php" hash="e350af4605b4d02558b0e30c13184e3e"/><file name="New.php" hash="6ac499b1064c29fd6893c61cb29209c4"/></dir><file name="Emts.php" hash="b0e91f038bfea92da099a94cb5c232a3"/></dir></dir><dir name="Helper"><file name="Data.php" hash="3bcd2a0563cf4a604cefac0a41884819"/><file name="Emvtemplate.php" hash="2b4c13c664becc8564727c9100c25303"/></dir><dir name="Model"><dir name="Mage"><dir name="Core"><dir name="Email"><file name="Template.php" hash="f1b5d52867dc1b35c406294bb7359891"/></dir></dir></dir><dir name="Mysql4"><dir name="Attribute"><file name="Collection.php" hash="a029255fdb8ccb45250959e08bd7f304"/></dir><dir name="Emt"><file name="Collection.php" hash="40297d68cac532feb2b8eecfa166f6e2"/></dir><dir name="Mailmode"><file name="Collection.php" hash="98b8005f11a230829c8b1664d9222f2c"/></dir><file name="Attribute.php" hash="13fe2d1ca2efa66b4184da68a629135c"/><file name="Emt.php" hash="9a5e2265b2e5841f07cb175229f79971"/><file name="Mailmode.php" hash="7585af6b9d102fc52788ac0083d338ae"/></dir><dir name="Resource"><file name="Setup.php" hash="62b3de559b3484cec6767a174cda42e9"/></dir><file name="Attribute.php" hash="430f2ba97ded59d319fcd8579555c53c"/><file name="Emt.php" hash="51ad525e79f8d3939bba7b5a5ec69f2f"/><file name="MageTemplate.php" hash="66051e8c63d2012c022d7bf45a3e880b"/><file name="Mailmode.php" hash="d77ce590e7302f0115dcd2075468595c"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="EmtController.php" hash="c9ef7c5a9e6176b114a767edce51a996"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="46610ec63dd5443130e59dbc900e3541"/><file name="config.xml" hash="837cdaf661abefaefba7fca6ab421419"/></dir><dir name="sql"><dir name="emvemt_setup"><file name="mysql4-install-0.1.0.php" hash="a7d12df049f2c1377a072fa7899dcb6c"/><file name="mysql4-upgrade-0.1.0-0.2.0.php" hash="34df942808b7609c10077b493e87f2c2"/></dir></dir><file name="Constants.php" hash="419073d59d393b684d1f55932b717e26"/></dir><dir name="CartAlert"><dir name="Block"><dir name="Cart"><file name="Items.php" hash="e776828d83029fddafb78ef2d0d095b7"/></dir><dir name="Customer"><file name="Abandonment.php" hash="e4c33c79fec5b4f7873fc426b0810c0a"/></dir></dir><dir name="Helper"><file name="Data.php" hash="7254fa1e10dd0511a7650c97b1f51207"/></dir><dir name="Model"><dir name="Mysql4"><dir name="Abandonment"><file name="Collection.php" hash="45d4e4a5825f99d1fdaccc6aafa37b7b"/></dir><file name="Abandonment.php" hash="f7295df4a2db5cdd0d07ea7c45c471d4"/></dir><dir name="Resource"><file name="Setup.php" hash="252605dd07f4e2d28b8a8a483b28c51e"/></dir><file name="Abandonedcart.php" hash="b33a2507ccd51fb1cc8377e54c10d2a6"/><file name="Abandonedcartitem.php" hash="62299184dadf25b3da790e37ae0a89f9"/><file name="Abandonment.php" hash="d99a5180a449145ef3e902b2ffdfb842"/><file name="Observer.php" hash="07113261fd8cf291375b22a456eb5df3"/></dir><dir name="controllers"><file name="CustomerController.php" hash="14313e496e983685ae354907548065ba"/><file name="GuestController.php" hash="bfb7cdb821a1259e03b16461ae2cb81a"/></dir><dir name="etc"><file name="adminhtml.xml" hash="a9f89ee6ca0dd0168cba2eaabec343a7"/><file name="config.xml" hash="6483a1ab443e3804203522e90026b562"/><file name="system.xml" hash="170e847afa9cc636fd4747eb7d079458"/></dir><dir name="sql"><dir name="abandonment_setup"><file name="mysql4-install-0.1.0.php" hash="551c1d869ad2ed536955af4938863aa8"/><file name="mysql4-upgrade-0.1.0-0.2.0.php" hash="444d36d574561450c21117545ad10291"/></dir></dir><file name="Constants.php" hash="a3acc804622c4ac76ff67591bbd447c7"/></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="emt"><file name="attributes.phtml" hash="b6508fa8b577e1fe2ae56c635f2ca923"/></dir></dir></dir></dir></dir><dir name="frontend"><dir name="emv"><dir name="template"><dir name="abandonment"><dir name="reminder"><file name="items.phtml" hash="a4d533a70c78448837d27369b480c6f2"/></dir></dir></dir></dir><dir name="default"><dir name="default"><dir name="layout"><file name="abandonment.xml" hash="12838badbe46e199f07b5c0801a97d15"/></dir><dir name="template"><dir name="abandonment"><file name="customer.phtml" hash="d63198ab64858039aa5b23f9964dd6d3"/></dir></dir></dir></dir><dir name="enterprise"><dir name="default"><dir name="layout"><file name="abandonment.xml" hash="5c4ba85552b631fefb2b080f858591a0"/></dir><dir name="template"><dir name="abandonment"><file name="customer.phtml" hash="d63198ab64858039aa5b23f9964dd6d3"/></dir></dir></dir></dir></dir></target></contents>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  <compatible/>
17
- <dependencies/>
18
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Campaign_Commander_Transactional_Email_1_5</name>
4
+ <version>3.0.1</version>
5
  <stability>stable</stability>
6
  <license uri="http://www.opensource.org/licenses/academic.php">Academic Free License (AFL)</license>
7
  <channel>community</channel>
8
  <extends/>
9
+ <summary>Transactional message delivery, abandoned cart, and data sync for Magento </summary>
10
+ <description> 1. Engage customers with abandoned cart messages&#xD;
11
+ * Re-capture lost sales with automatic messaging when customers abandon a shopping cart&#xD;
12
+ * Increase conversion with ability to add promo code with reminder&#xD;
13
+ * View revenue and key statistics from reminder emails&#xD;
14
+ &#xD;
15
+ 2. Optimize design and delivery of transactional messages&#xD;
16
+ * Improve the design and deliverability of transactional messages by utilising the SmartFocus email platform&#xD;
17
+ * Increase transactional message response rates with branded communications&#xD;
18
+ * Take advantage of SmartFocus' advanced deliverability tools and capabilities&#xD;
19
+ &#xD;
20
+ 3. Synchronize data for a complete view of the customer&#xD;
21
+ * Automatically sychronize your Magento customer data with your SmartFocus marketing database</description>
22
+ <notes>* New SmartFocus menus&#xD;
23
+ &#xD;
24
+ * New API implementation&#xD;
25
+ &#xD;
26
+ * New features enhance email sending, abandoned cart reminders, and data synchronization</notes>
27
+ <authors><author><name>SmartFocus</name><user>itgemailvision</user><email>EMVIntegrationsDevelopment@smartfocus.com</email></author></authors>
28
+ <date>2014-02-05</date>
29
+ <time>10:57:08</time>
30
+ <contents><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><file name="campaign-commander.css" hash="7a48c4846463a3710661d4e19a36f150"/></dir></dir></dir></target><target name="magelib"><dir name="EmailVision"><dir name="Api"><file name="BatchMemberService.php" hash="48443e2dd252c3f089b7f0870316f503"/><file name="Common.php" hash="aa50e6fab781d0431aece5ea77630f8b"/><file name="Exception.php" hash="fbe812474106cb6a694e2ec21d304d7b"/><file name="MemberService.php" hash="f3dc742201351e99b3eedfd06a0b9a9d"/><file name="NotificationService.php" hash="1445b72b496d61528302f12d12bd8fe2"/><file name="TransactionalService.php" hash="7aa5530026dbc8f3972b4ef543cef348"/></dir><file name="SoapClient.php" hash="a764db42192da691ab8d01aceb4d3e8d"/><dir name="Tools"><dir name="File"><file name="Csv.php" hash="4fd8516f3b80ed60a8a919d217f2e8d3"/></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><dir name="template"><dir name="email"><dir name="emailvision"><dir name="abandonment"><file name="template1.html" hash="3eda1598c50876324609c0d634526624"/><file name="template2.html" hash="3eda1598c50876324609c0d634526624"/><file name="template3.html" hash="3eda1598c50876324609c0d634526624"/></dir><dir name="datasync"><file name="cron_errors.html" hash="bbf6122128d85d2291fd291d4096b6b2"/></dir></dir></dir></dir><file name="Emv_CartAlert.csv" hash="9fc25be18876d260c0b8e56735f14713"/><file name="Emv_Core.csv" hash="33f26cf37e6ca8c3c73a0a3b82bc2d13"/><file name="Emv_DataSync.csv" hash="94d468f0f3924e7713aa8be5939094c6"/><file name="Emv_Emt.csv" hash="f1a0246d49a5a3beaba3b8033785ba99"/><file name="Emv_Report.csv" hash="5f25d083b33cd20697ac1190e626782a"/></dir><dir name="fr_FR"><file name="Emv_CartAlert.csv" hash="0acb2fa39d9199c8f31849beea6b782a"/><file name="Emv_Core.csv" hash="e73b4ad1ee7853d7fb8f949c2e295906"/><file name="Emv_DataSync.csv" hash="d5d443e8511ca960e938cf92716d3f7e"/><file name="Emv_Emt.csv" hash="490f8bf088b342b2047e723ce95f7c6a"/><file name="Emv_Report.csv" hash="f586e64852651a4524b7f27eb2c3cd6a"/></dir></target><target name="mageetc"><dir name="modules"><file name="Emv_CartAlert.xml" hash="7c23ed23c48254c30e4aad7c11db1b62"/><file name="Emv_Core.xml" hash="e25dd0ea40fad09e0d1f6260f46e65ac"/><file name="Emv_DataSync.xml" hash="089e2b362da3cb466e1ba2dc79e63289"/><file name="Emv_Emt.xml" hash="d1e26edb25bce0b78e6c14792c07ac03"/><file name="Emv_Report.xml" hash="b41b407bbd282fc33e0bf6970082a08b"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="emailvision"><file name="abandonment_report.xml" hash="f60cff6610a8ea2756b9ae4139688a1d"/></dir></dir><dir name="template"><dir name="emailvision"><dir name="abandonment"><dir name="grid"><file name="container.phtml" hash="3375ac98f71cab4a81bb59ef64b3d6fc"/></dir></dir><dir name="account"><file name="associated_urls.phtml" hash="b0f41cede2009e3728c819403cb28426"/></dir><dir name="datasync"><dir name="system"><dir name="config"><dir name="form"><dir name="field"><file name="array.phtml" hash="e809c2a4c2aecc27f5ec3f51faed3c0a"/></dir></dir><file name="getfields.phtml" hash="e5680827bf0c2955b252d0f711dc90e8"/></dir></dir></dir><dir name="emt"><dir name="template"><file name="common_js.phtml" hash="b91b877122f3d48728c5c97423c3eb42"/><file name="edit.phtml" hash="f09b248f3187d2f83c90765ad17b7413"/><file name="mapped_attributes.phtml" hash="be2ea5d80b24ad044e351607aa76932e"/></dir></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="emailvision"><file name="abandonment.xml" hash="c6f5b8cf0aec8cd0ac881b58167ff234"/></dir></dir><dir name="template"><dir name="emailvision"><dir name="abandonment"><file name="customer.phtml" hash="d63198ab64858039aa5b23f9964dd6d3"/><dir name="reminder"><file name="items.phtml" hash="c2e0211ac4c28d81c14199ecb7450a79"/></dir></dir></dir></dir></dir></dir></dir></target><target name="magecommunity"><dir name="Emv"><dir name="CartAlert"><dir name="Block"><dir name="Cart"><file name="Items.php" hash="a6a99b56060cb4254a384e5c4eaef467"/></dir><dir name="Customer"><file name="Abandonment.php" hash="06dd3435302590f774d29271cea4d76e"/></dir></dir><file name="Constants.php" hash="b10c0a770bf2075a30408b54dc4b9824"/><dir name="Helper"><file name="Data.php" hash="25185f79349a728a0ce684829c59e720"/></dir><dir name="Model"><file name="Abandonment.php" hash="ac7111c71d744dfc9713ae2894b41cc8"/><dir name="Mysql4"><dir name="Abandonment"><file name="Collection.php" hash="4f06a6c5528ff4d067dd963bab96fca2"/></dir><file name="Abandonment.php" hash="ef528abb65db08c6bed6f99cbe0947ca"/><dir name="Orderflag"><file name="Collection.php" hash="3fc55bad9566113db73b6e7632af4ec7"/></dir><file name="Orderflag.php" hash="5163bd389466708b84001fbeb85af913"/><dir name="Stats"><file name="Collection.php" hash="24178657849cf0bdffd939816f3c8ba9"/></dir><file name="Stats.php" hash="a54399b037a210a719abba376b0415bc"/></dir><file name="Observer.php" hash="768f5503d719f58c885c6ac7a202cb93"/><file name="Orderflag.php" hash="5a6e33fce2512ba3f4ee93e90fc6f4e8"/><dir name="Resource"><file name="Setup.php" hash="0724e1d2ed5fd1b5ef93a2a267a4ee21"/></dir><file name="Stats.php" hash="33e9f3578d961cd3db55ade1df61ef7b"/></dir><dir name="controllers"><file name="CustomerController.php" hash="5c042b38b1a0dedd46cb7403ea9371cb"/><file name="GuestController.php" hash="8fa642676dc3fc057c44d1d870ff1f37"/></dir><dir name="etc"><file name="adminhtml.xml" hash="c28a61bac9988480fb403007daba54ee"/><file name="config.xml" hash="874654c8b45830a2adf94d96b9311c04"/><file name="system.xml" hash="3fa7067de36957004c16bb753058af65"/></dir><dir name="sql"><dir name="abandonment_setup"><file name="mysql4-install-0.1.0.php" hash="ee9bc7cabf23bec2867ee1394562ce27"/><file name="mysql4-upgrade-0.1.0-0.2.0.php" hash="d77033018e89d437a229ef462c786f97"/><file name="mysql4-upgrade-0.2.0-0.3.0.php" hash="3ad1df3e579e6a5d1c18aa09f764937b"/><file name="mysql4-upgrade-0.3.0-0.4.0.php" hash="b2c7e93739a101f6f844db6f3548b080"/><file name="mysql4-upgrade-0.4.0-0.5.0.php" hash="7403b4f3b3edcc8665e85f3571abb58f"/><file name="mysql4-upgrade-0.5.0-0.5.1.php" hash="c893dd6a2b0d2304204dabf0659cc75c"/><file name="mysql4-upgrade-0.5.1-0.5.2.php" hash="35d81990131a6e9cd0bec82eeb8cbe68"/></dir></dir></dir><dir name="Core"><dir name="Block"><dir name="Adminhtml"><dir name="Account"><dir name="Edit"><file name="AssociatedUrls.php" hash="4879c49496102f0f152f589249817fad"/><file name="Form.php" hash="64420bd3f05f502d84673aaf6fa0f1e9"/></dir><file name="Edit.php" hash="7817ac5fbe3d641c6e4bd49ea1a4cc45"/><file name="Grid.php" hash="d7d869a26decc54beb2fbc9574c10b00"/></dir><file name="Accounts.php" hash="078f85d162665246cf6d475b4c6cbc16"/></dir></dir><dir name="Helper"><file name="Data.php" hash="f493849c2a6261c3a232f489caba8b44"/></dir><dir name="Model"><file name="Account.php" hash="0ca3e88df84a27c8986c0836c9d39b74"/><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Backend"><dir name="Account"><file name="Abstract.php" hash="d2b7f88918b2034284ce7ae042133229"/></dir><file name="Enabled.php" hash="b5b9c77a30d98097777dac3434d381b3"/></dir></dir></dir></dir><dir name="Mysql4"><dir name="Account"><file name="Collection.php" hash="f9dbdbb023051a3e412be801e7c1d5ec"/></dir><file name="Account.php" hash="b7949c5e00cb29efe2b067087933c6a4"/></dir><dir name="Resource"><file name="Setup.php" hash="1aed96e7fe8c8cb06b27b5ef56f8822f"/></dir><dir name="Service"><file name="Abstract.php" hash="6dca2afd30b6f2f3c23234663da6335f"/><file name="BatchMember.php" hash="b6cc28b33e169b40ddbb37b093cf13a1"/><file name="Member.php" hash="b46d65f710d9dbee42e8f805006b65b8"/><file name="Notification.php" hash="fd131bf3071e3b7b0614036ca3f76c63"/><file name="Transactional.php" hash="b16beffebe860b071110013b3d3d0571"/></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="Account.php" hash="8e5ce5e669d481188c7e13cfee510697"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="AccountController.php" hash="545158a529f9b3ac17d5ab02fee354e3"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="e8f219eefa333cc503c48b0c1586d403"/><file name="config.xml" hash="cbd11a1571fb5b72185ab1a00c2cd7fd"/><file name="system.xml" hash="85d9908f748a15c6247582418a1b606c"/></dir><dir name="sql"><dir name="emvcore_setup"><file name="mysql4-install-0.1.0.php" hash="b1319057a975d8dd2c829d6c00affc74"/><file name="mysql4-upgrade-0.1.0-0.2.0.php" hash="af4506f20cd8cdfa11c0394fdd78a06c"/></dir></dir></dir><dir name="DataSync"><dir name="Block"><dir name="Adminhtml"><dir name="Form"><dir name="Field"><file name="CustomerAttributes.php" hash="c6add4119550dae8a1d3db4e5bca9683"/><file name="EmailVisionFields.php" hash="67d9bb70184bd844cba669d4ac5c04ed"/></dir></dir><dir name="System"><dir name="Config"><file name="CustomerAttributes.php" hash="7508f9dc0df62e5c9faf9accd3361765"/><file name="Date.php" hash="1790331bd1bb06a441737ecf345df6da"/><file name="GetFields.php" hash="75291de3c2c5e0338e8c6069066264f5"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="7e3b1646ab8b9330f5585cf0a57661fb"/><file name="Service.php" hash="8f459e115ba5d2fbeba937852189e28b"/></dir><dir name="Model"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Backend"><dir name="ApiMember"><file name="Account.php" hash="09cfe4b6651eae737945ab16b25ce6bb"/><file name="Cron.php" hash="1e7a38db39c21d04b0249ec181c1993f"/><file name="Enabled.php" hash="19e91d89fa6a098010ea4d9582b72451"/></dir><dir name="BatchMember"><file name="Account.php" hash="844f3af6efd125d6b1d9ef8808984e79"/><file name="Cron.php" hash="572c1d835574039a9287da6760b7111d"/><file name="Enabled.php" hash="b00cce598c212933cc2fe1db4cc4d4b4"/></dir><dir name="Clean"><file name="Cron.php" hash="1e55644bb34417d3285bf9bca0aee646"/></dir></dir><dir name="Source"><file name="Fields.php" hash="5f469c279ddabaa6f1142616e6106089"/><file name="MemberCronTime.php" hash="0ed64e65649d2f8b783fcf2fb19f49f8"/></dir></dir></dir></dir><file name="Cron.php" hash="52bcf45cdad1c6d89f64ef242a5b085b"/><file name="Observer.php" hash="30d2a4ece7ebcf68ef04aa2caa74076c"/><dir name="Service"><file name="BatchMember.php" hash="de66836efdf1a913ce285f979c2930e7"/><file name="Member.php" hash="28176c130e55ee07fb93ece9c918c0af"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="DataSyncController.php" hash="c4e46f74ea35132f564587c798cc88cc"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="0d0ba154e5cf38895a2b2b0d907797fb"/><file name="config.xml" hash="331af61703669c4c1dca3c93899c6602"/><file name="system.xml" hash="4d5cf9fe165760476ccb273ea5693f26"/></dir><dir name="sql"><dir name="emvdatasync_setup"><file name="mysql4-install-0.0.1.php" hash="073ecf5a0c8aae1572e3ac91a35633ff"/></dir></dir></dir><dir name="Emt"><dir name="Block"><dir name="Adminhtml"><dir name="Log"><dir name="Grid"><dir name="Renderer"><file name="GetError.php" hash="a7fb7e3075e611b0e5b672d0ecee3ddd"/></dir></dir><file name="Grid.php" hash="82ca5fdaeb5403c0a39fe1b17e0d9958"/></dir><file name="Log.php" hash="24551f106915450e8e775b2bb1324451"/><dir name="Resending"><file name="Grid.php" hash="f56672b844f848df3414668ffa2855c5"/></dir><file name="Resending.php" hash="beaad1da5f136d403f8881e21dc9639e"/><dir name="Template"><dir name="Edit"><dir name="Tab"><file name="EmvContent.php" hash="a540805b70ec00fc6b5cdcc32b1a1cfb"/><file name="EmvDyn.php" hash="2c3f5c8f739691b3eeb6d53de6b64e46"/><file name="General.php" hash="776675c177b6a147fd90c5c6d8a3e601"/></dir><file name="Tabs.php" hash="320b4c3e740ba5aacbbd5c602ffb041c"/></dir><file name="Edit.php" hash="5c672e813e76cf81755c80f54c78ea13"/><dir name="Grid"><dir name="Renderer"><file name="Emvname.php" hash="1cf0f98ad194b33c4d9c91f0195c8146"/><file name="MageTemplate.php" hash="e284d93be818c24016bd462e31c226ee"/></dir></dir><file name="Grid.php" hash="19ab59d96e2925d6fe2b14aad3111498"/></dir><file name="Templates.php" hash="12bcab5abc0be49e4e04b0d92eecf61c"/></dir></dir><dir name="Helper"><file name="Data.php" hash="067567bd92ed2d9c5ccd0c2f2d7d8cd2"/><file name="Emvtemplate.php" hash="97463f51b60d133d30d0e3655486b9d0"/></dir><dir name="Model"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Backend"><file name="Account.php" hash="301e5056ac13f4d00ba5c047a6eb79a8"/></dir></dir></dir></dir><file name="Attribute.php" hash="b0c369fcc0bc47f48ba7c5866dc72260"/><file name="Cron.php" hash="c5cec405088a1b951d2767309adf3461"/><file name="Emt.php" hash="45ca86eb4dfa46ce78a53f9f66d79bb2"/><file name="Log.php" hash="16a2e7e2bd1039f39a66d9fb61a324e9"/><dir name="Mage"><dir name="Core"><dir name="Email"><file name="Template.php" hash="e5c31cf93c5b2aa0b88e8176463f5a77"/></dir></dir></dir><file name="MageTemplate.php" hash="ddf98c89b163c6e59ceed1ac5dbe8f69"/><file name="Mailmode.php" hash="e08c76d5d72b21d3bd8b6b441ec06527"/><dir name="Mysql4"><dir name="Attribute"><file name="Collection.php" hash="3e3308be1178e99162606a668eace8ed"/></dir><file name="Attribute.php" hash="bd2854ed8ee4fb207b994543a0ecf9ba"/><dir name="Emt"><file name="Collection.php" hash="bbc3368b7276bbff83c1770b6a097c26"/></dir><file name="Emt.php" hash="7fd5ff6b090587b56ac09366289b369f"/><dir name="Log"><file name="Collection.php" hash="dc04e8d73fa3df064453f7c7ee12a400"/></dir><file name="Log.php" hash="f379a53b42152472dded21708572bce8"/><dir name="Resending"><dir name="Queue"><dir name="Message"><file name="Collection.php" hash="8b165985970886c74aef0c9d62140098"/></dir><file name="Message.php" hash="63b4e07ee46f64d7f1c8284f5f789f71"/></dir></dir></dir><dir name="Resending"><dir name="Queue"><file name="Message.php" hash="4830bc5ef750efcd8973ee46f424ec51"/></dir><file name="Queue.php" hash="bb2128bf1a9ecd5cf9fb8d06f8de845b"/><file name="Rule.php" hash="3accdc868f171f3a328e41658871e31c"/></dir><dir name="Resource"><file name="Setup.php" hash="b5fc87772ed86c16c54eb9262dd291a3"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="LogController.php" hash="05fbabe704020cddc12a8656cc9220bd"/><file name="RescheduleController.php" hash="5331244d0bb14e448fbde3b797fb680d"/><file name="TemplateController.php" hash="71c335b0d6455bc51ba9f9e45d7639a4"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="193ed52e7bc6f002b4526d697166c84d"/><file name="config.xml" hash="f6fed0b59662a2b43b9271d9d3a9a046"/><file name="system.xml" hash="a6293b65fc0e398db437e443a992c3cc"/></dir><dir name="sql"><dir name="emvemt_setup"><file name="mysql4-install-0.1.0.php" hash="a7d12df049f2c1377a072fa7899dcb6c"/><file name="mysql4-upgrade-0.1.0-0.2.0.php" hash="3b52221a751b221ae98e16a03807335a"/><file name="mysql4-upgrade-0.2.0-0.3.0.php" hash="0108cecb8c995004987e869fc008bf34"/><file name="mysql4-upgrade-0.3.0-0.4.0.php" hash="7ef46dc220aeb7265ef43cab5b17156f"/><file name="mysql4-upgrade-0.4.0-0.4.1.php" hash="a6eb1e85d8773af9c0935bacabcc06dd"/></dir></dir></dir><dir name="Report"><dir name="Block"><dir name="Adminhtml"><dir name="Conversion"><file name="Form.php" hash="9c537aa62d666816058130d257f75bb8"/></dir><file name="Conversion.php" hash="79959891324dcc99448d93f9cfa01724"/><dir name="Details"><file name="Grid.php" hash="beb3a98688d554cb8d49aa5a8613bd5a"/></dir><file name="Details.php" hash="a765998cb0a765423f89cd652a2d1dab"/></dir></dir><dir name="Helper"><file name="Data.php" hash="14fd1c74a2de74a85190394166c1e684"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="ConversionController.php" hash="638f3ad969d3bc9fcec2f8e7b5c14854"/><file name="DetailsController.php" hash="653096279fbe200d6b5ac6208efe732a"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="973a0f60081aba81dc048f7a67963954"/><file name="config.xml" hash="f5a9c3e32da692808072c07be851a7de"/></dir></dir></dir><dir name="Mage"><dir name="SalesRule"><dir name="Helper"><file name="Coupon.php" hash="05d42b935bd31dad39c9e31052ef60c8"/></dir><dir name="Model"><dir name="Coupon"><file name="Massgenerator.php" hash="c5312f2a745bf79d2a8ac90c23fb79dc"/></dir><dir name="System"><dir name="Config"><dir name="Source"><dir name="Coupon"><file name="Format.php" hash="64236cb46364219d4a5702521898a249"/></dir></dir></dir></dir></dir></dir></dir></target></contents>
31
  <compatible/>
32
+ <dependencies><required><php><min>5.2.6</min><max>5.5.4</max></php></required></dependencies>
33
  </package>
skin/adminhtml/default/default/campaign-commander.css ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .emv_attributes .va-middle{
2
+ vertical-align: middle;
3
+ }
4
+ .emv_attributes .content-header {
5
+ margin-bottom: 10px;
6
+ border-bottom: 4px solid #FFF;
7
+ }
8
+ .emv_attributes textarea{
9
+ width: 90%;
10
+ margin-top: 2px;
11
+ }
12
+ .emv_attributes th{
13
+ height: 30px;
14
+ }