Bronto_Extension - Version 2.0.0.1

Version Notes

This is the first release of a new Bronto extension that replaces and deprecates the "Bronto Order Import for Magento," "Bronto Shopping Cart Abandonment," and "Bronto Newsletter Opt-In" extensions. All of the functionality of those extensions is included in this Bronto Extension for Magento.

For installation and configuration instructions, as well as a full list of new features and known issues, please review the Implementation Guide at http://a.bron.to/magento.

Download this release

Release Info

Developer Chris Geiss
Extension Bronto_Extension
Version 2.0.0.1
Comparing to
See all releases


Code changes from version 2.0.0 to 2.0.0.1

Files changed (277) hide show
  1. app/code/community/Bronto/Common/Block/Adminhtml/System/Config/About.php +95 -0
  2. app/code/community/Bronto/Common/Block/Adminhtml/System/Config/Cron.php +223 -0
  3. app/code/community/Bronto/Common/Block/Adminhtml/System/Config/Form/Field.php +31 -0
  4. app/code/community/Bronto/Common/Block/Adminhtml/System/Config/Form/Field/Apitoken.php +142 -0
  5. app/code/community/Bronto/Common/Block/Adminhtml/System/Config/Form/Field/Hidden.php +22 -0
  6. app/code/community/Bronto/Common/Block/Adminhtml/System/Config/Form/Field/List.php +46 -0
  7. app/code/community/Bronto/Common/Helper/Contact.php +86 -0
  8. app/code/community/Bronto/Common/Helper/Data.php +438 -0
  9. app/code/community/Bronto/Common/Helper/DataInterface.php +18 -0
  10. app/code/community/Bronto/Common/Helper/Field.php +38 -0
  11. app/code/community/Bronto/Common/Helper/Message.php +109 -0
  12. app/code/community/Bronto/Common/Helper/Product.php +138 -0
  13. app/code/community/Bronto/Common/Model/Api.php +69 -0
  14. app/code/community/Bronto/Common/Model/Email/Message.php +323 -0
  15. app/code/community/Bronto/Common/Model/Email/Message/Filter.php +839 -0
  16. app/code/community/Bronto/Common/Model/Email/Message/Templatefilter.php +291 -0
  17. app/code/community/Bronto/Common/Model/Keysentry.php +66 -0
  18. app/code/community/Bronto/Common/Model/Observer.php +35 -0
  19. app/code/community/Bronto/Common/Model/Resource/Setup.php +56 -0
  20. app/code/community/Bronto/Common/Model/System/Config/Backend/Cron.php +117 -0
  21. app/code/community/Bronto/Common/Model/System/Config/Backend/Token.php +49 -0
  22. app/code/community/Bronto/Common/Model/System/Config/Source/Contact/Status.php +48 -0
  23. app/code/community/Bronto/Common/Model/System/Config/Source/Cron/Frequency.php +41 -0
  24. app/code/community/Bronto/Common/Model/System/Config/Source/Cron/Minutes.php +28 -0
  25. app/code/community/Bronto/Common/Model/System/Config/Source/Field.php +50 -0
  26. app/code/community/Bronto/Common/Model/System/Config/Source/List.php +40 -0
  27. app/code/community/Bronto/Common/Model/System/Config/Source/Message.php +51 -0
  28. app/code/community/Bronto/Common/Test/Config/Config.php +171 -0
  29. app/code/community/Bronto/Common/Test/Model/Checkout.php +187 -0
  30. app/code/community/Bronto/Common/Test/Model/Keysentry.php +71 -0
  31. app/code/community/Bronto/Common/Test/Model/Keysentry/fixtures/seed.yaml +3 -0
  32. app/code/community/Bronto/Common/controllers/LogController.php +121 -0
  33. app/code/community/Bronto/Common/etc/adminhtml.xml +22 -0
  34. app/code/community/Bronto/Common/etc/config.xml +95 -0
  35. app/code/community/Bronto/Common/etc/system.xml +96 -0
  36. app/code/community/Bronto/Common/sql/bronto_common_setup/mysql4-install-1.7.0.php +10 -0
  37. app/code/community/Bronto/ConflictChecker/Block/Adminhtml/System/Config/About.php +54 -0
  38. app/code/community/Bronto/ConflictChecker/Block/Adminhtml/System/Config/Conflictchecker.php +88 -0
  39. app/code/community/Bronto/ConflictChecker/Block/Printer.php +77 -0
  40. app/code/community/Bronto/ConflictChecker/Helper/Data.php +34 -0
  41. app/code/community/Bronto/ConflictChecker/Model/Config/Blocks.php +69 -0
  42. app/code/community/Bronto/ConflictChecker/Model/Config/Checker.php +64 -0
  43. app/code/community/Bronto/ConflictChecker/Model/Config/ConfigAbstract.php +125 -0
  44. app/code/community/Bronto/ConflictChecker/Model/Config/ConfigInterface.php +46 -0
  45. app/code/community/Bronto/ConflictChecker/Model/Config/Datastore.php +98 -0
  46. app/code/community/Bronto/ConflictChecker/Model/Config/Helpers.php +69 -0
  47. app/code/community/Bronto/ConflictChecker/Model/Config/Models.php +68 -0
  48. app/code/community/Bronto/ConflictChecker/Model/Config/Printer.php +58 -0
  49. app/code/community/Bronto/ConflictChecker/Model/Config/Resources.php +69 -0
  50. app/code/community/Bronto/ConflictChecker/Model/Core/Config.php +2024 -0
  51. app/code/community/Bronto/ConflictChecker/Model/Core/Config/Base.php +50 -0
  52. app/code/community/Bronto/ConflictChecker/Model/Core/Config/Element.php +84 -0
  53. app/code/community/Bronto/ConflictChecker/Model/Lib/Varien/Simplexml/Config.php +46 -0
  54. app/code/community/Bronto/ConflictChecker/Model/Lib/Varien/Simplexml/Element.php +224 -0
  55. app/code/community/Bronto/ConflictChecker/Model/Mysql4/Core/Config.php +35 -0
  56. app/code/community/Bronto/ConflictChecker/Model/Path/Locator/Array.php +73 -0
  57. app/code/community/Bronto/ConflictChecker/Model/Path/Locator/Factory.php +55 -0
  58. app/code/community/Bronto/ConflictChecker/Model/Path/Locator/IteratorAbstract.php +60 -0
  59. app/code/community/Bronto/ConflictChecker/Model/Path/Locator/LocatorInterface.php +63 -0
  60. app/code/community/Bronto/ConflictChecker/Model/Path/Locator/Stack.php +73 -0
  61. app/code/community/Bronto/ConflictChecker/Model/Resource/Core/Config.php +260 -0
  62. app/code/community/Bronto/ConflictChecker/Test/Config/Config.php +259 -0
  63. app/code/community/Bronto/ConflictChecker/Test/Model/Path/Locator/Array.php +25 -0
  64. app/code/community/Bronto/ConflictChecker/Test/Model/Path/Locator/Factory.php +21 -0
  65. app/code/community/Bronto/ConflictChecker/Test/Model/Path/Locator/Stack.php +25 -0
  66. app/code/community/Bronto/ConflictChecker/etc/adminhtml.xml +32 -0
  67. app/code/community/Bronto/ConflictChecker/etc/config.xml +60 -0
  68. app/code/community/Bronto/ConflictChecker/etc/system.xml +32 -0
  69. app/code/community/Bronto/Customer/Block/Adminhtml/System/Config/About.php +19 -0
  70. app/code/community/Bronto/Customer/Block/Adminhtml/System/Config/Cron.php +65 -0
  71. app/code/community/Bronto/Customer/Block/Adminhtml/System/Config/Form/Fieldset/Attributes.php +90 -0
  72. app/code/community/Bronto/Customer/Block/Adminhtml/System/Config/Form/Fieldset/Attributes/Address.php +46 -0
  73. app/code/community/Bronto/Customer/Block/Adminhtml/System/Config/Form/Fieldset/Attributes/Customer.php +52 -0
  74. app/code/community/Bronto/Customer/Block/Adminhtml/Widget/Button/Reset.php +23 -0
  75. app/code/community/Bronto/Customer/Block/Adminhtml/Widget/Button/Run.php +22 -0
  76. app/code/community/Bronto/Customer/Helper/Data.php +63 -0
  77. app/code/community/Bronto/Customer/Model/Customer/Observer.php +19 -0
  78. app/code/community/Bronto/Customer/Model/Observer.php +186 -0
  79. app/code/community/Bronto/Customer/Model/Resource/Customer/Collection.php +81 -0
  80. app/code/community/Bronto/Customer/Model/Resource/Setup.php +20 -0
  81. app/code/community/Bronto/Customer/Model/System/Config/Backend/Cron.php +11 -0
  82. app/code/community/Bronto/Customer/Model/System/Config/Backend/Newfield.php +54 -0
  83. app/code/community/Bronto/Customer/Test/Config/Config.php +148 -0
  84. app/code/community/Bronto/Customer/controllers/Adminhtml/CustomerController.php +123 -0
  85. app/code/community/Bronto/Customer/etc/adminhtml.xml +22 -0
  86. app/code/community/Bronto/Customer/etc/config.xml +143 -0
  87. app/code/community/Bronto/Customer/etc/system.xml +547 -0
  88. app/code/community/Bronto/Customer/sql/bronto_customer_setup/mysql4-install-1.0.0.php +27 -0
  89. app/code/community/Bronto/Email/Block/Adminhtml/System/Config/About.php +19 -0
  90. app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Log.php +56 -0
  91. app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Log/Grid.php +102 -0
  92. app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Log/Grid/Renderer/Customer.php +27 -0
  93. app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Log/Grid/Renderer/Fields.php +41 -0
  94. app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Template.php +95 -0
  95. app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Template/Edit.php +75 -0
  96. app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Template/Edit/Form.php +119 -0
  97. app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Template/Grid.php +107 -0
  98. app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Template/Grid/Renderer/Message.php +30 -0
  99. app/code/community/Bronto/Email/Helper/Contact.php +28 -0
  100. app/code/community/Bronto/Email/Helper/Data.php +57 -0
  101. app/code/community/Bronto/Email/Helper/Field.php +19 -0
  102. app/code/community/Bronto/Email/Helper/Message.php +19 -0
  103. app/code/community/Bronto/Email/Model/Email/Message.php +67 -0
  104. app/code/community/Bronto/Email/Model/Log.php +15 -0
  105. app/code/community/Bronto/Email/Model/Mysql4/Log.php +14 -0
  106. app/code/community/Bronto/Email/Model/Mysql4/Log/Collection.php +40 -0
  107. app/code/community/Bronto/Email/Model/Observer.php +27 -0
  108. app/code/community/Bronto/Email/Model/System/Config/Source/Email/Template.php +50 -0
  109. app/code/community/Bronto/Email/Model/Template/Import.php +140 -0
  110. app/code/community/Bronto/Email/Test/Config/Config.php +216 -0
  111. app/code/community/Bronto/Email/Test/Model/Email/Message.php +37 -0
  112. app/code/community/Bronto/Email/controllers/Adminhtml/System/Email/LogController.php +38 -0
  113. app/code/community/Bronto/Email/controllers/Adminhtml/System/Email/TemplateController.php +117 -0
  114. app/code/community/Bronto/Email/etc/adminhtml.xml +23 -0
  115. app/code/community/Bronto/Email/etc/config.xml +136 -0
  116. app/code/community/Bronto/Email/etc/system.xml +64 -0
  117. app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-install-1.0.0.php +30 -0
  118. app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-install-1.0.2.php +59 -0
  119. app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-install-1.0.5.php +59 -0
  120. app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-install-1.0.8.php +64 -0
  121. app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-install-1.1.2.php +75 -0
  122. app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-upgrade-1.0.0-1.0.2.php +48 -0
  123. app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-upgrade-1.0.2-1.0.5.php +8 -0
  124. app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-upgrade-1.0.5-1.0.8.php +21 -0
  125. app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-upgrade-1.0.8-1.1.1.php +8 -0
  126. app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-upgrade-1.1.1-1.1.2.php +20 -0
  127. app/code/community/Bronto/Newsletter/Block/Adminhtml/System/Config/About.php +24 -0
  128. app/code/community/Bronto/Newsletter/Block/Adminhtml/System/Config/Cron.php +66 -0
  129. app/code/community/Bronto/Newsletter/Block/Adminhtml/Widget/Button/Run.php +22 -0
  130. app/code/community/Bronto/Newsletter/Block/Checkout/Onepage/Newsletter.php +65 -0
  131. app/code/community/Bronto/Newsletter/Helper/Contact.php +129 -0
  132. app/code/community/Bronto/Newsletter/Helper/Data.php +160 -0
  133. app/code/community/Bronto/Newsletter/Model/Mysql4/Queue.php +39 -0
  134. app/code/community/Bronto/Newsletter/Model/Mysql4/Queue/Collection.php +40 -0
  135. app/code/community/Bronto/Newsletter/Model/Observer.php +169 -0
  136. app/code/community/Bronto/Newsletter/Model/Queue.php +41 -0
  137. app/code/community/Bronto/Newsletter/Test/Config/Config.php +226 -0
  138. app/code/community/Bronto/Newsletter/controllers/Adminhtml/NewsletterController.php +123 -0
  139. app/code/community/Bronto/Newsletter/etc/adminhtml.xml +22 -0
  140. app/code/community/Bronto/Newsletter/etc/config.xml +178 -0
  141. app/code/community/Bronto/Newsletter/etc/system.xml +212 -0
  142. app/code/community/Bronto/Newsletter/sql/bronto_newsletter_setup/mysql4-install-1.0.0.php +27 -0
  143. app/code/community/Bronto/Newsletter/sql/bronto_newsletter_setup/mysql4-install-1.4.0.php +27 -0
  144. app/code/community/Bronto/Newsletter/sql/bronto_newsletter_setup/mysql4-upgrade-1.4.0-1.4.1.php +29 -0
  145. app/code/community/Bronto/Order/Block/Adminhtml/Sales/Order/View/Tab/Info.php +63 -0
  146. app/code/community/Bronto/Order/Block/Adminhtml/System/Config/About.php +24 -0
  147. app/code/community/Bronto/Order/Block/Adminhtml/System/Config/Cron.php +72 -0
  148. app/code/community/Bronto/Order/Block/Adminhtml/Widget/Button/Reset.php +28 -0
  149. app/code/community/Bronto/Order/Block/Adminhtml/Widget/Button/Run.php +27 -0
  150. app/code/community/Bronto/Order/Block/Bta.php +31 -0
  151. app/code/community/Bronto/Order/Helper/Data.php +62 -0
  152. app/code/community/Bronto/Order/Model/Observer.php +239 -0
  153. app/code/community/Bronto/Order/Model/Order/Observer.php +46 -0
  154. app/code/community/Bronto/Order/Model/Quote/Observer.php +28 -0
  155. app/code/community/Bronto/Order/Model/Resource/Order/Collection.php +81 -0
  156. app/code/community/Bronto/Order/Model/Resource/Setup.php +31 -0
  157. app/code/community/Bronto/Order/Model/System/Config/Backend/Cron.php +19 -0
  158. app/code/community/Bronto/Order/Model/System/Config/Source/Description.php +20 -0
  159. app/code/community/Bronto/Order/Model/System/Config/Source/Limit.php +23 -0
  160. app/code/community/Bronto/Order/Test/Config/Config.php +233 -0
  161. app/code/community/Bronto/Order/controllers/Adminhtml/OrderController.php +137 -0
  162. app/code/community/Bronto/Order/etc/adminhtml.xml +22 -0
  163. app/code/community/Bronto/Order/etc/config.xml +176 -0
  164. app/code/community/Bronto/Order/etc/system.xml +115 -0
  165. app/code/community/Bronto/Order/sql/bronto_order_setup/mysql4-install-1.0.0.php +39 -0
  166. app/code/community/Bronto/PermissionChecker/Block/Adminhtml/System/Config/About.php +54 -0
  167. app/code/community/Bronto/PermissionChecker/Block/Adminhtml/System/Config/Permissionchecker.php +78 -0
  168. app/code/community/Bronto/PermissionChecker/Block/Printer.php +77 -0
  169. app/code/community/Bronto/PermissionChecker/Helper/Data.php +33 -0
  170. app/code/community/Bronto/PermissionChecker/Model/Validator/Checker.php +60 -0
  171. app/code/community/Bronto/PermissionChecker/Model/Validator/Directory.php +65 -0
  172. app/code/community/Bronto/PermissionChecker/Model/Validator/File.php +67 -0
  173. app/code/community/Bronto/PermissionChecker/Model/Validator/Filter/PatternIterator.php +55 -0
  174. app/code/community/Bronto/PermissionChecker/Model/Validator/Group.php +69 -0
  175. app/code/community/Bronto/PermissionChecker/Model/Validator/Owner.php +69 -0
  176. app/code/community/Bronto/PermissionChecker/Model/Validator/Printer.php +53 -0
  177. app/code/community/Bronto/PermissionChecker/Model/Validator/ValidatorAbstract.php +92 -0
  178. app/code/community/Bronto/PermissionChecker/Model/Validator/ValidatorInterface.php +48 -0
  179. app/code/community/Bronto/PermissionChecker/Test/Config/Config.php +197 -0
  180. app/code/community/Bronto/PermissionChecker/etc/adminhtml.xml +32 -0
  181. app/code/community/Bronto/PermissionChecker/etc/config.xml +64 -0
  182. app/code/community/Bronto/PermissionChecker/etc/system.xml +78 -0
  183. app/code/community/Bronto/Reminder/Block/Adminhtml/Promo/Notice.php +29 -0
  184. app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder.php +26 -0
  185. app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit.php +90 -0
  186. app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit/Form.php +24 -0
  187. app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit/Tab/Bronto.php +62 -0
  188. app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit/Tab/Conditions.php +33 -0
  189. app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit/Tab/Customers.php +129 -0
  190. app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit/Tab/General.php +136 -0
  191. app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit/Tabs.php +56 -0
  192. app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Grid.php +95 -0
  193. app/code/community/Bronto/Reminder/Block/Adminhtml/System/Config/About.php +19 -0
  194. app/code/community/Bronto/Reminder/Block/Adminhtml/System/Config/Cron.php +14 -0
  195. app/code/community/Bronto/Reminder/Block/Adminhtml/Widget/Grid/Column/Renderer/Email.php +21 -0
  196. app/code/community/Bronto/Reminder/Block/Adminhtml/Widget/Grid/Column/Renderer/Id.php +22 -0
  197. app/code/community/Bronto/Reminder/Helper/Contact.php +28 -0
  198. app/code/community/Bronto/Reminder/Helper/Data.php +79 -0
  199. app/code/community/Bronto/Reminder/Helper/Message.php +19 -0
  200. app/code/community/Bronto/Reminder/Model/Condition/Abstract.php +61 -0
  201. app/code/community/Bronto/Reminder/Model/Condition/Combine/Abstract.php +188 -0
  202. app/code/community/Bronto/Reminder/Model/Email/Message.php +14 -0
  203. app/code/community/Bronto/Reminder/Model/Guest.php +15 -0
  204. app/code/community/Bronto/Reminder/Model/Mysql4/Customer/Collection.php +79 -0
  205. app/code/community/Bronto/Reminder/Model/Mysql4/Guest.php +14 -0
  206. app/code/community/Bronto/Reminder/Model/Mysql4/Guest/Collection.php +15 -0
  207. app/code/community/Bronto/Reminder/Model/Mysql4/Rule.php +500 -0
  208. app/code/community/Bronto/Reminder/Model/Mysql4/Rule/Collection.php +138 -0
  209. app/code/community/Bronto/Reminder/Model/Observer.php +127 -0
  210. app/code/community/Bronto/Reminder/Model/Rule.php +377 -0
  211. app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart.php +237 -0
  212. app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Amount.php +94 -0
  213. app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Attributes.php +112 -0
  214. app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Combine.php +45 -0
  215. app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Couponcode.php +88 -0
  216. app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Itemsquantity.php +69 -0
  217. app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Sku.php +82 -0
  218. app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Storeview.php +117 -0
  219. app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Subcombine.php +39 -0
  220. app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Subselection.php +103 -0
  221. app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Totalquantity.php +69 -0
  222. app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Virtual.php +87 -0
  223. app/code/community/Bronto/Reminder/Model/Rule/Condition/Combine.php +40 -0
  224. app/code/community/Bronto/Reminder/Model/Rule/Condition/Combine/Root.php +76 -0
  225. app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist.php +149 -0
  226. app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Attributes.php +159 -0
  227. app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Combine.php +37 -0
  228. app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Quantity.php +73 -0
  229. app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Sharing.php +84 -0
  230. app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Storeview.php +116 -0
  231. app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Subcombine.php +33 -0
  232. app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Subselection.php +114 -0
  233. app/code/community/Bronto/Reminder/Model/System/Config/Backend/Cron.php +19 -0
  234. app/code/community/Bronto/Reminder/Test/Config/Config.php +187 -0
  235. app/code/community/Bronto/Reminder/Test/Helper/Contact.php +31 -0
  236. app/code/community/Bronto/Reminder/Test/Helper/Data.php +98 -0
  237. app/code/community/Bronto/Reminder/Test/Helper/Message.php +21 -0
  238. app/code/community/Bronto/Reminder/Test/Model/Observer.php +36 -0
  239. app/code/community/Bronto/Reminder/Test/Model/Rule.php +47 -0
  240. app/code/community/Bronto/Reminder/controllers/Adminhtml/RemindersController.php +396 -0
  241. app/code/community/Bronto/Reminder/controllers/LoadController.php +77 -0
  242. app/code/community/Bronto/Reminder/etc/adminhtml.xml +46 -0
  243. app/code/community/Bronto/Reminder/etc/config.xml +194 -0
  244. app/code/community/Bronto/Reminder/etc/system.xml +124 -0
  245. app/code/community/Bronto/Reminder/sql/bronto_reminder_setup/mysql4-install-1.4.2.php +111 -0
  246. app/code/community/Bronto/Reminder/sql/bronto_reminder_setup/mysql4-upgrade-1.4.0-1.4.2.php +20 -0
  247. app/code/community/Bronto/Reminder/sql/bronto_reminder_setup/mysql4-upgrade-1.4.10-1.4.11.php +34 -0
  248. app/code/community/Bronto/Reminder/sql/bronto_reminder_setup/mysql4-upgrade-1.4.2-1.4.9.php +28 -0
  249. app/code/community/Bronto/Reminder/sql/bronto_reminder_setup/mysql4-upgrade-1.4.9-1.4.10.php +20 -0
  250. app/code/community/Bronto/Reminder/sql/reference/saveMatchedCustomers.sql +21 -0
  251. app/code/community/Bronto/Roundtrip/Block/Adminhtml/System/Config/About.php +24 -0
  252. app/code/community/Bronto/Roundtrip/Block/Adminhtml/System/Config/Status.php +91 -0
  253. app/code/community/Bronto/Roundtrip/Block/Adminhtml/Widget/Button/Run.php +18 -0
  254. app/code/community/Bronto/Roundtrip/Helper/Data.php +139 -0
  255. app/code/community/Bronto/Roundtrip/Model/Contact/Builder.php +107 -0
  256. app/code/community/Bronto/Roundtrip/Model/Roundtrip.php +378 -0
  257. app/code/community/Bronto/Roundtrip/Model/Roundtrip/Test/Order.php +106 -0
  258. app/code/community/Bronto/Roundtrip/Test/Config/Config.php +196 -0
  259. app/code/community/Bronto/Roundtrip/Test/Model/Roundtrip.php +82 -0
  260. app/code/community/Bronto/Roundtrip/Test/Model/Roundtrip/Contact.php +24 -0
  261. app/code/community/Bronto/Roundtrip/Test/Model/Roundtrip/Test/Order.php +33 -0
  262. app/code/community/Bronto/Roundtrip/controllers/Adminhtml/RoundtripController.php +87 -0
  263. app/code/community/Bronto/Roundtrip/etc/adminhtml.xml +31 -0
  264. app/code/community/Bronto/Roundtrip/etc/config.xml +81 -0
  265. app/code/community/Bronto/Roundtrip/etc/system.xml +23 -0
  266. app/design/adminhtml/default/default/layout/bronto/email.xml +8 -0
  267. app/design/adminhtml/default/default/layout/bronto/reminder.xml +8 -0
  268. app/design/adminhtml/default/default/layout/bronto/roundtrip.xml +8 -0
  269. app/design/adminhtml/default/default/template/bronto/common/about.phtml +16 -0
  270. app/design/adminhtml/default/default/template/bronto/common/cron.phtml +46 -0
  271. app/design/adminhtml/default/default/template/bronto/conflictchecker/errors.phtml +47 -0
  272. app/design/adminhtml/default/default/template/bronto/email/template/edit.phtml +256 -0
  273. app/design/adminhtml/default/default/template/bronto/email/template/list.phtml +41 -0
  274. app/design/adminhtml/default/default/template/bronto/permissionchecker/errors.phtml +28 -0
  275. app/design/adminhtml/default/default/template/bronto/roundtrip/status.phtml +5 -0
  276. app/locale/en_US/template/email/bronto/abandoned_cart.html +279 -0
  277. package.xml +4 -4
app/code/community/Bronto/Common/Block/Adminhtml/System/Config/About.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 2.0.0
7
+ */
8
+ class Bronto_Common_Block_Adminhtml_System_Config_About extends Mage_Adminhtml_Block_System_Config_Form_Fieldset
9
+ {
10
+ /**
11
+ * Name of module
12
+ * @var string
13
+ */
14
+ protected $_module = 'bronto_common';
15
+
16
+ /**
17
+ * Module display name
18
+ * @var string
19
+ */
20
+ protected $_name = 'Bronto Extension for Magento';
21
+
22
+ public function _construct()
23
+ {
24
+ parent::_construct();
25
+ $this->setTemplate('bronto/common/about.phtml');
26
+ }
27
+
28
+ /**
29
+ * @param Varien_Data_Form_Element_Abstract $element
30
+ * @return string
31
+ */
32
+ public function render(Varien_Data_Form_Element_Abstract $element)
33
+ {
34
+ return $this->toHtml();
35
+ }
36
+
37
+ /**
38
+ * Get the module namespace
39
+ * @return string
40
+ */
41
+ public function getModuleNamespace()
42
+ {
43
+ return $this->_module;
44
+ }
45
+
46
+ /**
47
+ * Get the module name
48
+ * @return string
49
+ */
50
+ public function getModuleName()
51
+ {
52
+ return $this->_name;
53
+ }
54
+
55
+ /**
56
+ * Get the module version
57
+ * @return string
58
+ */
59
+ public function getModuleVersion()
60
+ {
61
+ $version = Mage::helper($this->_module)->getModuleVersion();
62
+ return empty($version) ? null : "v{$version}";
63
+ }
64
+
65
+ /**
66
+ * Get log url
67
+ *
68
+ * @return string
69
+ */
70
+ public function getLogViewUrl()
71
+ {
72
+ return Mage::getSingleton('adminhtml/url')->getUrl('bronto/log/index', array('print' => 1, 'file' => $this->_module));
73
+ }
74
+
75
+ /**
76
+ * Get if debugging is turned on for module
77
+ *
78
+ * @return bool
79
+ */
80
+ public function hasDebugEnabled()
81
+ {
82
+ return (bool) Mage::helper($this->_module)->isDebugEnabled();
83
+ }
84
+
85
+ /**
86
+ * Get if the log file exists
87
+ *
88
+ * @return bool
89
+ */
90
+ public function logFileExists()
91
+ {
92
+ $logFile = Mage::getBaseDir('log') . DIRECTORY_SEPARATOR . "{$this->_module}.log";
93
+ return (bool) @file_exists($logFile);
94
+ }
95
+ }
app/code/community/Bronto/Common/Block/Adminhtml/System/Config/Cron.php ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Block_Adminhtml_System_Config_Cron extends Mage_Adminhtml_Block_System_Config_Form_Fieldset
9
+ {
10
+ /**
11
+ * Job code
12
+ * @var string
13
+ */
14
+ protected $_jobCode;
15
+
16
+ /**
17
+ * Button widgets
18
+ * @var array
19
+ */
20
+ protected $_buttons = array();
21
+
22
+ /**
23
+ * Progress bar
24
+ * @var boolean
25
+ */
26
+ protected $_hasProgressBar = false;
27
+
28
+ public function _construct()
29
+ {
30
+ parent::_construct();
31
+ $this->setTemplate('bronto/common/cron.phtml');
32
+ }
33
+
34
+ /**
35
+ * Prepare the layout
36
+ *
37
+ * @return Bronto_Common_Block_Adminhtml_System_Config_Cron
38
+ */
39
+ protected function _prepareLayout()
40
+ {
41
+ if ($head = $this->getLayout()->getBlock('head')) {
42
+ $head->addCss('bronto/cron.css');
43
+ }
44
+
45
+ return parent::_prepareLayout();
46
+ }
47
+
48
+ /**
49
+ * Render the block
50
+ *
51
+ * @param Varien_Data_Form_Element_Abstract $element
52
+ * @return string
53
+ */
54
+ public function render(Varien_Data_Form_Element_Abstract $element)
55
+ {
56
+ return $this->toHtml();
57
+ }
58
+
59
+ /**
60
+ * Get a job schedule collection
61
+ *
62
+ * @return Mage_Cron_Model_Mysql4_Schedule_Collection
63
+ */
64
+ public function getJobSchedule()
65
+ {
66
+ return Mage::getModel('cron/schedule')->getCollection()
67
+ ->addFieldToFilter('job_code', $this->_jobCode)
68
+ ->setPageSize(6)
69
+ ->setCurPage(1)
70
+ ->setOrder('scheduled_at', 'DESC');
71
+ }
72
+
73
+ /**
74
+ * Get cron job message
75
+ * Note: Limits to 100 characters
76
+ *
77
+ * @param Mage_Cron_Model_Schedule $job
78
+ * @return string
79
+ */
80
+ public function getTruncatedJobMessages($job)
81
+ {
82
+ return Mage::helper('core/string')->truncate($job->getMessages(), 100);
83
+ }
84
+
85
+ /**
86
+ * Get the HTML markup for the button widgets
87
+ *
88
+ * @return string
89
+ */
90
+ public function getButtonsHtml()
91
+ {
92
+ $html = null;
93
+ if ($buttons = $this->getButtons()) {
94
+ foreach ($buttons as $_button) {
95
+ $html .= $_button->toHtml();
96
+ }
97
+ }
98
+
99
+ if (!empty($html)) {
100
+ $html = "<p class=\"form-buttons\">{$html}</p>";
101
+ }
102
+
103
+ return $html;
104
+ }
105
+
106
+ /**
107
+ * Get the HTML markup for the progress bar
108
+ *
109
+ * @return string
110
+ */
111
+ public function getProgressBarHtml()
112
+ {
113
+ $percent = 0;
114
+ $pending = (int) $this->getProgressBarPending();
115
+ $total = (int) $this->getProgressBarTotal();
116
+
117
+ $complete = $total - $pending;
118
+ if ($complete > 0) {
119
+ $percent = round(($complete / $total) * 100);
120
+ }
121
+
122
+ $message = "{$percent}% ({$complete}/{$total})";
123
+ $html = "<div class=\"bronto-progress-bar\"><div style=\"width: {$percent}%\">";
124
+ if ($percent < 25) {
125
+ $html .= "</div>{$message}";
126
+ } else {
127
+ $html .= "{$message}</div>";
128
+ }
129
+ $html .= '</div>';
130
+
131
+ return $html;
132
+ }
133
+
134
+ /**
135
+ * Color code the job status
136
+ *
137
+ * @param string $status
138
+ * @return string
139
+ */
140
+ public function decorateJobStatus($status)
141
+ {
142
+ switch ($status) {
143
+ case Mage_Cron_Model_Schedule::STATUS_SUCCESS:
144
+ $color = 'green';
145
+ break;
146
+ case Mage_Cron_Model_Schedule::STATUS_RUNNING:
147
+ $color = 'yellow';
148
+ break;
149
+ case Mage_Cron_Model_Schedule::STATUS_MISSED:
150
+ $color = 'orange';
151
+ break;
152
+ case Mage_Cron_Model_Schedule::STATUS_ERROR:
153
+ $color = 'red';
154
+ break;
155
+ case Mage_Cron_Model_Schedule::STATUS_PENDING:
156
+ default:
157
+ $color = 'lightgray';
158
+ break;
159
+ }
160
+
161
+ return "<span class=\"bar-{$color}\"><span>{$status}</span></span>";
162
+ }
163
+
164
+ /**
165
+ * Add button widget
166
+ *
167
+ * @param Mage_Adminhtml_Block_Widget_Button $button
168
+ * @return Bronto_Common_Block_Adminhtml_System_Config_Cron
169
+ */
170
+ public function addButton(Mage_Adminhtml_Block_Widget_Button $button)
171
+ {
172
+ $this->_buttons[] = $button;
173
+ return $this;
174
+ }
175
+
176
+ /**
177
+ * Get button widgets
178
+ *
179
+ * @return array
180
+ */
181
+ public function getButtons()
182
+ {
183
+ return $this->_buttons;
184
+ }
185
+
186
+ /**
187
+ * Set if we're using a progress bar
188
+ *
189
+ * @param bool $hasProgressBar
190
+ * @return Bronto_Common_Block_Adminhtml_System_Config_Cron
191
+ */
192
+ public function setHasProgressBar($hasProgressBar)
193
+ {
194
+ $this->_hasProgressBar = $hasProgressBar;
195
+ return $this;
196
+ }
197
+
198
+ /**
199
+ * Get if we have a progress bar
200
+ *
201
+ * @return boolean
202
+ */
203
+ public function hasProgressBar()
204
+ {
205
+ return (bool) $this->_hasProgressBar;
206
+ }
207
+
208
+ /**
209
+ * @return int
210
+ */
211
+ protected function getProgressBarTotal()
212
+ {
213
+ return 0;
214
+ }
215
+
216
+ /**
217
+ * @return int
218
+ */
219
+ protected function getProgressBarPending()
220
+ {
221
+ return 0;
222
+ }
223
+ }
app/code/community/Bronto/Common/Block/Adminhtml/System/Config/Form/Field.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Block_Adminhtml_System_Config_Form_Field extends Mage_Adminhtml_Block_System_Config_Form_Field
9
+ {
10
+ /**
11
+ * Override method to output our custom HTML with JavaScript
12
+ *
13
+ * @param Varien_Data_Form_Element_Abstract $element
14
+ * @return String
15
+ */
16
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
17
+ {
18
+ if (!extension_loaded('soap') || !extension_loaded('openssl')) {
19
+ $element->setDisabled('disabled')->setValue(0);
20
+ } else {
21
+ if (!Mage::helper('bronto_common')->getApiToken()) {
22
+ $element->setDisabled('disabled')->setValue(0);
23
+ if ($element->getLabel() === 'Enable Module') {
24
+ $element->setComment('<span style="color:red;font-weight: bold">A valid Bronto API key is required.</span>');
25
+ }
26
+ }
27
+ }
28
+
29
+ return parent::_getElementHtml($element);
30
+ }
31
+ }
app/code/community/Bronto/Common/Block/Adminhtml/System/Config/Form/Field/Apitoken.php ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Block_Adminhtml_System_Config_Form_Field_Apitoken extends Mage_Adminhtml_Block_System_Config_Form_Field
9
+ {
10
+ /**
11
+ * Get element ID of the dependent field's parent row
12
+ *
13
+ * @param object $element
14
+ * @return String
15
+ */
16
+ protected function _getRowElementId($element)
17
+ {
18
+ return 'row_' . $element->getId();
19
+ }
20
+
21
+ /**
22
+ * Override method to output our custom HTML with JavaScript
23
+ *
24
+ * @param Varien_Data_Form_Element_Abstract $element
25
+ * @return String
26
+ */
27
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
28
+ {
29
+ $_html = array();
30
+
31
+ if (!Mage::helper('bronto_common')->getApiToken()) {
32
+ $element->setComment('<span style="color:red;font-weight:bold">Please enter your Bronto API key here.</span>');
33
+ $element->setData('onchange', "toggleDisabled(this.form, this);");
34
+ $element->setData('after_element_html', "
35
+ <script>
36
+ function toggleDisabled(form, element) {
37
+ var disabled = (element.value.length < 36);
38
+ for (i = 0; i < form.length; i++) {
39
+ if (form.elements[i].id != '{$element->getId()}' &&
40
+ form.elements[i].type != 'hidden' &&
41
+ form.elements[i].name.indexOf('groups') == 0) {
42
+ console.log(form.elements[i]);
43
+ form.elements[i].disabled = disabled;
44
+ }
45
+ }
46
+ var last = element.parentNode.lastChild;
47
+ if (last.className == 'note') {
48
+ last.innerHTML = '';
49
+ }
50
+
51
+ var buttonP = document.getElementById('verify-button');
52
+ console.log(buttonP);
53
+ console.log(buttonP.children[0]);
54
+ for (i = 0; i < buttonP.children.length; i++) {
55
+ console.log(buttonP.children[i]);
56
+ console.log(i);
57
+ if (disabled) {
58
+ $(buttonP.children[i]).addClassName('disabled');
59
+ }
60
+ buttonP.children[i].disabled = disabled;
61
+ }
62
+ }
63
+ </script>
64
+ ");
65
+
66
+ $button = $this
67
+ ->getLayout()
68
+ ->createBlock('bronto_roundtrip/adminhtml_widget_button_run')
69
+ ->setData('disabled', 'disabled')
70
+ ->toHtml()
71
+ ;
72
+ } else {
73
+ try {
74
+ $button = $this
75
+ ->getLayout()
76
+ ->createBlock('bronto_roundtrip/adminhtml_widget_button_run')
77
+ ->toHtml()
78
+ ;
79
+
80
+ $organization = null;
81
+ $name = null;
82
+ $email = null;
83
+
84
+ /* @var $loginObject Bronto_Api_Login */
85
+ $loginObject = Mage::helper('bronto_common')->getApi()->getLoginObject();
86
+ $iterator = $loginObject->readAll()->iterate();
87
+ foreach ($iterator as $login /* @var $login Bronto_Api_Login_Row */) {
88
+ if ($iterator->count() == 1) {
89
+ if (isset($login->contactInformation->organization)) {
90
+ $organization = $login->contactInformation->organization;
91
+ }
92
+ if (isset($login->contactInformation->firstName)) {
93
+ $name = trim($login->contactInformation->firstName);
94
+ }
95
+ if (isset($login->contactInformation->lastName)) {
96
+ $name .= trim(' ' . $login->contactInformation->lastName);
97
+ }
98
+ if (isset($login->contactInformation->email)) {
99
+ $email = trim($login->contactInformation->email);
100
+ }
101
+ } else {
102
+ if (isset($login->contactInformation->organization)) {
103
+ if (strlen($login->contactInformation->organization) > $organization) {
104
+ $organization = $login->contactInformation->organization;
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ if (!empty($organization)) {
111
+ $_html[] = '<strong style="float: left; width: 88px">Organization:</strong> ' . $organization;
112
+ }
113
+
114
+ if (!empty($name)) {
115
+ $_html[] = '<strong style="float: left; width: 88px">Name:</strong> ' . $name;
116
+ }
117
+
118
+ if (!empty($email)) {
119
+ $_html[] = '<strong style="float: left; width: 88px">Email:</strong> ' . $email;
120
+ }
121
+ } catch (Exception $e) {
122
+ //
123
+ }
124
+ }
125
+
126
+ // Show Roundtrip Install Verification Status
127
+ $buttonHtml = "<p class=\"form-buttons\" id=\"verify-button\">{$button}</p>";
128
+ $_html[] = '<strong style="float: left; width: 88px">Install Status:</strong> ' .
129
+ Mage::helper('bronto_roundtrip')->getRoundtripStatusText() . $buttonHtml;
130
+
131
+ // Show everything Else
132
+ if (!empty($_html)) {
133
+ $elementHtml = $element->getElementHtml();
134
+ $elementHtml .= '<div style="margin-top:10px">';
135
+ $elementHtml .= implode('<br />', $_html);
136
+ $elementHtml .= '</div>';
137
+ return $elementHtml;
138
+ }
139
+
140
+ return parent::_getElementHtml($element);
141
+ }
142
+ }
app/code/community/Bronto/Common/Block/Adminhtml/System/Config/Form/Field/Hidden.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Block_Adminhtml_System_Config_Form_Field_Hidden extends Mage_Adminhtml_Block_System_Config_Form_Field
9
+ {
10
+ /**
11
+ * @param Varien_Data_Form_Element_Abstract $element
12
+ * @return string
13
+ */
14
+ public function render(Varien_Data_Form_Element_Abstract $element)
15
+ {
16
+ if (!extension_loaded('soap') || !extension_loaded('openssl') || !Mage::helper('bronto_common')->getApiToken()) {
17
+ return null;
18
+ }
19
+
20
+ return parent::render($element);
21
+ }
22
+ }
app/code/community/Bronto/Common/Block/Adminhtml/System/Config/Form/Field/List.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.7.0
7
+ */
8
+ class Bronto_Common_Block_Adminhtml_System_Config_Form_Field_List extends Bronto_Common_Block_Adminhtml_System_Config_Form_Field_Hidden
9
+ {
10
+ /**
11
+ * Override method to output our custom HTML with JavaScript
12
+ *
13
+ * @param Varien_Data_Form_Element_Abstract $element
14
+ * @return String
15
+ */
16
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
17
+ {
18
+ if (!Mage::app()->isSingleStoreMode()) {
19
+ $request = Mage::app()->getRequest();
20
+ if (!$request->getParam('store') && !$request->getParam('website') && !$request->getParam('group')) {
21
+ $element->setCanUseDefaultValue(false)
22
+ ->setDisabled('disabled')
23
+ ->setValue(null)
24
+ ;
25
+ }
26
+ }
27
+
28
+ return parent::_getElementHtml($element);
29
+ }
30
+
31
+ /**
32
+ * @param Varien_Data_Form_Element_Abstract $element
33
+ * @return string
34
+ */
35
+ public function render(Varien_Data_Form_Element_Abstract $element)
36
+ {
37
+ if (!Mage::app()->isSingleStoreMode()) {
38
+ $request = Mage::app()->getRequest();
39
+ if (!$request->getParam('store') && !$request->getParam('website') && !$request->getParam('group')) {
40
+ return null;
41
+ }
42
+ }
43
+
44
+ return parent::render($element);
45
+ }
46
+ }
app/code/community/Bronto/Common/Helper/Contact.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Helper_Contact extends Bronto_Common_Helper_Data
9
+ {
10
+ /**
11
+ * @param string $email
12
+ * @param string $customSource
13
+ * @param int $store
14
+ * @return Bronto_Api_Contact_Row
15
+ */
16
+ public function getContactByEmail($email, $customSource = null, $store = null)
17
+ {
18
+ if (empty($email)) {
19
+ return false;
20
+ }
21
+
22
+ /* @var $contactObject Bronto_Api_Contact */
23
+ $api = $this->getApi(null, $store);
24
+ $contactObject = $api->getContactObject();
25
+
26
+ // Load Contact
27
+ $contact = $contactObject->createRow();
28
+ $contact->email = $email;
29
+ try {
30
+ $contact = $contact->read();
31
+ } catch (Exception $e) {
32
+ // Contact doesn't exist
33
+ $this->writeDebug('No Contact exists with email: ' . $email);
34
+ // Set customSource if available
35
+ if (!empty($customSource)) {
36
+ $contact->customSource = $customSource;
37
+ }
38
+ }
39
+
40
+ return $contact;
41
+ }
42
+
43
+ /**
44
+ * @param Bronto_Api_Contact_Row $contact
45
+ * @param bool $persistOnly
46
+ * @return Bronto_Api_Contact_Row
47
+ */
48
+ public function saveContact(Bronto_Api_Contact_Row $contact, $persistOnly = false)
49
+ {
50
+
51
+ if ($this->isTestModeEnabled()) {
52
+ if (!$contact->id) {
53
+ // Check for @bronto.com
54
+ $parts = explode('@', $contact->email);
55
+ if (isset($parts[1]) && $parts[1] == 'bronto.com') {
56
+ $this->writeInfo('TEST MODE: Contact is @bronto.com, allowing...');
57
+ } else {
58
+ // User doesn't exist and isn't @bronto
59
+ $this->writeInfo('TEST MODE: Not updating Contact with email: ' . $contact->email);
60
+ return $contact;
61
+ }
62
+ }
63
+ }
64
+
65
+ if ($persistOnly) {
66
+ $contact->persist();
67
+ } else {
68
+ try {
69
+ if ($contact->id) {
70
+ $this->writeDebug("Updating existing Contact: ({$contact->email})...");
71
+ } else {
72
+ $this->writeDebug("Saving new Contact: ({$contact->email})...");
73
+ }
74
+ $contact->save(false);
75
+ } catch (Exception $e) {
76
+ $this->writeError($e);
77
+ }
78
+ }
79
+
80
+ $this->writeVerboseDebug('===== CONTACT SAVE =====', 'bronto_common_api.log');
81
+ $this->writeVerboseDebug(var_export($contact->getApi()->getLastRequest(), true), 'bronto_common_api.log');
82
+ $this->writeVerboseDebug(var_export($contact->getApi()->getLastResponse(), true), 'bronto_common_api.log');
83
+
84
+ return $contact;
85
+ }
86
+ }
app/code/community/Bronto/Common/Helper/Data.php ADDED
@@ -0,0 +1,438 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Helper_Data extends Mage_Core_Helper_Abstract
9
+ {
10
+ const XML_PATH_GLOBAL_SETTINGS = 'bronto/settings/';
11
+ const XML_PATH_API_TOKEN = 'bronto/settings/api_token';
12
+ const XML_PATH_DEBUG = 'bronto/settings/debug';
13
+ const XML_PATH_VERBOSE = 'bronto/settings/verbose';
14
+ const XML_PATH_TEST = 'bronto/settings/test';
15
+ const XML_PATH_NOTICES = 'bronto/settings/notices';
16
+ const XML_PATH_ENABLED = 'bronto/settings/enabled';
17
+
18
+ /**
19
+ * @param string $path
20
+ * @param mixed $store
21
+ * @param int $websiteId
22
+ * @return mixed
23
+ */
24
+ public function getAdminScopedConfig($path, $store = null, $websiteId = null)
25
+ {
26
+ if (!is_null($store)) {
27
+ return Mage::getStoreConfig($path, $store);
28
+ } elseif (!is_null($websiteId)) {
29
+ $website = Mage::app()->getWebsite($websiteId);
30
+ return $website->getConfig($path);
31
+ }
32
+
33
+ $action = Mage::app()->getFrontController()->getAction();
34
+ if ($action instanceOf Mage_Adminhtml_System_ConfigController) {
35
+ if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
36
+ $store = Mage::app()->getStore($storeCode);
37
+ return $store->getConfig($path);
38
+ } elseif ($websiteCode = Mage::app()->getRequest()->getParam('website')){
39
+ $website = Mage::app()->getWebsite($websiteCode);
40
+ return $website->getConfig($path);
41
+ } else if ($groupCode = Mage::app()->getRequest()->getParam('group')){
42
+ $website = Mage::app()->getGroup($groupCode)->getWebsite();
43
+ return $website->getConfig($path);
44
+ }
45
+ }
46
+
47
+ return Mage::getStoreConfig($path);
48
+ }
49
+
50
+ /**
51
+ * @return bool
52
+ */
53
+ public function isEnabled()
54
+ {
55
+ return (bool) Mage::getStoreConfig(self::XML_PATH_ENABLED);
56
+ }
57
+
58
+ /**
59
+ * Verify that all required PHP extensions are loaded
60
+ *
61
+ * @param string $module
62
+ * @param array $required
63
+ * @return boolean
64
+ */
65
+ public function varifyRequirements($module, $required = array())
66
+ {
67
+ // Check for required PHP extensions
68
+ $verified = true;
69
+ $missing = array();
70
+ $defaultRequired = array('soap', 'openssl');
71
+ $required = array_merge($required, $defaultRequired);
72
+
73
+ /*
74
+ * Run through PHP extensions to see if they are loaded
75
+ * if no, add them to the list of missing and set verified = false flag
76
+ */
77
+ foreach ($required as $extName) {
78
+ if (!extension_loaded($extName)) {
79
+ $missing[] = $extName;
80
+ $verified = false;
81
+ }
82
+ }
83
+
84
+ // If not verified, create a message telling the user what they are missing
85
+ if (!$verified) {
86
+ // If module is enabled, disable it
87
+ if ($this->isEnabled()) {
88
+ Mage::helper($module)->disableModule();
89
+ }
90
+ // Create message informing of missing extensions
91
+ $message = Mage::getSingleton('core/message')->error(
92
+ Mage::helper('bronto_common')->__(
93
+ sprintf(
94
+ 'The module "'.$module.'" has been automatically disabled due to missing PHP extensions: %s',
95
+ implode(',', $missing)
96
+ )
97
+ )
98
+ );
99
+ $message->setIdentifier($module);
100
+ Mage::getSingleton('adminhtml/session')->addMessage($message);
101
+ return false;
102
+ }
103
+
104
+ return true;
105
+ }
106
+
107
+ /**
108
+ * @param string $token
109
+ * @param int $store
110
+ * @param int $websiteId
111
+ * @return Bronto_Common_Model_Api
112
+ */
113
+ public function getApi($token = null, $store = null, $websiteId = null)
114
+ {
115
+ if (empty($token)) {
116
+ $token = $this->getApiToken($store, $websiteId);
117
+ }
118
+
119
+ return Bronto_Common_Model_Api::getInstance($token);
120
+ }
121
+
122
+ /**
123
+ * Determine if API token is valid
124
+ *
125
+ * @param string $token
126
+ * @param int $store
127
+ * @param int $websiteId
128
+ * @return boolean
129
+ */
130
+ public function validApiToken($token = null, $store = null, $websiteId = null)
131
+ {
132
+ if (empty($token)) {
133
+ $token = $this->getApiToken($store, $websiteId);
134
+ }
135
+
136
+ if (strlen($token) < 36) {
137
+ return false;
138
+ }
139
+ try {
140
+ $api = new Bronto_Api($token, array('debug' => true));
141
+ $api->login();
142
+ } catch (Exception $e) {
143
+ return false;
144
+ }
145
+ return true;
146
+ }
147
+
148
+ /**
149
+ * Check all API tokens are valid
150
+ * @return boolean
151
+ */
152
+ public function validApiTokens($identifier = 'bronto_common')
153
+ {
154
+ $valid = true;
155
+ if (!$this->validApiToken()) {
156
+ $message = Mage::getSingleton('core/message')->error(
157
+ Mage::helper('bronto_common')->__('The Bronto API Token you have entered for Default Configuration appears to be invalid.')
158
+ );
159
+ $message->setIdentifier($identifier);
160
+ Mage::getSingleton('adminhtml/session')->addMessage($message);
161
+ $valid = false;
162
+ }
163
+ foreach (Mage::app()->getWebsites() as $website) {
164
+ if (!$this->validApiToken(null, null, $website->getId())) {
165
+ $message = Mage::getSingleton('core/message')->error(
166
+ Mage::helper('bronto_common')->__(sprintf('The Bronto API Token you have entered for website "%s" appears to be invalid.', $website->getName()))
167
+ );
168
+ $message->setIdentifier($identifier);
169
+ Mage::getSingleton('adminhtml/session')->addMessage($message);
170
+ $valid = false;
171
+ }
172
+ foreach ($website->getGroups() as $group) {
173
+ $stores = $group->getStores();
174
+ if (count($stores) > 0) {
175
+ foreach ($stores as $store) {
176
+ if (!$this->validApiToken(null, $store->getId(), $website->getId())) {
177
+ $message = Mage::getSingleton('core/message')->error(
178
+ Mage::helper('bronto_common')->__(sprintf('The Bronto API Token you have entered for store "%s" on website "%s" appears to be invalid.', $store->getName(), $website->getName()))
179
+ );
180
+ $message->setIdentifier($identifier);
181
+ Mage::getSingleton('adminhtml/session')->addMessage($message);
182
+ $valid = false;
183
+ }
184
+ }
185
+ }
186
+ }
187
+ }
188
+
189
+ return $valid;
190
+ }
191
+
192
+ /**
193
+ * @param string $moduleName
194
+ * @return bool
195
+ */
196
+ public function isModuleInstalled($moduleName = null)
197
+ {
198
+ $modules = (array) Mage::getConfig()->getNode('modules')->children();
199
+
200
+ if ($moduleName === null) {
201
+ $moduleName = $this->_getModuleName();
202
+ }
203
+
204
+ return isset($modules[$moduleName]);
205
+ }
206
+
207
+ /**
208
+ * @param string $moduleName
209
+ * @return string
210
+ */
211
+ public function getModuleVersion($moduleName = null)
212
+ {
213
+ $modules = (array) Mage::getConfig()->getNode('modules')->children();
214
+
215
+ if ($moduleName === null) {
216
+ $moduleName = $this->_getModuleName();
217
+ }
218
+
219
+ return isset($modules[$moduleName]) ? (string) $modules[$moduleName]->version : null;
220
+ }
221
+
222
+ /**
223
+ * @param string $store
224
+ * @return string
225
+ */
226
+ public function getApiToken($store = null, $websiteId = null)
227
+ {
228
+ $token = $this->getAdminScopedConfig(self::XML_PATH_API_TOKEN, $store, $websiteId);
229
+
230
+ if (!$token || empty($token)) {
231
+ return false;
232
+ }
233
+
234
+ return $token;
235
+ }
236
+
237
+ /**
238
+ * @param string $store
239
+ * @return Bronto_Api_ApiToken_Row
240
+ */
241
+ public function getApiTokenRow($store = null)
242
+ {
243
+ if (!($token = $this->getApiToken($store))) {
244
+ return false;
245
+ }
246
+
247
+ if ($api = $this->getApi($token)) {
248
+ if (!$api->isAuthenticated()) {
249
+ return false;
250
+ }
251
+ } else {
252
+ return false;
253
+ }
254
+
255
+ $apiTokenObject = $api->getApiTokenObject();
256
+ $apiToken = $apiTokenObject->createRow();
257
+ $apiToken->id = $token;
258
+ try {
259
+ $apiToken->read();
260
+ } catch (Exception $e) {
261
+ $this->writeError($e);
262
+ return false;
263
+ }
264
+
265
+ return $apiToken;
266
+ }
267
+
268
+ /**
269
+ * @return bool
270
+ */
271
+ public function isDebugEnabled()
272
+ {
273
+ if (!$this->getApiToken()){
274
+ return false;
275
+ }
276
+
277
+ return (bool) Mage::getStoreConfig(self::XML_PATH_DEBUG);
278
+ }
279
+
280
+ /**
281
+ * @return bool
282
+ */
283
+ public function isVerboseEnabled()
284
+ {
285
+ if (!$this->isDebugEnabled()) {
286
+ return false;
287
+ }
288
+
289
+ return (bool) Mage::getStoreConfig(self::XML_PATH_VERBOSE);
290
+ }
291
+
292
+ /**
293
+ * @return bool
294
+ */
295
+ public function isTestModeEnabled()
296
+ {
297
+ if (!$this->getApiToken()){
298
+ return false;
299
+ }
300
+
301
+ return (bool) Mage::getStoreConfig(self::XML_PATH_TEST);
302
+ }
303
+
304
+ /**
305
+ * @return bool
306
+ */
307
+ public function isNoticesEnabled()
308
+ {
309
+ if (!$this->getApiToken()){
310
+ return false;
311
+ }
312
+
313
+ return (bool) Mage::getStoreConfig(self::XML_PATH_NOTICES);
314
+ }
315
+
316
+ /**
317
+ * @param string $path
318
+ * @param string $scope
319
+ * @param int $scopeId
320
+ * @return bool
321
+ */
322
+ protected function _disableModule($path, $scope = 'default', $scopeId = 0)
323
+ {
324
+ $config = Mage::getModel('core/config');
325
+ $config->saveConfig($path, 0, $scope, $scopeId);
326
+
327
+ $version = Mage::getVersionInfo();
328
+ if (1 == $version['major'] && 9 != $version['minor']) {
329
+ // Get the Module alias from the path
330
+ // $path = bronto_email/settings/api_token
331
+ // $module = bronto_email
332
+ list($module) = explode('/', $path);
333
+ // we have to physically insert the enabled path into the
334
+ // core_config_data table of the DB w/ a value of 0, or the module
335
+ // could inherit from its parent and not actually get disabled.
336
+ // b/c the state of the checkbox is determined by whether or not
337
+ // a value is set in the core_config_data table.
338
+ $configData = Mage::getModel('core/config_data');
339
+ $configData->setScope($scope)
340
+ ->setScopeId($scopeId)
341
+ ->setPath("$module/settings/enabled")
342
+ ->setValue(0)
343
+ ->save();
344
+ }
345
+
346
+ return $this;
347
+ }
348
+
349
+ /**
350
+ * @param string $message
351
+ * @param string|null $file
352
+ * @return bool|void
353
+ */
354
+ public function writeDebug($message, $file = null, $verbose = false)
355
+ {
356
+ if ($verbose && !$this->isVerboseEnabled()) {
357
+ return;
358
+ }
359
+
360
+ if ($this->isDebugEnabled()) {
361
+ return $this->writeLog($message, $file, Zend_Log::DEBUG);
362
+ }
363
+ }
364
+
365
+ /**
366
+ * @param string $message
367
+ * @param string|null $file
368
+ * @return bool|void
369
+ */
370
+ public function writeVerboseDebug($message, $file = null)
371
+ {
372
+ if ($this->isVerboseEnabled()) {
373
+ return $this->writeDebug($message, $file, true);
374
+ }
375
+ }
376
+
377
+ /**
378
+ * @param string $message
379
+ * @param string|null $file
380
+ * @return bool|void
381
+ */
382
+ public function writeInfo($message, $file = null)
383
+ {
384
+ if ($this->isNoticesEnabled()) {
385
+ if (Mage::getSingleton('admin/session')->isLoggedIn()) {
386
+ /* @var $message Mage_Core_Model_Message_Notice */
387
+ $message = Mage::getSingleton('core/message')->notice("[Bronto] {$message}");
388
+ Mage::getSingleton('adminhtml/session')->addMessage($message);
389
+ } else {
390
+ Mage::getSingleton('core/session')->addNotice("[Bronto] {$message}");
391
+ }
392
+ }
393
+ return $this->writeLog($message, $file, Zend_Log::INFO);
394
+ }
395
+
396
+ /**
397
+ * @param Exception|string $message
398
+ * @param string|null $file
399
+ * @return bool|void
400
+ */
401
+ public function writeError($message, $file = null)
402
+ {
403
+ if (is_object($message) && $message instanceOf Exception) {
404
+ $message = $message->getMessage();
405
+ }
406
+ if ($this->isNoticesEnabled()) {
407
+ if (Mage::getSingleton('admin/session')->isLoggedIn()) {
408
+ /* @var $message Mage_Core_Model_Message_Error */
409
+ $message = Mage::getSingleton('core/message')->error("[Bronto] {$message}");
410
+ Mage::getSingleton('adminhtml/session')->addMessage($message);
411
+ } else {
412
+ Mage::getSingleton('core/session')->addError("[Bronto] {$message}");
413
+ }
414
+ }
415
+ return $this->writeLog($message, $file, Zend_Log::ERR);
416
+ }
417
+
418
+ /**
419
+ * @param string $message
420
+ * @param string|null $file
421
+ * @param int $level
422
+ * @return bool|void
423
+ */
424
+ public function writeLog($message, $file = null, $level = Zend_Log::DEBUG)
425
+ {
426
+ if (empty($file)) {
427
+ $file = strtolower($this->_getModuleName()) . '.log';
428
+ }
429
+ if (!is_string($message)) {
430
+ if (method_exists($message, '__toString')) {
431
+ $message = $message->__toString();
432
+ } else {
433
+ return false;
434
+ }
435
+ }
436
+ return Mage::log($message, $level, $file, true);
437
+ }
438
+ }
app/code/community/Bronto/Common/Helper/DataInterface.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ interface Bronto_Common_Helper_DataInterface
9
+ {
10
+ /**
11
+ * Disable the module in the admin configuration
12
+ *
13
+ * @param string $scope
14
+ * @param int $scopeId
15
+ * @return bool
16
+ */
17
+ public function disableModule($scope = 'default', $scopeId = 0);
18
+ }
app/code/community/Bronto/Common/Helper/Field.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Helper_Field extends Bronto_Common_Helper_Data
9
+ {
10
+ /**
11
+ * @param string $name
12
+ * @param array $options
13
+ * @return Bronto_Api_Field_Row
14
+ */
15
+ public function getFieldByName($name, $options)
16
+ {
17
+ /* @var $fieldObject Bronto_Api_Field */
18
+ $fieldObject = $this->getApi()->getFieldObject();
19
+
20
+ if (!($field = $fieldObject->getFromCache($name))) {
21
+ $field = $fieldObject->createRow();
22
+ $field->name = $name;
23
+ $field->label = $options['label'];
24
+ $field->type = $options['type'];
25
+ if (!empty($options['options'])) {
26
+ $field->options = $options['options'];
27
+ }
28
+ try {
29
+ $field->save();
30
+ $fieldObject->addToCache($name, $field);
31
+ } catch (Exception $e) {
32
+ $this->writeError($e);
33
+ }
34
+ }
35
+
36
+ return $field;
37
+ }
38
+ }
app/code/community/Bronto/Common/Helper/Message.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Helper_Message extends Bronto_Common_Helper_Data
9
+ {
10
+ /**
11
+ * @param string $messageId
12
+ * @return Bronto_Api_Message_Row
13
+ */
14
+ public function getMessageById($messageId, $storeId = null, $websiteId = null)
15
+ {
16
+ /* @var $messageObject Bronto_Api_Message */
17
+ $messageObject = $this->getApi(null, $storeId, $websiteId)->getMessageObject();
18
+
19
+ // Load Message
20
+ try {
21
+ /* @var $message Bronto_Api_Message_Row */
22
+ $message = $messageObject->createRow();
23
+ $message->id = $messageId;
24
+ $message->read();
25
+ } catch (Exception $e) {
26
+ $this->writeError($e);
27
+ }
28
+
29
+ return $message;
30
+ }
31
+
32
+ /**
33
+ * @return array
34
+ */
35
+ public function getAllMessageOptions()
36
+ {
37
+ $messageOptions = array();
38
+ foreach (Mage::app()->getWebsites() as $website) {
39
+ foreach ($website->getGroups() as $group) {
40
+ $stores = $group->getStores();
41
+ if (count($stores) == 0) {
42
+ continue;
43
+ }
44
+ foreach ($stores as $store) {
45
+ $storeMessages = Mage::helper('bronto_common/message')
46
+ ->getMessagesOptionsArray(
47
+ $store->getId(),
48
+ $website->getId()
49
+ );
50
+ $messageOptions = array_merge($messageOptions, $storeMessages);
51
+ }
52
+ }
53
+ }
54
+ $existingValues = array();
55
+ foreach ($messageOptions as $key => $option) {
56
+ if (!in_array($option['value'], $existingValues)) {
57
+ $existingValues[] = $option['value'];
58
+ } else {
59
+ unset($messageOptions[$key]);
60
+ }
61
+ }
62
+
63
+ return $messageOptions;
64
+ }
65
+
66
+ /**
67
+ * Retrieve array of available Bronto Messages
68
+ *
69
+ * @return array
70
+ */
71
+ public function getMessagesOptionsArray($store = null, $websiteId = null)
72
+ {
73
+ /* @var $api Bronto_Api */
74
+ $api = $this->getApi(null, $store, $websiteId);
75
+
76
+ if ($api) {
77
+ /* @var $messageObject Bronto_Api_Message */
78
+ $messageObject = $api->getMessageObject();
79
+
80
+ $options = array();
81
+ $pageNumber = 1;
82
+
83
+ try {
84
+ while ($messages = $messageObject->readAll(array(), false, $pageNumber)) {
85
+ if ($messages->count() <= 0) {
86
+ break;
87
+ }
88
+ foreach ($messages as $message /* @var $message Bronto_Api_Message_Row */) {
89
+ if ($message->status == 'active') {
90
+ $options[] = array(
91
+ 'label' => $message->name,
92
+ 'value' => $message->id,
93
+ );
94
+ }
95
+ }
96
+ $pageNumber++;
97
+ }
98
+ } catch (Exception $e) {
99
+ Mage::helper('bronto_common')->writeError($e);
100
+ }
101
+ }
102
+ array_unshift($options, array(
103
+ 'label' => '-- Not Selected --',
104
+ 'value' => '',
105
+ ));
106
+
107
+ return $options;
108
+ }
109
+ }
app/code/community/Bronto/Common/Helper/Product.php ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Helper_Product extends Mage_Core_Helper_Abstract
9
+ {
10
+ /**
11
+ * @var array
12
+ */
13
+ protected $_productCache = array();
14
+
15
+ /**
16
+ * @var array
17
+ */
18
+ protected $_templateVars = array();
19
+
20
+ /**
21
+ * Transforms input string by replacing parameters in the
22
+ * template string with corresponding values
23
+ *
24
+ * @link https://github.com/leek/zf-components/blob/master/library/Leek/Config.php
25
+ * @param string $subject Template string
26
+ * @param array $map Key / value pairs to substitute with
27
+ * @param string $delimiter Template parameter delimiter (must be valid without escaping in a regular expression)
28
+ * @param bool $blankIfNone Set to blank if none found
29
+ * @return string
30
+ * @static
31
+ */
32
+ public function templatize($subject, $map, $delimiter = '%', $blankIfNone = false)
33
+ {
34
+ if ($matches = $this->getTemplateVariables($subject, $delimiter)) {
35
+ $map = array_change_key_case($map, CASE_LOWER);
36
+ foreach ($matches as $match) {
37
+ if (isset($map[$match])) {
38
+ $subject = str_replace($delimiter . $match . $delimiter, $map[$match], $subject);
39
+ } elseif ($blankIfNone) {
40
+ $subject = str_replace($delimiter . $match . $delimiter, '', $subject);
41
+ }
42
+ }
43
+ }
44
+
45
+ return $subject;
46
+ }
47
+
48
+ /**
49
+ * @param string $subject
50
+ * @param string $delimiter
51
+ * @param mixed $index
52
+ * @return array
53
+ */
54
+ public function getTemplateVariables($subject, $delimiter = '%')
55
+ {
56
+ if (!isset($this->_templateVars[$subject])) {
57
+ $this->_templateVars[$subject] = array();
58
+ if (preg_match_all('/' . $delimiter . '([a-z0-9_]+)' . $delimiter . '/', $subject, $matches)) {
59
+ if ($matches[1]) {
60
+ $this->_templateVars[$subject] = $matches[1];
61
+ }
62
+ }
63
+ }
64
+
65
+ return $this->_templateVars[$subject];
66
+ }
67
+
68
+ /**
69
+ * @param int $productId
70
+ * @return boolean|Mage_Catalog_Model_Product
71
+ */
72
+ public function getProduct($productId)
73
+ {
74
+ if (is_int($productId) || is_string($productId)) {
75
+ if (isset($this->_productCache[$productId])) {
76
+ return $this->_productCache[$productId];
77
+ } else {
78
+ $product = Mage::getModel('catalog/product')->load($productId);
79
+ }
80
+ } else {
81
+ $product = $productId;
82
+ }
83
+
84
+ if (!is_object($product) || !($product instanceOf Mage_Catalog_Model_Product)) {
85
+ return false;
86
+ } else {
87
+ $productId = $product->getId();
88
+ }
89
+
90
+ $this->_productCache[$productId] = $product;
91
+ return $product;
92
+ }
93
+
94
+ /**
95
+ * @param Mage_Catalog_Model_Product $product
96
+ * @param string $name
97
+ * @return mixed
98
+ */
99
+ public function getProductAttribute($productId, $name)
100
+ {
101
+ if ($product = $this->getProduct($productId)) {
102
+ try {
103
+ switch ($name) {
104
+ case 'img':
105
+ case 'image':
106
+ return $product->getSmallImageUrl();
107
+ case 'url':
108
+ return Mage::helper('catalog/product')->getProductUrl($product);
109
+ }
110
+
111
+ $inputType = $product->getResource()
112
+ ->getAttribute($name)
113
+ ->getFrontend()
114
+ ->getInputType();
115
+
116
+ switch ($inputType) {
117
+ case 'multiselect':
118
+ case 'select':
119
+ case 'dropdown':
120
+ $value = $product->getAttributeText($name);
121
+ if (is_array($value)) {
122
+ $value = implode(', ', $value);
123
+ }
124
+ break;
125
+ default:
126
+ $value = $product->getData($name);
127
+ break;
128
+ }
129
+
130
+ return $value;
131
+ } catch (Exception $e) {
132
+ //
133
+ }
134
+ }
135
+
136
+ return false;
137
+ }
138
+ }
app/code/community/Bronto/Common/Model/Api.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Bronto
5
+ * @package Common
6
+ */
7
+ class Bronto_Common_Model_Api extends Bronto_Api
8
+ {
9
+ // {{{ properties
10
+
11
+ /**
12
+ * @var array
13
+ */
14
+ static private $_instances = array();
15
+
16
+ // }}}
17
+ // {{{ getInstance()
18
+
19
+ /**
20
+ * @param string $token
21
+ * @param bool $debug
22
+ *
23
+ * @return Bronto_Common_Model_Api
24
+ * @access public
25
+ */
26
+ public static function getInstance($token, $debug = true)
27
+ {
28
+ $token = trim($token);
29
+
30
+ if (!isset(self::$_instances[$token])) {
31
+ Mage::helper('bronto_common')->writeDebug("Initiating API for token: {$token}");
32
+ self::$_instances[$token] = new self($token, array(
33
+ 'retry_limit' => 2,
34
+ 'debug' => $debug,
35
+ ));
36
+ }
37
+
38
+ return self::$_instances[$token];
39
+ }
40
+
41
+ // }}}
42
+ // {{{ throwException()
43
+
44
+ /**
45
+ * @param string|Exception $exception
46
+ * @param string $message
47
+ * @param string $code
48
+ *
49
+ * @return void
50
+ * @access public
51
+ * @throws Bronto_Api_Exception
52
+ */
53
+ public function throwException($exception, $message = null, $code = null)
54
+ {
55
+ try {
56
+ parent::throwException($exception, $message, $code);
57
+ } catch (Bronto_Api_Exception $e) {
58
+ if ($request = $e->getRequest()) {
59
+ Mage::helper('bronto_common')->writeDebug(var_export($request, true));
60
+ }
61
+ if ($response = $e->getResponse()) {
62
+ Mage::helper('bronto_common')->writeDebug(var_export($response, true));
63
+ }
64
+ throw $e;
65
+ }
66
+ }
67
+
68
+ // }}}
69
+ }
app/code/community/Bronto/Common/Model/Email/Message.php ADDED
@@ -0,0 +1,323 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Model_Email_Message extends Mage_Core_Model_Email_Template
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_helper = 'bronto_common';
14
+
15
+ /**
16
+ * @var Bronto_Api_Message_Row
17
+ */
18
+ protected $_message;
19
+
20
+ /**
21
+ * @var Bronto_Common_Model_Email_Message_Filter
22
+ */
23
+ protected $_messageFilter;
24
+
25
+ /**
26
+ * @var string
27
+ */
28
+ protected $_lastDeliveryId;
29
+
30
+ /**
31
+ * @var Bronto_Email_Model_Log
32
+ */
33
+ protected $_log;
34
+
35
+ /**
36
+ * Get the message currently set
37
+ *
38
+ * @return boolean|Bronto_Api_Message_Row False if no message is set
39
+ */
40
+ public function getMessage()
41
+ {
42
+ if (empty($this->_message)) {
43
+ $messageId = $this->getBrontoMessageId();
44
+ if (!empty($messageId)) {
45
+ $this->_message = Mage::helper($this->_helper . '/message')->getMessageById($messageId);
46
+ } else {
47
+ return false;
48
+ }
49
+ }
50
+ return $this->_message;
51
+ }
52
+
53
+ /**
54
+ * Set the message
55
+ *
56
+ * @param Bronto_Api_Message_Row $message
57
+ */
58
+ public function setMessage(Bronto_Api_Message_Row $message)
59
+ {
60
+ $this->_message = $message;
61
+ }
62
+
63
+ /**
64
+ * Get filter object for template processing logic
65
+ *
66
+ * @return Bronto_Common_Model_Email_Message_Filter
67
+ */
68
+ public function getMessageFilter()
69
+ {
70
+ if (empty($this->_messageFilter)) {
71
+ $this->_messageFilter = Mage::getModel('bronto_common/email_message_filter');
72
+ }
73
+ return $this->_messageFilter;
74
+ }
75
+
76
+ /**
77
+ * Process email template code
78
+ *
79
+ * @param Bronto_Api_Delivery_Row $delivery
80
+ * @param array $variables
81
+ *
82
+ * @return Bronto_Api_Delivery_Row
83
+ */
84
+ public function getProcessedDelivery(Bronto_Api_Delivery_Row $delivery, array $variables = array())
85
+ {
86
+ $processor = $this->getMessageFilter();
87
+
88
+ if (isset($variables['subscriber']) && ($variables['subscriber'] instanceof Mage_Newsletter_Model_Subscriber)) {
89
+ $processor->setStoreId($variables['subscriber']->getStoreId());
90
+ }
91
+
92
+ if ($message = $this->getMessage()) {
93
+ $processor->setMessageId($message->id);
94
+ }
95
+
96
+ $processor->setVariables($variables);
97
+ $processor->setAvailable($this->getVariablesOptionArray());
98
+
99
+ return $processor->filter($delivery);
100
+ }
101
+
102
+ /**
103
+ * If this message can be used for sending queue as main template
104
+ *
105
+ * @return boolean
106
+ */
107
+ public function isMessageValidForSend()
108
+ {
109
+ /* @var $message Bronto_Api_Message_Row */
110
+ $message = $this->getMessage();
111
+
112
+ if (!($message instanceOf Bronto_Api_Message_Row)) {
113
+ Mage::helper($this->_helper)->writeError(' Invalid Message');
114
+ return false;
115
+ }
116
+
117
+ if ($message->status != 'active') {
118
+ Mage::helper($this->_helper)->writeError(' Message is not active: ' . $message->name);
119
+ return false;
120
+ }
121
+
122
+ if (!($this->getSenderName() && $this->getSenderEmail())) {
123
+ Mage::helper($this->_helper)->writeError(' Message cannot be sent');
124
+ return false;
125
+ }
126
+
127
+ return true;
128
+ }
129
+
130
+ /**
131
+ * Send mail to recipient
132
+ *
133
+ * @param array|string $email E-mail(s)
134
+ * @param array|string|null $name receiver name(s)
135
+ * @param array $variables template variables
136
+ *
137
+ * @return boolean
138
+ */
139
+ public function send($email, $name = null, array $variables = array())
140
+ {
141
+ if (!Mage::helper($this->_helper)->isEnabled()) {
142
+ return parent::send($email, $name, $variables);
143
+ }
144
+
145
+ /* @var $message Bronto_Api_Message_Row */
146
+ $message = $this->getMessage();
147
+ $messageId = $this->getBrontoMessageId();
148
+
149
+ if (empty($messageId)) {
150
+ return parent::send($email, $name, $variables);
151
+ }
152
+
153
+ if (!$this->isMessageValidForSend()) {
154
+ return false;
155
+ }
156
+
157
+ $emails = array_values((array) $email);
158
+ $names = is_array($name) ? $name : (array)$name;
159
+ $names = array_values($names);
160
+ foreach ($emails as $key => $email) {
161
+ if (!isset($names[$key])) {
162
+ $names[$key] = substr($email, 0, strpos($email, '@'));
163
+ }
164
+ }
165
+
166
+ $variables['email'] = reset($emails);
167
+ $variables['name'] = reset($names);
168
+ // Load Bronto Contact(s)
169
+ $contacts = array();
170
+ foreach ($emails as $key => $email) {
171
+ Mage::helper($this->_helper . '/contact')->writeDebug(' Getting Contact Object for: ' . $email . ' - Store: ' . $variables['store']->getId());
172
+ $contacts[$key] = Mage::helper($this->_helper . '/contact')->getContactByEmail($email, $this->_helper, $variables['store']->getId(), 2);
173
+ }
174
+
175
+ $deliveryCount = 0;
176
+ $deliveryErrors = 0;
177
+ /* @var $contact Bronto_Api_Contact_Row */
178
+ foreach ($contacts as $key => $contact) {
179
+ try {
180
+ if (!$contact->id || empty($contact->id)) {
181
+ $contact = Mage::helper($this->_helper . '/contact')->saveContact($contact);
182
+ if (!$contact->id || empty($contact->id)) {
183
+ $this->_beforeSend($contact, $message);
184
+ $deliveryErrors++;
185
+ Mage::helper($this->_helper)->writeDebug(' TEST MODE: Skipping e-mail: ' . $contact->email);
186
+ $this->_afterSend(0, "TEST MODE ENABLED: Contact does not exist: " . $contact->email);
187
+ continue;
188
+ }
189
+ }
190
+ $this->_beforeSend($contact, $message);
191
+
192
+ /* @var $deliveryObject Bronto_Api_Delivery */
193
+ Mage::helper($this->_helper)->writeDebug(' Getting Delivery Object...');
194
+ $deliveryObject = Mage::helper($this->_helper)
195
+ ->getApi(null, $variables['store']->getId())
196
+ ->getDeliveryObject();
197
+ $deliveryCount++;
198
+
199
+ /* @var $delivery Bronto_Api_Delivery_Row */
200
+ $delivery = $deliveryObject->createRow();
201
+ $delivery->start = date('c');
202
+ $delivery->messageId = $message->id;
203
+ $delivery->type = 'transactional';
204
+ if (Mage::helper($this->_helper)->isTestModeEnabled()) {
205
+ $delivery->type = 'test';
206
+ }
207
+ $delivery->fromEmail = $this->getSenderEmail();
208
+ $delivery->fromName = $this->getSenderName();
209
+ $delivery->replyEmail = $this->getSenderEmail();
210
+ $delivery->recipients = array(
211
+ array(
212
+ 'type' => 'contact',
213
+ 'id' => $contact->id,
214
+ ),
215
+ );
216
+
217
+ $delivery = $this->getProcessedDelivery($delivery, $variables);
218
+
219
+ Mage::helper($this->_helper)->writeDebug(' Saving Delivery...');
220
+
221
+ $delivery->save();
222
+ if ($delivery->id) {
223
+ $this->setLastDeliveryId($delivery->id);
224
+ $this->_afterSend(true, null, $delivery);
225
+ } else {
226
+ $deliveryErrors++;
227
+ $this->_afterSend(false, null, $delivery);
228
+ }
229
+ } catch (Exception $e) {
230
+ if ($e->getCode() === Bronto_Api_Delivery_Exception::MESSAGE_NOT_TRANSACTIONAL_APPROVED) {
231
+ $this->setBrontoMessageApproved(0);
232
+ $this->save();
233
+ }
234
+ $deliveryErrors++;
235
+ Mage::helper($this->_helper)->writeError($e);
236
+ $this->_afterSend(false, $e->getMessage(), isset($delivery) ? $delivery : null);
237
+ }
238
+ }
239
+
240
+ return $deliveryErrors == 0;
241
+ }
242
+
243
+ /**
244
+ * Send transactional email to recipient
245
+ *
246
+ * @param int $templateId
247
+ * @param string|array $sender Sender information, can be declared as part of config path
248
+ * @param string $email Recipient email
249
+ * @param string $name Recipient name
250
+ * @param array $vars Variables which can be used in template
251
+ * @param int|null $storeId
252
+ *
253
+ * @return Mage_Core_Model_Email_Template
254
+ */
255
+ public function sendTransactional($templateId, $sender, $email, $name, $vars = array(), $storeId = null)
256
+ {
257
+ if (!Mage::helper($this->_helper)->isEnabled() || !($templateId instanceOf Bronto_Api_Message_Row)) {
258
+ return parent::sendTransactional($templateId, $sender, $email, $name, $vars, $storeId);
259
+ } else {
260
+ $message = $templateId;
261
+ }
262
+
263
+ $this->setSentSuccess(false);
264
+ if (($storeId === null) && $this->getDesignConfig()->getStore()) {
265
+ $storeId = $this->getDesignConfig()->getStore();
266
+ }
267
+
268
+ $this->setMessage($message);
269
+ $this->setBrontoMessageId($message->id);
270
+ $this->setBrontoMessageName($message->name);
271
+ $this->setBrontoMessageApproved(1);
272
+
273
+ if (!is_array($sender)) {
274
+ $this->setSenderName(Mage::getStoreConfig('trans_email/ident_'.$sender.'/name', $storeId));
275
+ $this->setSenderEmail(Mage::getStoreConfig('trans_email/ident_'.$sender.'/email', $storeId));
276
+ } else {
277
+ $this->setSenderName($sender['name']);
278
+ $this->setSenderEmail($sender['email']);
279
+ }
280
+
281
+ if (!isset($vars['store'])) {
282
+ $vars['store'] = Mage::app()->getStore($storeId);
283
+ }
284
+ $this->setSentSuccess($this->send($email, $name, $vars));
285
+ return $this;
286
+ }
287
+
288
+ /**
289
+ * @param string $deliveryId
290
+ *
291
+ * @return Bronto_Common_Model_Email_Message
292
+ */
293
+ public function setLastDeliveryId($deliveryId)
294
+ {
295
+ $this->_lastDeliveryId = $deliveryId;
296
+ return $this;
297
+ }
298
+
299
+ /**
300
+ * @return string
301
+ */
302
+ public function getLastDeliveryId()
303
+ {
304
+ return $this->_lastDeliveryId;
305
+ }
306
+
307
+ /**
308
+ * @param Bronto_Api_Contact_Row $contact
309
+ * @param Bronto_Api_Message_Row $message
310
+ */
311
+ protected function _beforeSend(Bronto_Api_Contact_Row $contact, Bronto_Api_Message_Row $message)
312
+ {
313
+ }
314
+
315
+ /**
316
+ * @param int $success
317
+ * @param string $error
318
+ * @param Bronto_Api_Delivery_Row $delivery
319
+ */
320
+ protected function _afterSend($success, $error = null, Bronto_Api_Delivery_Row $delivery = null)
321
+ {
322
+ }
323
+ }
app/code/community/Bronto/Common/Model/Email/Message/Filter.php ADDED
@@ -0,0 +1,839 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Model_Email_Message_Filter
9
+ {
10
+ /**
11
+ * @var Bronto_Api_Delivery_Row
12
+ */
13
+ protected $_delivery;
14
+
15
+ /**
16
+ * @var int
17
+ */
18
+ protected $_storeId;
19
+
20
+ /**
21
+ * @var Mage_Core_Model_Store
22
+ */
23
+ protected $_store;
24
+
25
+ /**
26
+ * @var string
27
+ */
28
+ protected $_messageId;
29
+
30
+ /**
31
+ * Assigned template variables
32
+ *
33
+ * @var array
34
+ */
35
+ protected $_variables = array();
36
+
37
+ /**
38
+ * Available template variables
39
+ *
40
+ * @var array
41
+ */
42
+ protected $_available = array();
43
+
44
+ /**
45
+ * @var array
46
+ */
47
+ protected $_processedAvailable = array();
48
+
49
+ /**
50
+ * @var array
51
+ */
52
+ protected $_filteredObjects = array();
53
+
54
+ /**
55
+ * @var array
56
+ */
57
+ protected $_queryParams = array();
58
+
59
+ /**
60
+ * Map of keys that we would rather have a pretty name for.
61
+ * Rather than a 25 character truncated value.
62
+ *
63
+ * @var array
64
+ */
65
+ protected $_prettyMap = array(
66
+ 'subscriberConfirmationLink' => 'subConfirmationLink'
67
+ );
68
+
69
+ /**
70
+ * @return array
71
+ */
72
+ protected function _processAvailable()
73
+ {
74
+ $this->_processedAvailable = array();
75
+
76
+ foreach ($this->_available as $available) {
77
+
78
+ $variable = isset($available['value']) ? $available['value'] : null;
79
+ if (preg_match('/^{{skin|store|layout|block/', $variable)) {
80
+ continue;
81
+ }
82
+
83
+ $variable = str_replace('{{var ', '', $variable);
84
+ $variable = str_replace('{{htmlescape var=$', '', $variable);
85
+ $variable = str_replace('}}', '', $variable);
86
+
87
+ $parts = explode('.', $variable);
88
+ foreach ($parts as $i => $part) {
89
+ if (stripos($part, 'get') === 0) {
90
+ $parts[$i] = str_replace('get', '', $parts[$i]);
91
+ $parts[$i] = str_replace('()', '', $parts[$i]);
92
+ }
93
+ if (stripos($part, 'format') === 0) {
94
+ unset($parts[$i]);
95
+ }
96
+ }
97
+
98
+ $variable = implode('_', $parts);
99
+ $this->_processedAvailable[] = $this->_camelize($variable);
100
+
101
+ }
102
+
103
+ return $this->_processedAvailable;
104
+ }
105
+
106
+ /**
107
+ * @return Bronto_Common_Model_Email_Message_Filter
108
+ */
109
+ protected function _processQueryParams()
110
+ {
111
+ $this->_queryParams = array();
112
+
113
+ // Add rule_id (if available)
114
+ if (isset($this->_variables['rule'])){
115
+ if (class_exists('Bronto_Reminder_Model_Rule', false) && $this->_variables['rule'] instanceOf Bronto_Reminder_Model_Rule) {
116
+ $this->_queryParams['rule_id'] = $this->_variables['rule']->getId();
117
+ }
118
+ }
119
+
120
+ // Add message_id (if available)
121
+ if ($this->getMessageId()) {
122
+ $this->_queryParams['message_id'] = $this->getMessageId();
123
+ }
124
+
125
+ return $this;
126
+ }
127
+
128
+ /**
129
+ * @param Bronto_Api_Delivery_Row $delivery
130
+ * @return Bronto_Api_Delivery_Row
131
+ */
132
+ public function filter(Bronto_Api_Delivery_Row $delivery)
133
+ {
134
+ $this->_filteredObjects = array();
135
+ $this->_delivery = $delivery;
136
+
137
+ $this->_processAvailable();
138
+ $this->_processQueryParams();
139
+
140
+ foreach ($this->_variables as $var => $value) {
141
+
142
+ //
143
+ // Handle strings
144
+ if (is_string($value)) {
145
+ $key = $this->_camelize($var);
146
+ if (in_array($key, $this->_processedAvailable)) {
147
+ $this->setField($key, $value);
148
+ } else {
149
+ // Sanitize the best we can...
150
+ $key = preg_replace('/[^\w_]$/', '', $key);
151
+ $key = $this->_camelize($key);
152
+ $this->setField($key, $value);
153
+ }
154
+ }
155
+
156
+ if (is_object($value)) {
157
+
158
+ //
159
+ // Handle properties that can be get()'ed
160
+ foreach ($this->_processedAvailable as $keyValue) {
161
+ $method = str_replace($var, '', $keyValue);
162
+ $object = str_replace($method, '', $keyValue);
163
+ if ($object == $var) {
164
+ try {
165
+ $method = "get{$method}";
166
+ $this->setField($keyValue, $value->{$method}());
167
+ } catch (Exception $e) {
168
+ // Ignore
169
+ }
170
+ }
171
+ }
172
+
173
+ // Store
174
+ if ($value instanceOf Mage_Core_Model_Store) {
175
+ $this->_filterStore($value);
176
+ }
177
+
178
+ // Admin User
179
+ if ($value instanceOf Mage_Admin_Model_User) {
180
+ $this->_filterAdmin($value);
181
+ }
182
+
183
+ // Customer
184
+ if ($value instanceOf Mage_Customer_Model_Customer) {
185
+ $this->_filterCustomer($value);
186
+ }
187
+
188
+ // Shipment
189
+ if ($value instanceOf Mage_Sales_Model_Order_Shipment) {
190
+ $this->_filterShipment($value);
191
+ }
192
+
193
+ // Invoice
194
+ if ($value instanceOf Mage_Sales_Model_Order_Invoice) {
195
+ $this->_filterInvoice($value);
196
+ }
197
+
198
+ // Order
199
+ if ($value instanceOf Mage_Sales_Model_Order) {
200
+ $this->_filterOrder($value);
201
+ }
202
+
203
+ // Credit memo
204
+ if ($value instanceOf Mage_Sales_Model_Order_Creditmemo) {
205
+ $this->_filterCreditmemo($value);
206
+ }
207
+
208
+ // Quote
209
+ if ($value instanceOf Mage_Sales_Model_Quote) {
210
+ $this->_filterQuote($value);
211
+ }
212
+
213
+ // Product
214
+ if ($value instanceOf Mage_Catalog_Model_Product) {
215
+ $this->_filterProduct($value);
216
+ }
217
+
218
+ if ($value instanceof Mage_Sales_Model_Order_Address) {
219
+ $this->_filterAddress($value);
220
+ }
221
+
222
+ }
223
+
224
+ }
225
+
226
+ return $this->_delivery;
227
+ }
228
+
229
+ /**
230
+ * @param Mage_Core_Model_Store $store
231
+ * @return Bronto_Common_Model_Email_Message_Filter
232
+ */
233
+ protected function _filterStore(Mage_Core_Model_Store $store)
234
+ {
235
+ if (!in_array('store', $this->_filteredObjects)) {
236
+ $this->setStore($store);
237
+ $this->setField('storeName', $store->getName());
238
+ $this->setField('storeFrontendName', $store->getFrontendName());
239
+ $this->setField('storeURL', $store->getUrl('cms', $this->getQueryParams()));
240
+ $this->setField('cartURL', $store->getUrl('checkout/cart', $this->getQueryParams()));
241
+ $this->setField('customerURL', $store->getUrl('customer/account', $this->getQueryParams()));
242
+ $this->setField('supportEmail', $store->getConfig('trans_email/ident_support/email'));
243
+ $this->setField('supportPhone', $store->getConfig('general/store_information/phone'));
244
+ $this->setField('salesEmail', $store->getConfig('trans_email/ident_sales/email'));
245
+
246
+ // if the theme is not set at all (not a likely occurrence in a real site)
247
+ // then it returns the theme for the Find (RSS feed).
248
+ $theme = Mage::getSingleton('core/design_package')->getTheme('skin');
249
+ if ($theme == 'find') {
250
+ $theme = 'default';
251
+ }
252
+ $package = Mage::getSingleton('core/design_package')->getPackageName();
253
+ $this->setField('emailLogo', Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_SKIN) . 'frontend' . DS . $package . DS . $theme . DS . 'images/logo_email.gif');
254
+
255
+ $this->_filteredObjects[] = 'store';
256
+ }
257
+
258
+ return $this;
259
+ }
260
+
261
+ /**
262
+ * @param Mage_Admin_Model_User $user
263
+ * @return Bronto_Common_Model_Email_Message_Filter
264
+ */
265
+ protected function _filterAdmin(Mage_Admin_Model_User $user)
266
+ {
267
+ if (!in_array('admin', $this->_filteredObjects)) {
268
+ $this->setField('adminName', $user->getUsername());
269
+ $this->setField('adminPassword', $user->getPlainPassword());
270
+ $this->setField('adminLoginURL', Mage::helper('adminhtml')->getUrl('adminhtml/system_account/'));
271
+ if (version_compare(Mage::getVersion(), '1.6.1.0', '>=')) {
272
+ $this->setField('adminPasswordResetLink', Mage::helper('adminhtml')->getUrl('adminhtml/index/resetpassword', array('_query' => array('id' => $user->getId(), 'token' => $user->getRpToken()))));
273
+ }
274
+
275
+ $this->_filteredObjects[] = 'admin';
276
+ }
277
+
278
+ return $this;
279
+ }
280
+
281
+ /**
282
+ * @param Mage_Customer_Model_Customer $customer
283
+ * @return Bronto_Common_Model_Email_Message_Filter
284
+ */
285
+ protected function _filterCustomer(Mage_Customer_Model_Customer $customer)
286
+ {
287
+ if (!in_array('customer', $this->_filteredObjects)) {
288
+ $this->setField('customerName', $customer->getName());
289
+ $this->setField('customerEmail', $customer->getEmail());
290
+ $this->setField('customerPassword', $customer->getPassword());
291
+ if ($store = $this->getStore()) {
292
+ $this->setField('confirmationLink', $store->getUrl('customer/account/confirm', array('_query'=>array('id'=>$customer->getId(), 'key'=>$customer->getConfirmation()))));
293
+ if (version_compare(Mage::getVersion(), '1.6.1.0', '>=')) {
294
+ $this->setField('passwordResetLink', $store->getUrl('customer/account/resetpassword', array('_query' => array('id' => $customer->getId(), 'token' => $customer->getRpToken()))));
295
+ }
296
+ } else {
297
+ $this->setField('confirmationLink', Mage::getUrl('customer/account/confirm', array('_query'=>array('id'=>$customer->getId(), 'key'=>$customer->getConfirmation()))));
298
+ if (version_compare(Mage::getVersion(), '1.6.1.0', '>=')) {
299
+ $this->setField('passwordResetLink', Mage::getUrl('customer/account/resetpassword', array('_query' => array('id' => $customer->getId(), 'token' => $customer->getRpToken()))));
300
+ }
301
+ }
302
+
303
+ $this->_filteredObjects[] = 'customer';
304
+ }
305
+
306
+ return $this;
307
+ }
308
+
309
+ /**
310
+ * @param Mage_Sales_Model_Order $order
311
+ * @return Bronto_Common_Model_Email_Message_Filter
312
+ */
313
+ protected function _filterOrder(Mage_Sales_Model_Order $order, $type = 'order')
314
+ {
315
+ if (!in_array('order', $this->_filteredObjects)) {
316
+ // Order may not be a shippable order
317
+ $shipAddress = 'N/A';
318
+ $shipDescription = 'N/A';
319
+ if ($order->getIsNotVirtual()) {
320
+ $shipAddress = $order->getShippingAddress()->format('html');
321
+ $shipDescription = $order->getShippingDescription();
322
+ }
323
+
324
+ // Check for guest orders
325
+ $customerName = $order->getCustomerIsGuest() ? $order->getBillingAddress()->getName() : $order->getCustomerName();
326
+
327
+ $this->setField('orderIncrementId', $order->getIncrementId());
328
+ $this->setField('orderCreatedAt', $order->getCreatedAtFormated('long'));
329
+ $this->setField('orderBillingAddress', $order->getBillingAddress()->format('html'));
330
+ $this->setField('orderShippingAddress', $shipAddress);
331
+ $this->setField('orderShippingDescription', $shipDescription);
332
+ $this->setField('orderCustomerName', $customerName);
333
+ $this->setField('orderStatusLabel', $order->getStatusLabel());
334
+ $this->setField('orderItems', $this->_filterOrderItems($order));
335
+
336
+ $this->_filteredObjects[] = 'order';
337
+ }
338
+
339
+ return $this;
340
+ }
341
+
342
+ protected function _filterAddress(Mage_Sales_Model_Order_Address $address)
343
+ {
344
+ if (!in_array('address', $this->_filteredObjects)) {
345
+
346
+ $this->setField('billingName', $address->getName());
347
+ $this->_filteredObjects[] = 'address';
348
+ }
349
+ return $this;
350
+ }
351
+
352
+ /**
353
+ * @param Mage_Sales_Model_Order_Invoice $invoice
354
+ * @return Bronto_Common_Model_Email_Message_Filter
355
+ */
356
+ protected function _filterInvoice(Mage_Sales_Model_Order_Invoice $invoice)
357
+ {
358
+ if (!in_array('invoice', $this->_filteredObjects)) {
359
+ $this->setField('invoiceIncrementId', $invoice->getIncrementId());
360
+ $this->setField('invoiceItems', $this->_filterInvoiceItems($invoice));
361
+
362
+ $this->_filteredObjects[] = 'invoice';
363
+ }
364
+
365
+ return $this;
366
+ }
367
+
368
+ /**
369
+ * @param Mage_Sales_Model_Order_Shipment $shipment
370
+ * @return Bronto_Common_Model_Email_Message_Filter
371
+ */
372
+ protected function _filterShipment(Mage_Sales_Model_Order_Shipment $shipment)
373
+ {
374
+ if (!in_array('shipment', $this->_filteredObjects)) {
375
+ $this->setField('shipmentIncrementId', $shipment->getIncrementId());
376
+ $this->setField('shipmentCreatedAt', Mage::helper('core')->formatDate($shipment->getCreatedAtStoreDate(), 'long', true)); // TODO: needed?
377
+ $this->setField('shipmentItems', $this->_filterShipmentItems($shipment));
378
+ $this->setField('shipmentTracking', $this->_getShipmentTrackingNumber($shipment, $shipment->getOrder()));
379
+
380
+ $this->_filteredObjects[] = 'shipment';
381
+ }
382
+
383
+ return $this;
384
+ }
385
+
386
+ /**
387
+ * @param Mage_Sales_Model_Order_Creditmemo $creditmemo
388
+ * @return Bronto_Common_Model_Email_Message_Filter
389
+ */
390
+ protected function _filterCreditmemo(Mage_Sales_Model_Order_Creditmemo $creditmemo)
391
+ {
392
+ if (!in_array('creditmemo', $this->_filteredObjects)) {
393
+ $this->setField('creditmemoIncrementId', $creditmemo->getIncrementId());
394
+ $this->setField('creditmemoCreatedAt', Mage::helper('core')->formatDate($creditmemo->getCreatedAtStoreDate(), 'long', true)); // TODO: needed?
395
+ $this->setField('creditmemoItems', $this->_filterCreditmemoItems($creditmemo));
396
+
397
+ $this->_filteredObjects[] = 'creditmemo';
398
+ }
399
+ return $this;
400
+ }
401
+
402
+ /**
403
+ * @param Mage_Sales_Model_Quote $order
404
+ * @return Bronto_Common_Model_Email_Message_Filter
405
+ */
406
+ protected function _filterQuote(Mage_Sales_Model_Quote $quote)
407
+ {
408
+ if (!in_array('quote', $this->_filteredObjects)) {
409
+ $this->setField('subtotal', number_format($quote->getSubtotal(), 2));
410
+ $this->setField('grandTotal', number_format($quote->getGrandTotal(), 2));
411
+
412
+ $index = 1;
413
+ foreach ($quote->getAllItems() as $item /* @var $item Mage_Sales_Model_Quote_Item */) {
414
+ if (!$item->getParentItem()) {
415
+ $this->_filterQuoteItem($item, $index);
416
+ $index++;
417
+ }
418
+ }
419
+
420
+ $queryParams = $this->getQueryParams();
421
+ $queryParams['id'] = urlencode(base64_encode(Mage::helper('core')->encrypt($quote->getId())));
422
+ if ($store = $this->getStore()) {
423
+ $this->setField('quoteURL', $store->getUrl('reminder/load/index', $queryParams));
424
+ } else {
425
+ $this->setField('quoteURL', Mage::getUrl('reminder/load/index', $queryParams));
426
+ }
427
+
428
+ // Setup quote items as a template
429
+ if (class_exists('Bronto_Reminder_Block_Cart_Items', false)) {
430
+ $layout = Mage::getSingleton('core/layout');
431
+
432
+ /* @var $items Mage_Sales_Block_Items_Abstract */
433
+ $items = $layout->createBlock('bronto/bronto_reminder_cart_items', 'items');
434
+ $items->setTemplate('bronto/reminder/items.phtml');
435
+ $items->setQuote($item->getQuote());
436
+
437
+ // When emailing from the admin, we need to ensure that we're using templates from the frontend
438
+ Mage::getDesign()->setArea('frontend');
439
+ $this->setField("cartItems", $items->toHtml());
440
+ }
441
+
442
+ $this->_filteredObjects[] = 'quote';
443
+ }
444
+ return $this;
445
+ }
446
+
447
+ /**
448
+ * @param Mage_Sales_Model_Quote_Item $item
449
+ * @return Bronto_Common_Model_Email_Message_Filter
450
+ */
451
+ protected function _filterQuoteItem($item, $index = null)
452
+ {
453
+ if ($item->getParentItem()) {
454
+ return $this;
455
+ }
456
+
457
+ $this->setField("productName_{$index}", $item->getName());
458
+ $this->setField("productSku_{$index}", $item->getSku());
459
+ $this->setField("productPrice_{$index}", number_format($item->getPrice(), 2));
460
+ $this->setField("productTotal_{$index}", number_format($item->getRowTotal(), 2));
461
+ $this->setField("productQty_{$index}", $item->getQty());
462
+ $this->setField("productUrl_{$index}", $this->_getQuoteItemUrl($item));
463
+
464
+ /* @var $product Mage_Catalog_Model_Product */
465
+ $product = $item->getProduct();
466
+ if (!$product) {
467
+ $product = Mage::getModel('catalog/product')->load($item->getProductId());
468
+ }
469
+ $this->_filterProduct($product, $index);
470
+
471
+ return $this;
472
+ }
473
+
474
+ /**
475
+ * @param Mage_Sales_Model_Order $order
476
+ * @return String containing HTML for order items
477
+ */
478
+ protected function _filterOrderItems(Mage_Sales_Model_Order $order)
479
+ {
480
+ $layout = Mage::getSingleton('core/layout');
481
+
482
+ /* @var $items Mage_Sales_Block_Items_Abstract */
483
+ $items = $layout->createBlock('sales/order_email_items', 'items');
484
+ $items->setTemplate('email/order/items.phtml');
485
+ $items->setOrder($order);
486
+
487
+ // Setup templates to use for products
488
+ $items->addItemRender('default', 'sales/order_email_items_order_default', 'email/order/items/order/default.phtml');
489
+ $items->addItemRender('grouped', 'sales/order_email_items_order_grouped', 'email/order/items/order/default.phtml');
490
+ $items->addItemRender('bundle', 'bundle/sales_order_items_renderer', 'bundle/email/order/items/order/default.phtml');
491
+
492
+ // When emailing from the admin, we need to ensure that we're using templates from the frontend
493
+ Mage::getDesign()->setArea('frontend');
494
+
495
+ $totals = $this->_getTotalsBlock($layout, $order, 'sales/order_totals', 'order_totals');
496
+ $items->append($totals, 'order_totals');
497
+
498
+ return $items->toHtml();
499
+ }
500
+
501
+ /**
502
+ * @param Mage_Sales_Model_Order_Invoice $invoice
503
+ * @return String containing HTML for invoice items
504
+ */
505
+ protected function _filterInvoiceItems(Mage_Sales_Model_Order_Invoice $invoice)
506
+ {
507
+ $order = $invoice->getOrder();
508
+ $layout = Mage::getSingleton('core/layout');
509
+
510
+ /* @var $items Mage_Sales_Block_Items_Abstract */
511
+ $items = $layout->createBlock('sales/order_email_invoice_items', 'items');
512
+ $items->setTemplate('email/order/invoice/items.phtml');
513
+ $items->setOrder($order);
514
+ $items->setInvoice($invoice);
515
+
516
+ // Setup templates to use for products
517
+ $items->addItemRender('default', 'sales/order_email_items_order_default', 'email/order/items/invoice/default.phtml');
518
+ $items->addItemRender('grouped', 'sales/order_email_items_order_grouped', 'email/order/items/invoice/default.phtml');
519
+ $items->addItemRender('bundle', 'bundle/sales_order_items_renderer', 'bundle/email/order/items/invoice/default.phtml');
520
+
521
+ // When emailing from the admin, we need to ensure that we're using templates from the frontend
522
+ Mage::getDesign()->setArea('frontend');
523
+
524
+ $totals = $this->_getTotalsBlock($layout, $order, 'sales/order_invoice_totals', 'invoice_totals');
525
+ $items->append($totals, 'invoice_totals');
526
+
527
+ return $items->toHtml();
528
+ }
529
+
530
+ /**
531
+ * @param Mage_Sales_Model_Order_Shipment $shipment
532
+ * @return String containing HTML for shipment items and tracking numbers
533
+ */
534
+ protected function _filterShipmentItems(Mage_Sales_Model_Order_Shipment $shipment)
535
+ {
536
+ $order = $shipment->getOrder();
537
+ $layout = Mage::getSingleton('core/layout');
538
+
539
+ /* @var $items Mage_Sales_Block_Items_Abstract */
540
+ $items = $layout->createBlock('sales/order_email_shipment_items', 'items');
541
+ $items->setTemplate('email/order/shipment/items.phtml');
542
+ $items->setOrder($order);
543
+ $items->setShipment($shipment);
544
+
545
+ // Setup templates to use for products
546
+ $items->addItemRender('default', 'sales/order_email_items_order_default', 'email/order/items/shipment/default.phtml');
547
+ $items->addItemRender('grouped', 'sales/order_email_items_order_grouped', 'email/order/items/shipment/default.phtml');
548
+ $items->addItemRender('bundle', 'bundle/sales_order_items_renderer', 'bundle/email/order/items/shipment/default.phtml');
549
+
550
+ // When emailing from the admin, we need to ensure that we're using templates from the frontend
551
+ Mage::getDesign()->setArea('frontend');
552
+
553
+ return $items->toHtml();
554
+ }
555
+
556
+ /**
557
+ * Get the shipment tracking info.
558
+ *
559
+ * @param Mage_Sales_Model_Order_Shipment $shipment
560
+ * @param Mage_Sales_Model_Order $order
561
+ */
562
+ protected function _getShipmentTrackingNumber(Mage_Sales_Model_Order_Shipment $shipment, Mage_Sales_Model_Order $order)
563
+ {
564
+ $layout = Mage::getSingleton('core/layout');
565
+ $block = $layout->createBlock('core/template')->setTemplate('email/order/shipment/track.phtml');
566
+ $block->setOrder($order);
567
+ $block->setShipment($shipment);
568
+ $block->setArea('frontend');
569
+
570
+ return $block->toHtml();
571
+ }
572
+
573
+ /**
574
+ * @param Mage_Sales_Model_Order_Creditmemo $creditmemo
575
+ * @return String containing HTML for credit memo items
576
+ */
577
+ protected function _filterCreditmemoItems(Mage_Sales_Model_Order_Creditmemo $creditmemo)
578
+ {
579
+ $order = $creditmemo->getOrder();
580
+ $layout = Mage::getSingleton('core/layout');
581
+
582
+ /* @var $items Mage_Sales_Block_Items_Abstract */
583
+ $items = $layout->createBlock('sales/order_email_creditmemo_items', 'items');
584
+ $items->setTemplate('email/order/creditmemo/items.phtml');
585
+ $items->setOrder($order);
586
+ $items->setCreditmemo($creditmemo);
587
+
588
+ // Setup templates to use for products
589
+ $items->addItemRender('default', 'sales/order_email_items_order_default', 'email/order/items/creditmemo/default.phtml');
590
+ $items->addItemRender('grouped', 'sales/order_email_items_order_grouped', 'email/order/items/creditmemo/default.phtml');
591
+ $items->addItemRender('bundle', 'bundle/sales_order_items_renderer', 'bundle/email/order/items/creditmemo/default.phtml');
592
+
593
+ // When emailing from the admin, we need to ensure that we're using templates from the frontend
594
+ Mage::getDesign()->setArea('frontend');
595
+
596
+ $totals = $this->_getTotalsBlock($layout, $order, 'sales/order_creditmemo_totals', 'creditmemo_totals');
597
+ $items->append($totals, 'creditmemo_totals');
598
+
599
+ return $items->toHtml();
600
+ }
601
+
602
+ /**
603
+ * Get the totals block for order-style emails.
604
+ *
605
+ * @param Mage_Core_Model_Layout $layout
606
+ * @param Mage_Sales_Model_Order $order
607
+ * @param String $totals_block_type
608
+ * @param String $totals_block_name
609
+ * @return Mage_Core_Block_Template
610
+ */
611
+ protected function _getTotalsBlock($layout, $order, $totals_block_type, $totals_block_name)
612
+ {
613
+ $totals = $layout->createBlock($totals_block_type, $totals_block_name);
614
+ $totals->setOrder($order);
615
+ $totals->setTemplate('sales/order/totals.phtml');
616
+ $totals->setLabelProperties('colspan="3" align="right" style="padding:3px 9px"');
617
+ $totals->setValueProperties('align="right" style="padding:3px 9px"');
618
+
619
+ $tax = $layout->createBlock('tax/sales_order_tax', 'tax');
620
+ $tax->setOrder($order);
621
+ $tax->setTemplate('tax/order/tax.phtml');
622
+ $tax->setIsPlaneMode(1);
623
+ $totals->append($tax, 'tax');
624
+
625
+ return $totals;
626
+ }
627
+
628
+ /**
629
+ * @param Mage_Catalog_Model_Product $product
630
+ * @param int $index
631
+ * @return Bronto_Common_Model_Email_Message_Filter
632
+ */
633
+ protected function _filterProduct(Mage_Catalog_Model_Product $product, $index = null)
634
+ {
635
+ if ($index !== null) {
636
+ try {
637
+ $this->setField("productImgUrl_{$index}", $product->getSmallImageUrl());
638
+ } catch (Exception $e) {
639
+ Mage::log('Error loading image: ' . $e);
640
+ }
641
+ } else {
642
+ $this->setField('productUrl', $product->getUrl());
643
+ $this->setField('productName', $product->getName());
644
+ }
645
+
646
+ return $this;
647
+ }
648
+
649
+ /**
650
+ * @param Mage_Sales_Model_Quote_Item $item
651
+ * @return string
652
+ */
653
+ protected function _getQuoteItemUrl(Mage_Sales_Model_Quote_Item $item)
654
+ {
655
+ if ($item->getRedirectUrl()) {
656
+ return $item->getRedirectUrl();
657
+ }
658
+
659
+ $product = $item->getProduct();
660
+ $option = $item->getOptionByCode('product_type');
661
+ if ($option) {
662
+ $product = $option->getProduct();
663
+ }
664
+
665
+ return $product->getUrlModel()->getUrl($product);
666
+ }
667
+
668
+ /**
669
+ * @param string $key
670
+ * @param string|array $value
671
+ * @return Bronto_Common_Model_Email_Message_Filter
672
+ */
673
+ public function setField($key, $value, $type = 'html')
674
+ {
675
+ if (!is_string($key) || empty($key)) {
676
+ return $this;
677
+ }
678
+
679
+ if (is_array($value)) {
680
+ // Address objects come in as an array on payment failed emails
681
+ $delim = $type == 'html' ? '<br/>' : "\n\r";
682
+ if (isset($value['address_id'])) {
683
+ $new_value = $value['street'] . $delim;
684
+ $new_value .= $value['city'] . $delim;
685
+ $new_value .= $value['region'] . $delim;
686
+ $new_value .= $value['postcode'] . $delim;
687
+ $new_value .= $value['country_id'];
688
+ $this->_delivery->setField($key, $new_value, $type);
689
+ }
690
+ } else {
691
+ if (isset($this->_prettyMap[$key])) {
692
+ // Overwrite $key if we have a mapped overridden value
693
+ $key = $this->_prettyMap[$key];
694
+ }
695
+ $this->_delivery->setField($key, $value, $type);
696
+ }
697
+
698
+ return $this;
699
+ }
700
+
701
+ /**
702
+ * @return array
703
+ */
704
+ public function getQueryParams()
705
+ {
706
+ return $this->_queryParams;
707
+ }
708
+
709
+ /**
710
+ * Setter
711
+ *
712
+ * @param integer $storeId
713
+ * @return Bronto_Common_Model_Email_Message_Filter
714
+ */
715
+ public function setStoreId($storeId)
716
+ {
717
+ $this->_storeId = $storeId;
718
+ return $this;
719
+ }
720
+
721
+ /**
722
+ * Getter
723
+ * if $_storeId is null return Design store id
724
+ *
725
+ * @return integer
726
+ */
727
+ public function getStoreId()
728
+ {
729
+ if (null === $this->_storeId) {
730
+ $this->_storeId = Mage::app()->getStore()->getId();
731
+ }
732
+ return $this->_storeId;
733
+ }
734
+
735
+ /**
736
+ * @param Mage_Core_Model_Store $store
737
+ * @return Bronto_Common_Model_Email_Message_Filter
738
+ */
739
+ public function setStore(Mage_Core_Model_Store $store)
740
+ {
741
+ $this->_store = $store;
742
+ return $this;
743
+ }
744
+
745
+ /**
746
+ * @return Mage_Core_Model_Store
747
+ */
748
+ public function getStore()
749
+ {
750
+ return $this->_store;
751
+ }
752
+
753
+ /**
754
+ * @param string $messageId
755
+ * @return Bronto_Common_Model_Email_Message_Filter
756
+ */
757
+ public function setMessageId($messageId)
758
+ {
759
+ $this->_messageId = $messageId;
760
+ return $this;
761
+ }
762
+
763
+ /**
764
+ * @return string
765
+ */
766
+ public function getMessageId()
767
+ {
768
+ return $this->_messageId;
769
+ }
770
+
771
+ /**
772
+ * @param array $variables
773
+ * @return Bronto_Common_Model_Email_Message_Filter
774
+ */
775
+ public function setVariables($variables = array())
776
+ {
777
+ if (!is_array($variables)) {
778
+ $variables = array();
779
+ }
780
+ foreach ($variables as $name => $value) {
781
+ $this->_variables[$name] = $value;
782
+ }
783
+ return $this;
784
+ }
785
+
786
+ /**
787
+ * @param array $variables
788
+ * @return Bronto_Common_Model_Email_Message_Filter
789
+ */
790
+ public function setAvailable($variables = array())
791
+ {
792
+ if (!is_array($variables)) {
793
+ $variables = array();
794
+ }
795
+ foreach ($variables as $name => $value) {
796
+ $this->_available[$name] = $value;
797
+ }
798
+ return $this;
799
+ }
800
+
801
+ /**
802
+ * Converts field names for setters and geters
803
+ *
804
+ * @param string $name
805
+ * @return string
806
+ */
807
+ protected function _underscore($name)
808
+ {
809
+ $result = strtolower(preg_replace('/(.)([A-Z])/', "$1_$2", $name));
810
+ return $result;
811
+ }
812
+
813
+ /**
814
+ * @param string $name
815
+ * @return string
816
+ */
817
+ protected function _camelize($name)
818
+ {
819
+ return $this->_lcfirst(uc_words($name, ''));
820
+ }
821
+
822
+ /**
823
+ * For PHP < 5.3
824
+ *
825
+ * @param string $string
826
+ * @return string
827
+ */
828
+ protected function _lcfirst($string)
829
+ {
830
+ if (function_exists('lcfirst') !== false) {
831
+ return lcfirst($string);
832
+ } else {
833
+ if (!empty($string)) {
834
+ $string{0} = strtolower($string{0});
835
+ }
836
+ }
837
+ return $string;
838
+ }
839
+ }
app/code/community/Bronto/Common/Model/Email/Message/Templatefilter.php ADDED
@@ -0,0 +1,291 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Bronto_Common_Model_Email_Message_Templatefilter extends Mage_Core_Model_Email_Template_Filter
4
+ {
5
+
6
+
7
+ public function blockDirective($construction)
8
+ {
9
+ $params = $this->_getIncludeParameters($construction[2]);
10
+ switch($params['template']) {
11
+ case 'email/order/shipment/track.phtml':
12
+ return $this->_addBrontoStyle('shipmentTracking');
13
+ default:
14
+ return '';
15
+ }
16
+
17
+ }
18
+
19
+ /**
20
+ *
21
+ * @param array $construction
22
+ * @return string
23
+ */
24
+ public function layoutDirective($construction)
25
+ {
26
+ $params = $this->_getIncludeParameters($construction[2]);
27
+ switch ($params['handle']) {
28
+ case 'sales_email_order_shipment_items':
29
+ $return = 'shipmentItems';
30
+ break;
31
+ case 'sales_email_order_items':
32
+ $return = 'orderItems';
33
+ break;
34
+ case 'sales_email_order_creditmemo_items':
35
+ $return = 'creditmemoItems';
36
+ break;
37
+ case 'sales_email_order_invoice_items':
38
+ $return = 'invoiceItems';
39
+ break;
40
+ default:
41
+ return '';
42
+ break;
43
+ }
44
+ return $this->_addBrontoStyle($return);
45
+ }
46
+
47
+ /**
48
+ * Retrieve block parameters
49
+ *
50
+ * @param mixed $value
51
+ * @return array
52
+ */
53
+ protected function _getBlockParameters($value)
54
+ {
55
+ $tokenizer = new Varien_Filter_Template_Tokenizer_Parameter();
56
+ $tokenizer->setString($value);
57
+
58
+ return $tokenizer->tokenize();
59
+ }
60
+
61
+ /**
62
+ * Retrieve Skin URL directive
63
+ *
64
+ * @param array $construction
65
+ * @return string
66
+ */
67
+ public function skinDirective($construction)
68
+ {
69
+ return '';
70
+ }
71
+
72
+ /**
73
+ * Retrieve media file URL directive
74
+ *
75
+ * @param array $construction
76
+ * @return string
77
+ */
78
+ public function mediaDirective($construction)
79
+ {
80
+ return '';
81
+ }
82
+
83
+ /**
84
+ * Retrieve store URL directive
85
+ * Support url and direct_url properties
86
+ *
87
+ * @param array $construction
88
+ * @return string
89
+ */
90
+ public function storeDirective($construction)
91
+ {
92
+ $params = $this->_getIncludeParameters($construction[2]);
93
+
94
+ if (isset($params['direct_url'])) {
95
+ return $this->_addBrontoStyle('storeurl_' . str_replace('/', '_', $params['direct_url']));
96
+ } elseif (isset($params['url'])) {
97
+ switch (trim($params['url'],'/')) {
98
+ case 'checkout/cart':
99
+ return $this->_addBrontoStyle('cartURL');
100
+ case 'customer/account':
101
+ return $this->_addBrontoStyle('customerURL');
102
+ case 'adminhtml/index/resetpassword':
103
+ return $this->_addBrontoStyle('adminPasswordResetLink');
104
+ case 'customer/account/resetpassword':
105
+ return $this->_addBrontoStyle('passwordResetLink');
106
+ case 'customer/account/confirm':
107
+ return $this->_addBrontoStyle('confirmationLink');
108
+ case '':
109
+ return $this->_addBrontoStyle('storeURL');
110
+ default:
111
+ return $this->_addBrontoStyle('storeurl_' . str_replace('/', '_', $params['url']));
112
+ }
113
+ } else {
114
+ return $this->_addBrontoStyle('storeURL');
115
+ }
116
+ }
117
+
118
+ /**
119
+ * Directive for converting special characters to HTML entities
120
+ * Supported options:
121
+ * allowed_tags - Comma separated html tags that have not to be converted
122
+ *
123
+ * @param array $construction
124
+ * @return string
125
+ */
126
+ public function htmlescapeDirective($construction)
127
+ {
128
+ $params = $this->_getIncludeParameters($construction[2]);
129
+
130
+ if (strstr($construction[2],'var') === FALSE) {
131
+ return '';
132
+ }
133
+ $returnVariable = $this->processVariable(str_replace('var=$','',$construction[2]));
134
+ return $this->_addBrontoStyle($returnVariable);
135
+ }
136
+
137
+ /**
138
+ * Var directive with modifiers support
139
+ *
140
+ * @param array $construction
141
+ * @return string
142
+ */
143
+ public function varDirective($construction)
144
+ {
145
+ $returnVariable = $this->processVariable($construction[2]);
146
+ return $this->_addBrontoStyle($returnVariable);
147
+ }
148
+
149
+ protected function processVariable($variable)
150
+ {
151
+
152
+ switch (trim($variable)) {
153
+ case "order.getCreatedAtFormated('long')":
154
+ return 'orderCreatedAt';
155
+ case "rma.getCreatedAtFormated('long')":
156
+ return 'rmaCreatedAt';
157
+ case "logo_url":
158
+ return 'emailLogo';
159
+ case "user.name":
160
+ return 'adminName';
161
+ }
162
+ $parts = explode('|', $variable, 2);
163
+ if (2 === count($parts)) {
164
+ list($returnVariable, $modifiersString) = $parts;
165
+ } else {
166
+ $returnVariable = $variable;
167
+ }
168
+ $parts = explode('.', $returnVariable);
169
+ foreach ($parts as $i => $part) {
170
+ if (stripos($part, 'get') === 0) {
171
+ $parts[$i] = str_replace('get', '', $parts[$i]);
172
+ $parts[$i] = str_replace('()', '', $parts[$i]);
173
+ }
174
+ if (stripos($part, 'format') === 0) {
175
+ unset($parts[$i]);
176
+ }
177
+ }
178
+ return implode('_', $parts);
179
+ }
180
+
181
+ /**
182
+ * HTTP Protocol directive
183
+ *
184
+ * Using:
185
+ * {{protocol}} - current protocol http or https
186
+ * {{protocol url="www.domain.com/"}} domain URL with current protocol
187
+ * {{protocol http="http://url" https="https://url"}
188
+ * also allow additional parameter "store"
189
+ *
190
+ * @param array $construction
191
+ * @return string
192
+ */
193
+ public function protocolDirective($construction)
194
+ {
195
+ return '';
196
+ }
197
+
198
+ /**
199
+ * Store config directive
200
+ *
201
+ * @param array $construction
202
+ * @return string
203
+ */
204
+ public function configDirective($construction)
205
+ {
206
+ $configValue = '';
207
+ $params = $this->_getIncludeParameters($construction[2]);
208
+
209
+ switch ($params['path']) {
210
+ case 'trans_email/ident_support/email':
211
+ $returnValue = 'supportEmail';
212
+ break;
213
+ case 'general/store_information/phone':
214
+ $returnValue = 'supportPhone';
215
+ break;
216
+ case 'trans_email/ident_sales/email':
217
+ $returnValue = 'salesEmail';
218
+ break;
219
+ default:
220
+ $returnValue = str_replace('/','_',$params['path']);
221
+ break;
222
+ }
223
+ return $this->_addBrontoStyle($returnValue);
224
+ }
225
+
226
+ /**
227
+ * Custom Variable directive
228
+ *
229
+ * @param array $construction
230
+ * @return string
231
+ */
232
+ public function customvarDirective($construction)
233
+ {
234
+ return '';
235
+ }
236
+
237
+ /**
238
+ * Filter the string as template.
239
+ * Rewrited for logging exceptions
240
+ *
241
+ * @param string $value
242
+ * @return string
243
+ */
244
+ public function filter($value)
245
+ {
246
+ try {
247
+ $value = parent::filter($value);
248
+ } catch (Exception $e) {
249
+ $value = '';
250
+ Mage::logException($e);
251
+ }
252
+ return $value;
253
+ }
254
+
255
+ public function includeDirective($construction)
256
+ {
257
+ return '';
258
+ }
259
+
260
+ public function dependDirective($construction)
261
+ {
262
+ return $this->filter($construction[2]);
263
+ }
264
+
265
+ public function ifDirective($construction)
266
+ {
267
+ return '';
268
+ }
269
+
270
+ protected function _camelize($name)
271
+ {
272
+ return $this->_lcfirst(uc_words($name, ''));
273
+ }
274
+
275
+ protected function _lcfirst($string)
276
+ {
277
+ if (function_exists('lcfirst') !== false) {
278
+ return lcfirst($string);
279
+ } else {
280
+ if (!empty($string)) {
281
+ $string{0} = strtolower($string{0});
282
+ }
283
+ }
284
+ return $string;
285
+ }
286
+
287
+ protected function _addBrontoStyle($string)
288
+ {
289
+ return '%%#' . $this->_camelize($string) . '%%';
290
+ }
291
+ }
app/code/community/Bronto/Common/Model/Keysentry.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Model_Keysentry extends Mage_Core_Model_Abstract
9
+ {
10
+ /**
11
+ * Bronto email module alias
12
+ */
13
+ const EMAIL = 'bronto_email';
14
+
15
+ /**
16
+ * Bronto order module alias
17
+ */
18
+ const ORDER = 'bronto_order';
19
+
20
+ /**
21
+ * Bronto reminder module alias
22
+ */
23
+ const REMINDER = 'bronto_reminder';
24
+
25
+ /**
26
+ * Bronto newsletter module alias
27
+ */
28
+ const NEWSLETTER = 'bronto_newsletter';
29
+
30
+ /**
31
+ * Disable all the defined modules for the scope
32
+ *
33
+ * @param mixed $scope Site scope
34
+ * @param integer $scopeId Site scope id
35
+ */
36
+ public function disableModules($scope, $scopeId)
37
+ {
38
+ Mage::helper(self::EMAIL)->disableModule($scope, $scopeId);
39
+ Mage::helper(self::ORDER)->disableModule($scope, $scopeId);
40
+ Mage::helper(self::REMINDER)->disableModule($scope, $scopeId);
41
+ Mage::helper(self::NEWSLETTER)->disableModule($scope, $scopeId);
42
+ }
43
+
44
+ public function unlinkEmails(Mage_Core_Model_Resource_Db_Collection_Abstract $collection, $scopeId)
45
+ {
46
+ /*
47
+ // missing key variable. disabling for launch, keys are still relinked later
48
+ Mage::log($scopeId);
49
+ $collection->addFieldToFilter('bronto_message_id', array('eq' => strtolower($apiKey)));
50
+
51
+ // foreach ($collection as $template) {
52
+ // $template->unsetData('bronto_message_id');
53
+ // $template->save();
54
+ // }
55
+ // I think this is wrong (JK)
56
+ // @TODO comeback and revaluate this code
57
+ Mage::log($scopeId);
58
+ $collection->addFieldToFilter('bronto_message_id', array('eq' => strtolower($apiKey)));
59
+
60
+ foreach ($collection as $template) {
61
+ $template->unsetData('bronto_message_id');
62
+ $template->save();
63
+ }
64
+ */
65
+ }
66
+ }
app/code/community/Bronto/Common/Model/Observer.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Bronto
5
+ * @package Common
6
+ */
7
+ class Bronto_Common_Model_Observer
8
+ {
9
+
10
+ /**
11
+ * Description for const
12
+ */
13
+ const NOTICE_IDENTIFER = 'bronto_common';
14
+
15
+ /**
16
+ * @param Varien_Event_Observer $observer
17
+ * @return mixed
18
+ */
19
+ public function checkBrontoRequirements(Varien_Event_Observer $observer)
20
+ {
21
+ if (!Mage::getSingleton('admin/session')->isLoggedIn()) {
22
+ return;
23
+ }
24
+
25
+ // Verify Requirements
26
+ if (!Mage::helper(self::NOTICE_IDENTIFER)->varifyRequirements(self::NOTICE_IDENTIFER, array('soap', 'openssl'))) {
27
+ return;
28
+ }
29
+
30
+ // Verify API tokens are valid
31
+ if (Mage::helper(self::NOTICE_IDENTIFER)->isEnabled() && !Mage::helper(self::NOTICE_IDENTIFER)->validApiTokens(self::NOTICE_IDENTIFER)) {
32
+ return false;
33
+ }
34
+ }
35
+ }
app/code/community/Bronto/Common/Model/Resource/Setup.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Common_Model_Resource_Setup extends Mage_Sales_Model_Mysql4_Setup
9
+ {
10
+ public function handleOld()
11
+ {
12
+ // Look if Bronto folder exists in local codepool and recursively remove if it is
13
+ $source = Mage::getBaseDir('base') . DS . 'app' . DS . 'code' . DS . 'local' . DS . 'Bronto' . DS;
14
+ $destination = Mage::getBaseDir('base') . DS . 'var' . DS . 'bronto_backup' . DS;
15
+ if (file_exists($source)) {
16
+ $this->rcopy($source, $destination);
17
+ $this->rrmdir($source);
18
+
19
+ // Add Notification so customer is sure to know
20
+ $adminnotice = Mage::getSingleton('adminnotification/inbox')->add(
21
+ 4,
22
+ 'Bronto Update - Old Version Moved',
23
+ 'Bronto has been updated. We have moved the files from your previous intstallation to ' . $destination
24
+ );
25
+ }
26
+ }
27
+
28
+ public function rrmdir($dir)
29
+ {
30
+ $files = array_diff(scandir($dir), array('.', '..'));
31
+ foreach ($files as $file) {
32
+ (is_dir("$dir/$file")) ? $this->rrmdir("$dir/$file") : unlink("$dir/$file");
33
+ }
34
+ rmdir($dir);
35
+ }
36
+
37
+ public function rcopy($src, $dst)
38
+ {
39
+ // Remove Destination if it is a file
40
+ if (file_exists($dst)) {
41
+ $this->rrmdir($dst);
42
+ }
43
+ // If Source is a directory create destination and move everything
44
+ if (is_dir($src)) {
45
+ mkdir($dst);
46
+ $files = scandir($src);
47
+ foreach ($files as $file) {
48
+ if ($file != "." && $file != "..") {
49
+ $this->rcopy("$src/$file", "$dst/$file");
50
+ }
51
+ }
52
+ } elseif (file_exists($src)) {
53
+ copy($src, $dst);
54
+ }
55
+ }
56
+ }
app/code/community/Bronto/Common/Model/System/Config/Backend/Cron.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ abstract class Bronto_Common_Model_System_Config_Backend_Cron extends Mage_Core_Model_Config_Data
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_cron_string_path;
14
+
15
+ /**
16
+ * @var string
17
+ */
18
+ protected $_cron_model_path;
19
+
20
+ /**
21
+ * @var string
22
+ */
23
+ protected $_xml_path_enabled = 'enabled';
24
+
25
+ /**
26
+ * Cron settings after save
27
+ *
28
+ * @return Bronto_Common_Model_System_Config_Backend_Cron
29
+ */
30
+ protected function _afterSave()
31
+ {
32
+ $cronExprString = '';
33
+
34
+ if ($this->getFieldsetDataValue($this->_xml_path_enabled)) {
35
+ $minutely = Bronto_Common_Model_System_Config_Source_Cron_Frequency::CRON_MINUTELY;
36
+ $hourly = Bronto_Common_Model_System_Config_Source_Cron_Frequency::CRON_HOURLY;
37
+ $daily = Bronto_Common_Model_System_Config_Source_Cron_Frequency::CRON_DAILY;
38
+ $frequency = $this->getFieldsetDataValue('frequency');
39
+
40
+ if ($frequency == $minutely) {
41
+ $interval = (int) $this->getFieldsetDataValue('interval');
42
+ $cronExprString = "*/{$interval} * * * *";
43
+ } elseif ($frequency == $hourly) {
44
+ $minutes = (int) $this->getFieldsetDataValue('minutes');
45
+ if ($minutes >= 0 && $minutes <= 59) {
46
+ $cronExprString = "{$minutes} * * * *";
47
+ } else {
48
+ Mage::throwException(Mage::helper('bronto_common')->__('Please, specify correct minutes of hour.'));
49
+ }
50
+ } elseif ($frequency == $daily) {
51
+ $time = $this->getFieldsetDataValue('time');
52
+ $timeMinutes = intval($time[1]);
53
+ $timeHours = intval($time[0]);
54
+ $cronExprString = "{$timeMinutes} {$timeHours} * * *";
55
+ }
56
+ }
57
+
58
+ try {
59
+ if (!empty($this->_cron_string_path)) {
60
+ $this->_saveConfigData($this->_cron_string_path, $cronExprString);
61
+ }
62
+ if (!empty($this->_cron_model_path)) {
63
+ $this->_saveConfigData($this->_cron_model_path, (string) Mage::getConfig()->getNode($this->_cron_model_path));
64
+ }
65
+ } catch (Exception $e) {
66
+ Mage::throwException(Mage::helper('adminhtml')->__('Unable to save Cron expression'));
67
+ }
68
+ }
69
+
70
+ /**
71
+ * Get value by key for new user data from <section>/groups/<group>/fields/<field>
72
+ *
73
+ * @return string
74
+ */
75
+ public function getFieldsetDataValue($key)
76
+ {
77
+ if (method_exists('Mage_Core_Model_Config_Data', 'getFieldsetDataValue')) {
78
+ return parent::getFieldsetDataValue($key);
79
+ }
80
+
81
+ // Handle older Magento versions
82
+ $data = $this->_getData('fieldset_data');
83
+ if (is_array($data) && isset($data[$key])) {
84
+ return $data[$key];
85
+ }
86
+
87
+ $data = $this->getData();
88
+ $groups = isset($data['groups']) ? $data['groups'] : array();
89
+ $groupId = isset($data['group_id']) ? $data['group_id'] : array();
90
+ foreach ($groups as $group => $fields) {
91
+ $fields = isset($fields['fields']) ? $fields['fields'] : $fields;
92
+ if ($group == $groupId) {
93
+ if (isset($fields[$key]['value'])) {
94
+ return $fields[$key]['value'];
95
+ }
96
+ }
97
+ }
98
+
99
+ return null;
100
+ }
101
+
102
+ /**
103
+ * @param type $path
104
+ * @param type $value
105
+ * @return Bronto_Common_Model_System_Config_Backend_Cron
106
+ */
107
+ protected function _saveConfigData($path, $value)
108
+ {
109
+ Mage::getModel('core/config_data')
110
+ ->load($path, 'path')
111
+ ->setValue($value)
112
+ ->setPath($path)
113
+ ->save();
114
+
115
+ return $this;
116
+ }
117
+ }
app/code/community/Bronto/Common/Model/System/Config/Backend/Token.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_Model_System_Config_Backend_Token extends Mage_Core_Model_Config_Data
9
+ {
10
+ /**
11
+ * @return Bronto_Common_Model_System_Config_Backend_Token
12
+ */
13
+ protected function _beforeSave()
14
+ {
15
+ $value = $this->getValue();
16
+ if (!empty($value)) {
17
+ if (Mage::helper('bronto_common')->validApiToken($value) === false) {
18
+ Mage::throwException(Mage::helper('bronto_common')->__('The Bronto API Token you have entered appears to be invalid.'));
19
+ }
20
+
21
+ // API key is new and doesn't match existing API key
22
+ $currentApiKey = Mage::helper('bronto_common')->getApiToken();
23
+ if ($currentApiKey !== $value) {
24
+ // reset the verified status
25
+ Mage::helper('bronto_roundtrip')->setRoundtripStatus(
26
+ Mage::helper('bronto_roundtrip')->getPath('status'),
27
+ '2'
28
+ );
29
+
30
+ $sentry = Mage::getModel('bronto_common/keysentry');
31
+ $sentry->disableModules($this->getScope(), $this->getScopeId());
32
+ $version = Mage::getVersionInfo();
33
+ if (1 == $version['major'] && 9 != $version['minor']) {
34
+ $sentry->unlinkEmails(
35
+ Mage::getResourceSingleton('core/email_template_collection'),
36
+ $this->getScopeId()
37
+ );
38
+ }
39
+ }
40
+ } else {
41
+ Mage::helper('bronto_roundtrip')->setRoundtripStatus(
42
+ Mage::helper('bronto_roundtrip')->getPath('status'),
43
+ '2'
44
+ );
45
+ }
46
+
47
+ return parent::_beforeSave();
48
+ }
49
+ }
app/code/community/Bronto/Common/Model/System/Config/Source/Contact/Status.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Bronto
5
+ * @package Common
6
+ */
7
+ class Bronto_Common_Model_System_Config_Source_Contact_Status
8
+ {
9
+
10
+ /**
11
+ * Description for protected
12
+ * @var array
13
+ * @access protected
14
+ */
15
+ protected $_options = array();
16
+
17
+ /**
18
+ * Short description for function
19
+ *
20
+ * Long description (if any) ...
21
+ *
22
+ * @return array Return description (if any) ...
23
+ * @access public
24
+ */
25
+ public function toOptionArray()
26
+ {
27
+ if (!empty($this->_options)) {
28
+ return $this->_options;
29
+ }
30
+
31
+ try {
32
+ if ($api = Mage::helper('bronto_common')->getApi()) {
33
+ /* @var $contactObject Bronto_Api_Contact */
34
+ $contactObject = $api->getContactObject();
35
+ foreach ($contactObject->getOptionValues('status') as $status) {
36
+ $this->_options[] = array(
37
+ 'value' => $status,
38
+ 'label' => $status,
39
+ );
40
+ }
41
+ }
42
+ } catch (Exception $e) {
43
+ // Ignore
44
+ }
45
+
46
+ return $this->_options;
47
+ }
48
+ }
app/code/community/Bronto/Common/Model/System/Config/Source/Cron/Frequency.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Bronto
5
+ * @package Common
6
+ */
7
+ class Bronto_Common_Model_System_Config_Source_Cron_Frequency
8
+ {
9
+
10
+ /**
11
+ * Description for const
12
+ */
13
+ const CRON_MINUTELY = 'I';
14
+
15
+ /**
16
+ * Description for const
17
+ */
18
+ const CRON_HOURLY = 'H';
19
+
20
+ /**
21
+ * Description for const
22
+ */
23
+ const CRON_DAILY = 'D';
24
+
25
+ /**
26
+ * Short description for function
27
+ *
28
+ * Long description (if any) ...
29
+ *
30
+ * @return mixed Return description (if any) ...
31
+ * @access public
32
+ */
33
+ public function toOptionArray()
34
+ {
35
+ return array(
36
+ self::CRON_MINUTELY => Mage::helper('cron')->__('Minute Intervals'),
37
+ self::CRON_HOURLY => Mage::helper('cron')->__('Hourly'),
38
+ self::CRON_DAILY => Mage::helper('cron')->__('Daily'),
39
+ );
40
+ }
41
+ }
app/code/community/Bronto/Common/Model/System/Config/Source/Cron/Minutes.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Bronto
5
+ * @package Common
6
+ */
7
+ class Bronto_Common_Model_System_Config_Source_Cron_Minutes
8
+ {
9
+
10
+ /**
11
+ * Short description for function
12
+ *
13
+ * Long description (if any) ...
14
+ *
15
+ * @return mixed Return description (if any) ...
16
+ * @access public
17
+ */
18
+ public function toOptionArray()
19
+ {
20
+ return array(
21
+ 5 => Mage::helper('cron')->__('5 minutes'),
22
+ 10 => Mage::helper('cron')->__('10 minutes'),
23
+ 15 => Mage::helper('cron')->__('15 minutes'),
24
+ 20 => Mage::helper('cron')->__('20 minutes'),
25
+ 30 => Mage::helper('cron')->__('30 minutes'),
26
+ );
27
+ }
28
+ }
app/code/community/Bronto/Common/Model/System/Config/Source/Field.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Bronto
5
+ * @package Common
6
+ */
7
+ class Bronto_Common_Model_System_Config_Source_Field
8
+ {
9
+ /**
10
+ * @var array
11
+ */
12
+ protected $_options = array();
13
+
14
+ /**
15
+ * @return array
16
+ */
17
+ public function toOptionArray()
18
+ {
19
+ if (!empty($this->_options)) {
20
+ return $this->_options;
21
+ }
22
+
23
+ try {
24
+ if ($api = Mage::helper('bronto_common')->getApi()) {
25
+ /* @var $fieldObject Bronto_Api_Field */
26
+ $fieldObject = $api->getFieldObject();
27
+ foreach ($fieldObject->readAll()->iterate() as $field /* @var $field Bronto_Api_Field_Row */) {
28
+ $this->_options[] = array(
29
+ 'value' => $field->name,
30
+ 'label' => $field->label,
31
+ );
32
+ }
33
+ }
34
+ } catch (Exception $e) {
35
+ Mage::helper('bronto_common')->writeError($e);
36
+ }
37
+
38
+ array_unshift($this->_options, array(
39
+ 'label' => 'Create New...',
40
+ 'value' => '_new_',
41
+ ));
42
+
43
+ array_unshift($this->_options, array(
44
+ 'label' => '-- None Selected --',
45
+ 'value' => '_none_',
46
+ ));
47
+
48
+ return $this->_options;
49
+ }
50
+ }
app/code/community/Bronto/Common/Model/System/Config/Source/List.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Bronto
5
+ * @package Common
6
+ */
7
+ class Bronto_Common_Model_System_Config_Source_List
8
+ {
9
+ /**
10
+ * @var array
11
+ */
12
+ protected $_options = array();
13
+
14
+ /**
15
+ * @return array
16
+ */
17
+ public function toOptionArray()
18
+ {
19
+ if (!empty($this->_options)) {
20
+ return $this->_options;
21
+ }
22
+
23
+ try {
24
+ if ($api = Mage::helper('bronto_common')->getApi()) {
25
+ /* @var $listObject Bronto_Api_List */
26
+ $listObject = $api->getListObject();
27
+ foreach ($listObject->readAll()->iterate() as $list /* @var $list Bronto_Api_List_Row */) {
28
+ $this->_options[] = array(
29
+ 'value' => $list->id,
30
+ 'label' => $list->label,
31
+ );
32
+ }
33
+ }
34
+ } catch (Exception $e) {
35
+ Mage::helper('bronto_common')->writeError($e);
36
+ }
37
+
38
+ return $this->_options;
39
+ }
40
+ }
app/code/community/Bronto/Common/Model/System/Config/Source/Message.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Bronto
5
+ * @package Bronto_Common
6
+ */
7
+ class Bronto_Common_Model_System_Config_Source_Message
8
+ {
9
+ /**
10
+ * @var array
11
+ */
12
+ protected $_options = array();
13
+
14
+ /**
15
+ * @return array
16
+ */
17
+ public function toOptionArray($token = null)
18
+ {
19
+ if (!empty($this->_options)) {
20
+ return $this->_options;
21
+ }
22
+
23
+ try {
24
+ if ($api = Mage::helper('bronto_common')->getApi($token)) {
25
+ /* @var $messageObject Bronto_Api_Message */
26
+ $messageObject = $api->getMessageObject();
27
+ foreach ($messageObject->readAll()->iterate() as $message /* @var $message Bronto_Api_Message_Row */) {
28
+ $_option = array(
29
+ 'label' => $message->name,
30
+ 'value' => $message->id,
31
+ );
32
+
33
+ if ($message->status != 'active') {
34
+ $_option['disabled'] = true;
35
+ }
36
+
37
+ $this->_options[] = $_option;
38
+ }
39
+ }
40
+ } catch (Exception $e) {
41
+ Mage::helper('bronto_common')->writeError($e);
42
+ }
43
+
44
+ array_unshift($this->_options, array(
45
+ 'label' => '-- None Selected --',
46
+ 'value' => '',
47
+ ));
48
+
49
+ return $this->_options;
50
+ }
51
+ }
app/code/community/Bronto/Common/Test/Config/Config.php ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_Common_Test_Config_Config
3
+ extends EcomDev_PHPUnit_Test_Case_Config
4
+ {
5
+ public function blocksProvider()
6
+ {
7
+ return array(
8
+ array('bronto_common/adminhtml_system_config_about', 'Bronto_Common_Block_Adminhtml_System_Config_About'),
9
+ array('bronto_common/adminhtml_system_config_cron', 'Bronto_Common_Block_Adminhtml_System_Config_Cron'),
10
+ array('bronto_common/adminhtml_system_config_form_field', 'Bronto_Common_Block_Adminhtml_System_Config_Form_Field'),
11
+ array('bronto_common/adminhtml_system_config_form_field_apitoken', 'Bronto_Common_Block_Adminhtml_System_Config_Form_Field_Apitoken'),
12
+ array('bronto_common/adminhtml_system_config_form_field_hidden', 'Bronto_Common_Block_Adminhtml_System_Config_Form_Field_Hidden'),
13
+ array('bronto_common/adminhtml_system_config_form_field_list', 'Bronto_Common_Block_Adminhtml_System_Config_Form_Field_List'),
14
+ );
15
+ }
16
+
17
+ public function modelsProvider()
18
+ {
19
+ return array(
20
+ array('bronto_common/api', 'Bronto_Common_Model_Api'),
21
+ array('bronto_common/email_message', 'Bronto_Common_Model_Email_Message'),
22
+ array('bronto_common/email_message_filter', 'Bronto_Common_Model_Email_Message_Filter'),
23
+ array('bronto_common/system_config_backend_cron', 'Bronto_Common_Model_System_Config_Backend_Cron'),
24
+ array('bronto_common/system_config_backend_token', 'Bronto_Common_Model_System_Config_Backend_Token'),
25
+ array('bronto_common/system_config_source_fields', 'Bronto_Common_Model_System_Config_Source_Fields'),
26
+ array('bronto_common/system_config_source_list', 'Bronto_Common_Model_System_Config_Source_List'),
27
+ array('bronto_common/system_config_source_contact_status', 'Bronto_Common_Model_System_Config_Source_Contact_Status'),
28
+ array('bronto_common/system_config_source_cron_frequency', 'Bronto_Common_Model_System_Config_Source_Cron_Frequency'),
29
+ array('bronto_common/system_config_source_cron_minutes', 'Bronto_Common_Model_System_Config_Source_Cron_Minutes',),
30
+ );
31
+ }
32
+
33
+ public function resourceModelProvider()
34
+ {
35
+ return array(
36
+ array('bronto_common/resource_setup', 'Bronto_Common_Model_Resource_Setup'),
37
+ );
38
+ }
39
+
40
+ public function observersProvider()
41
+ {
42
+ return array(
43
+ array('adminhtml', 'controller_action_predispatch', 'bronto_common/observer', 'checkBrontoRequirements')
44
+ );
45
+ }
46
+
47
+ public function helpersProvider()
48
+ {
49
+ return array(
50
+ array('bronto_common/data', 'Bronto_Common_Helper_Data'),
51
+ array('bronto_common/message', 'Bronto_Common_Helper_Message'),
52
+ array('bronto_common/contact', 'Bronto_Common_Helper_Contact'),
53
+ array('bronto_common/field', 'Bronto_Common_Helper_Field'),
54
+ array('bronto_common/product', 'Bronto_Common_Helper_Product'),
55
+ );
56
+ }
57
+
58
+ public function dependsProvider()
59
+ {
60
+ return array(
61
+ array('Mage_Adminhtml'),
62
+ array('Mage_Customer'),
63
+ array('Mage_Checkout'),
64
+ array('Mage_Sales'),
65
+ );
66
+ }
67
+
68
+ /**
69
+ * @test
70
+ * @group amd
71
+ * @group config
72
+ */
73
+ public function assertCommonModuleVersionGreaterThanOrEquals()
74
+ {
75
+ $this->assertModuleVersionGreaterThanOrEquals('1.7.0');
76
+ }
77
+
78
+ /**
79
+ * @test
80
+ * @group amd
81
+ * @group config
82
+ */
83
+ public function assertCommonModuleInCommunityCodePool()
84
+ {
85
+ $this->assertModuleCodePool('community');
86
+ }
87
+
88
+ /**
89
+ * @test
90
+ * @group amd
91
+ * @group config
92
+ * @dataProvider dependsProvider
93
+ */
94
+ public function assertCommonModuleDepends(
95
+ $requiredModuleName
96
+ ) {
97
+ $this->assertModuleDepends($requiredModuleName);
98
+ }
99
+
100
+ /**
101
+ * @test
102
+ * @group amd
103
+ * @group config
104
+ * @dataProvider modelsProvider
105
+ */
106
+ public function assertCommonModelAliases(
107
+ $classAlias,
108
+ $expectedClassName
109
+ ) {
110
+ $this->assertModelAlias($classAlias, $expectedClassName);
111
+ }
112
+
113
+ /**
114
+ * @test
115
+ * @group amd
116
+ * @group config
117
+ * @dataProvider resourceModelProvider
118
+ */
119
+ public function assertCommonResourceModelAliases(
120
+ $classAlias,
121
+ $expectedClassName
122
+ ) {
123
+ $this->assertResourceModelAlias($classAlias, $expectedClassName);
124
+ }
125
+
126
+ /**
127
+ * @test
128
+ * @group amd
129
+ * @group config
130
+ * @dataProvider observersProvider
131
+ */
132
+ public function assertCommonEventObserversDefined(
133
+ $area,
134
+ $eventName,
135
+ $observerClassAlias,
136
+ $observerMethod
137
+ ) {
138
+ $this->assertEventObserverDefined(
139
+ $area,
140
+ $eventName,
141
+ $observerClassAlias,
142
+ $observerMethod
143
+ );
144
+ }
145
+
146
+ /**
147
+ * @test
148
+ * @group amd
149
+ * @group config
150
+ * @dataProvider blocksProvider
151
+ */
152
+ public function assertCommonBlockAliases(
153
+ $classAlias,
154
+ $expectedClassName
155
+ ) {
156
+ $this->assertBlockAlias($classAlias, $expectedClassName);
157
+ }
158
+
159
+ /**
160
+ * @test
161
+ * @group amd
162
+ * @group config
163
+ * @dataProvider helpersProvider
164
+ */
165
+ public function assertCommonHelperAliases(
166
+ $classAlias,
167
+ $expectedClassName
168
+ ) {
169
+ $this->assertHelperAlias($classAlias, $expectedClassName);
170
+ }
171
+ }
app/code/community/Bronto/Common/Test/Model/Checkout.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ abstract class Bronto_Common_Test_Model_Checkout extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+ /**
6
+ * @return Mage_Sales_Model_Order
7
+ */
8
+ public function createRandomGuestOrder()
9
+ {
10
+ /* @var $quote Mage_Sales_Model_Quote */
11
+ $quote = $this->_queryOrder();
12
+
13
+ /* @var $service Mage_Sales_Model_Service_Quote */
14
+ $service = Mage::getModel('sales/service_quote', $quote);
15
+ $service->submitAll();
16
+
17
+ $order = $service->getOrder();
18
+ $order->sendNewOrderEmail();
19
+ return $order;
20
+ }
21
+
22
+ /**
23
+ * @param Mage_Sales_Model_Order $order
24
+ * @return boolean
25
+ */
26
+ public function createInvoiceForOrder(Mage_Sales_Model_Order $order)
27
+ {
28
+ if ($order->canInvoice()) {
29
+ $invoiceId = Mage::getModel('sales/order_invoice_api')
30
+ ->create($order->getIncrementId(), array());
31
+
32
+ return Mage::getModel('sales/order_invoice')
33
+ ->loadByIncrementId($invoiceId)
34
+ ->capture()
35
+ ->save();
36
+ }
37
+
38
+ return false;
39
+ }
40
+
41
+ /**
42
+ * @param Mage_Sales_Model_Order $order
43
+ * @return boolean
44
+ */
45
+ public function createShipmentForOrder(Mage_Sales_Model_Order $order)
46
+ {
47
+ if ($order->canShip()) {
48
+ $shipmentId = Mage::getModel('sales/order_shipment_api')
49
+ ->create($order->getIncrementId(), array(), 'Test Shipment Created', true);
50
+
51
+ return Mage::getModel('sales/order_shipment_api')
52
+ ->addTrack($shipmentId, 'ups', 'UPS Test Shipment', rand(1000000000, 9999999999));
53
+ }
54
+
55
+ return false;
56
+ }
57
+
58
+ /**
59
+ * @param array $orderData
60
+ * @return Mage_Sales_Model_Quote
61
+ */
62
+ protected function _queryOrder()
63
+ {
64
+ /* @var $quote Mage_Sales_Model_Quote */
65
+ $quote = Mage::getModel('sales/quote');
66
+
67
+ foreach (array(166, 156, 149) as $productId) {
68
+ /* @var $product Mage_Catalog_Model_Product */
69
+ $product = Mage::getModel('catalog/product')->load($productId);
70
+ $quote->addProduct($product, 1);
71
+ }
72
+
73
+ $this->_addBillingAddress($quote);
74
+ $this->_addShippingAddress($quote);
75
+ $this->_addShippingMethod($quote);
76
+ $this->_addPayment($quote);
77
+
78
+ $quote = $this->_prepareGuestQuote($quote);
79
+ $quote->collectTotals()->save();
80
+ return $quote;
81
+ }
82
+
83
+ /**
84
+ * @param string $regionCode
85
+ * @param string $countryCode
86
+ * @return null
87
+ */
88
+ protected function _getIdByRegionCode($regionCode, $countryCode)
89
+ {
90
+ $region = Mage::getModel('directory/region')->loadByCode($regionCode, $countryCode);
91
+ if (!!$region && !!$region->getId()) {
92
+ return $region->getId();
93
+ }
94
+ return null;
95
+ }
96
+
97
+ /**
98
+ * @param Mage_Sales_Model_Quote $quote
99
+ */
100
+ protected function _addBillingAddress(Mage_Sales_Model_Quote $quote)
101
+ {
102
+ $billingAddress = $quote->getBillingAddress();
103
+ $billingAddress
104
+ ->setData('firstname', 'John')
105
+ ->setData('lastname', 'Doe ' . rand(0, 99))
106
+ ->setData('street', '123 Main St')
107
+ ->setData('city', 'Monroe')
108
+ ->setData('postcode', '28110')
109
+ ->setData('region_id', $this->_getIdByRegionCode('NC', 'US'))
110
+ ->setData('region', 'NC')
111
+ ->setData('country_id', 'US')
112
+ ->setData('telephone', '7045555555');
113
+ }
114
+
115
+ /**
116
+ * @param Mage_Sales_Model_Quote $quote
117
+ */
118
+ protected function _addShippingAddress(Mage_Sales_Model_Quote $quote)
119
+ {
120
+ $shippingAddress = $quote->getShippingAddress();
121
+ $shippingAddress
122
+ ->setData('firstname', 'John')
123
+ ->setData('lastname', 'Doe ' . rand(0, 99))
124
+ ->setData('street', '123 Main St')
125
+ ->setData('city', 'Monroe')
126
+ ->setData('postcode', '28110')
127
+ ->setData('region_id', $this->_getIdByRegionCode('NC', 'US'))
128
+ ->setData('region', 'NC')
129
+ ->setData('country_id', 'US')
130
+ ->setData('telephone', '7045555555');
131
+ }
132
+
133
+ /**
134
+ * @param Mage_Sales_Model_Quote $quote
135
+ */
136
+ protected function _addShippingMethod(Mage_Sales_Model_Quote $quote)
137
+ {
138
+ $shippingAddress = $quote->getShippingAddress();
139
+ $shippingAddress->setShippingMethod('flatrate_flatrate');
140
+ }
141
+
142
+ /**
143
+ * @param Mage_Sales_Model_Quote $quote
144
+ */
145
+ protected function _addPayment(Mage_Sales_Model_Quote $quote)
146
+ {
147
+ if ($quote->isVirtual()) {
148
+ $quote->getBillingAddress()->setPaymentMethod('checkmo');
149
+ } else {
150
+ $quote->getShippingAddress()->setPaymentMethod('checkmo');
151
+ }
152
+
153
+ if (!$quote->isVirtual() && $quote->getShippingAddress()) {
154
+ $quote->getShippingAddress()->setCollectShippingRates(true);
155
+ }
156
+
157
+ /* @var $payment Mage_Sales_Model_Quote_Payment */
158
+ $payment = $quote->getPayment();
159
+ $payment->importData(array('method' => 'checkmo'));
160
+ $quote->setPayment($payment);
161
+ }
162
+
163
+ /**
164
+ * @param Mage_Sales_Model_Quote $quote
165
+ * @return Mage_Sales_Model_Quote
166
+ */
167
+ protected function _prepareGuestQuote(Mage_Sales_Model_Quote $quote)
168
+ {
169
+ $quote->setCustomerId(null);
170
+ $quote->setCustomerEmail('j.doe+' . date('YmdHis') . '@bronto.com');
171
+ $quote->setCustomerIsGuest(true);
172
+ $quote->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
173
+ return $quote;
174
+ }
175
+
176
+ /**
177
+ * @param Mage_Sales_Model_Quote $quote
178
+ * @param type $customerId
179
+ * @return Mage_Sales_Model_Quote
180
+ */
181
+ protected function _prepareCustomerQuote(Mage_Sales_Model_Quote $quote, $customerId)
182
+ {
183
+ $customer = Mage::getModel('customer/customer')->load($customerId);
184
+ $quote->setCustomer($customer);
185
+ return $quote;
186
+ }
187
+ }
app/code/community/Bronto/Common/Test/Model/Keysentry.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Bronto_Common_Test_Model_Keysentry extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+ public function configDataProvider()
6
+ {
7
+ $data = array(
8
+ 'field' => 'api_token',
9
+ 'group_id' => 'settings',
10
+ 'store_code' => '',
11
+ 'website_code' => '',
12
+ 'scope' => 'default',
13
+ 'scope_id' => 0,
14
+ 'fieldset_data' => array(
15
+ 'api_token' => '',
16
+ 'debug' => '',
17
+ 'verbose' => '',
18
+ 'test' => '',
19
+ 'notices' => '',
20
+ ),
21
+ 'path' => 'bronto/settings/api_token',
22
+ 'value' => '53873730-F77B-4B0D-9840-43F21846F991',
23
+ );
24
+ $defaultConfig = Mage::getModel('bronto_common/system_config_backend_token');
25
+ $defaultConfig->setData($data);
26
+
27
+ $data['website_code'] = 'base';
28
+ $data['scope'] = 'websites';
29
+ $data['scope_id'] = 1;
30
+ $websiteConfig = Mage::getModel('bronto_common/system_config_backend_token');
31
+ $websiteConfig->setData($data);
32
+
33
+ $data['store_code'] = 'default';
34
+ $data['scope'] = 'stores';
35
+ $data['scope_id'] = 1;
36
+ $englishConfig = Mage::getModel('bronto_common/system_config_backend_token');
37
+ $englishConfig->setData($data);
38
+
39
+ $data['store_code'] = 'french';
40
+ $data['scope'] = 'stores';
41
+ $data['scope_id'] = 3;
42
+ $frenchConfig = Mage::getModel('bronto_common/system_config_backend_token');
43
+ $frenchConfig->setData($data);
44
+
45
+ $data['store_code'] = 'german';
46
+ $data['scope'] = 'stores';
47
+ $data['scope_id'] = 2;
48
+ $germanConfig = Mage::getModel('bronto_common/system_config_backend_token');
49
+ $germanConfig->setData($data);
50
+
51
+ return array(
52
+ array($defaultConfig),
53
+ array($websiteConfig),
54
+ array($englishConfig),
55
+ array($frenchConfig),
56
+ array($germanConfig),
57
+ );
58
+ }
59
+
60
+ /**
61
+ * @test
62
+ * @group jmk
63
+ * @group model
64
+ * @dataProvider configDataProvider
65
+ */
66
+ public function getMatchingScopes($configuration)
67
+ {
68
+ $config = Mage::getStoreConfig('bronto/settings/api_token');
69
+ var_dump($config);
70
+ }
71
+ }
app/code/community/Bronto/Common/Test/Model/Keysentry/fixtures/seed.yaml ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ scope:
2
+ website:
3
+ - website_id:
app/code/community/Bronto/Common/controllers/LogController.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Common
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.6.7
7
+ */
8
+ class Bronto_Common_LogController extends Mage_Core_Controller_Front_Action
9
+ {
10
+ /**
11
+ * @var array
12
+ */
13
+ private $_allowedIps = array(
14
+ '4.59.160.2',
15
+ '174.46.136.66',
16
+ );
17
+
18
+ /**
19
+ * Allows download of var/*.log files
20
+ *
21
+ * @return string
22
+ */
23
+ public function indexAction()
24
+ {
25
+
26
+ // Requirements for this controller require that Bronto's
27
+ // Debug mode be enabled for any log file to be available
28
+ // for download
29
+ if(!Mage::helper('bronto_common')->isDebugEnabled())
30
+ return $this->norouteAction();
31
+
32
+ // Add dyndns
33
+ $this->_allowedIps[] = gethostbyname('leek.dyndns.org');
34
+
35
+ $fileName = $this->getRequest()->getParam('name');
36
+ if (empty($fileName)) {
37
+ $fileName = $this->getRequest()->getParam('file');
38
+ }
39
+
40
+ $print = $this->getRequest()->getParam('print', false);
41
+ if (stripos($fileName, '.log') === false) {
42
+ $fileName .= '.log';
43
+ }
44
+
45
+ $filePath = Mage::getBaseDir('log') . DIRECTORY_SEPARATOR . $fileName;
46
+
47
+ if (empty($fileName) || !@file_exists($filePath)) {
48
+ return $this->norouteAction();
49
+ }
50
+
51
+ /* @var $httpHelper Mage_Core_Helper_Http */
52
+ $httpHelper = Mage::helper('core/http');
53
+ $ipAddress = $httpHelper->getRemoteAddr();
54
+
55
+ if (!in_array($ipAddress, $this->_allowedIps)) {
56
+ if (!Mage::getSingleton('admin/session')->isLoggedIn()) {
57
+ return $httpHelper->authFailed();
58
+ }
59
+ }
60
+
61
+ $this->getResponse()
62
+ ->setHttpResponseCode(200)
63
+ ->setHeader('Content-Type', 'text/plain', true)
64
+ ->setHeader('Pragma', 'public', true)
65
+ ->setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0', true);
66
+
67
+ if ($contentLength = @filesize($filePath)) {
68
+ $this->getResponse()->setHeader('Content-Length', $contentLength);
69
+ }
70
+
71
+ if ($lastModified = @filemtime($filePath)) {
72
+ $this->getResponse()->setHeader('Last-Modified', date('r', $lastModified));
73
+ }
74
+
75
+ if (!$print) {
76
+ $this->getResponse()->setHeader('Content-Disposition', 'attachment; filename="'.$fileName.'"');
77
+ }
78
+
79
+ $this->getResponse()->clearBody();
80
+ $this->getResponse()->sendHeaders();
81
+ $this->_readfileChunked($filePath);
82
+ exit;
83
+ }
84
+
85
+ /**
86
+ * Short description for function
87
+ *
88
+ * Long description (if any) ...
89
+ *
90
+ * @param unknown $filePath Parameter description (if any) ...
91
+ * @param boolean $returnBytes Parameter description (if any) ...
92
+ * @return mixed Return description (if any) ...
93
+ * @access private
94
+ */
95
+ private function _readfileChunked($filePath, $returnBytes = true)
96
+ {
97
+ $buffer = '';
98
+ $cnt = 0;
99
+ $handle = @fopen($filePath, 'rb');
100
+ if ($handle === false) {
101
+ return false;
102
+ }
103
+
104
+ while (!feof($handle)) {
105
+ $buffer = fread($handle, 8192);
106
+ echo $buffer;
107
+ ob_flush();
108
+ flush();
109
+ if ($returnBytes) {
110
+ $cnt += strlen($buffer);
111
+ }
112
+ }
113
+
114
+ $status = fclose($handle);
115
+ if ($returnBytes && $status) {
116
+ return $cnt;
117
+ }
118
+
119
+ return $status;
120
+ }
121
+ }
app/code/community/Bronto/Common/etc/adminhtml.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <admin>
6
+ <children>
7
+ <system>
8
+ <children>
9
+ <config>
10
+ <children>
11
+ <bronto module="bronto_common">
12
+ <title>Bronto General Section</title>
13
+ </bronto>
14
+ </children>
15
+ </config>
16
+ </children>
17
+ </system>
18
+ </children>
19
+ </admin>
20
+ </resources>
21
+ </acl>
22
+ </config>
app/code/community/Bronto/Common/etc/config.xml ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Bronto_Common>
5
+ <version>2.0.0</version>
6
+ </Bronto_Common>
7
+ </modules>
8
+ <global>
9
+ <blocks>
10
+ <bronto_common>
11
+ <class>Bronto_Common_Block</class>
12
+ </bronto_common>
13
+ </blocks>
14
+ <helpers>
15
+ <bronto_common>
16
+ <class>Bronto_Common_Helper</class>
17
+ </bronto_common>
18
+ </helpers>
19
+ <models>
20
+ <bronto_common>
21
+ <class>Bronto_Common_Model</class>
22
+ </bronto_common>
23
+ </models>
24
+ <resources>
25
+ <bronto_common_setup>
26
+ <setup>
27
+ <module>Bronto_Common</module>
28
+ <class>Bronto_Common_Model_Resource_Setup</class>
29
+ </setup>
30
+ <connection>
31
+ <use>core_setup</use>
32
+ </connection>
33
+ </bronto_common_setup>
34
+ </resources>
35
+ </global>
36
+ <frontend>
37
+ <routers>
38
+ <bronto_common>
39
+ <use>standard</use>
40
+ <args>
41
+ <module>Bronto_Common</module>
42
+ <frontName>bronto</frontName>
43
+ </args>
44
+ </bronto_common>
45
+ </routers>
46
+ </frontend>
47
+ <adminhtml>
48
+ <events>
49
+ <controller_action_predispatch>
50
+ <observers>
51
+ <bronto_common_controller_action_predispatch>
52
+ <class>bronto_common/observer</class>
53
+ <method>checkBrontoRequirements</method>
54
+ </bronto_common_controller_action_predispatch>
55
+ </observers>
56
+ </controller_action_predispatch>
57
+ </events>
58
+ <acl>
59
+ <resources>
60
+ <admin>
61
+ <children>
62
+ <system>
63
+ <children>
64
+ <config>
65
+ <children>
66
+ <bronto>
67
+ <title>Bronto General Section</title>
68
+ </bronto>
69
+ </children>
70
+ </config>
71
+ </children>
72
+ </system>
73
+ </children>
74
+ </admin>
75
+ </resources>
76
+ </acl>
77
+ </adminhtml>
78
+ <default>
79
+ <bronto>
80
+ <settings>
81
+ <debug>1</debug>
82
+ <verbose>0</verbose>
83
+ <test>0</test>
84
+ <notices>0</notices>
85
+ </settings>
86
+ </bronto>
87
+ </default>
88
+ <phpunit>
89
+ <suite>
90
+ <modules>
91
+ <Bronto_Common />
92
+ </modules>
93
+ </suite>
94
+ </phpunit>
95
+ </config>
app/code/community/Bronto/Common/etc/system.xml ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <tabs>
4
+ <bronto module="bronto_common">
5
+ <label>Bronto</label>
6
+ <sort_order>999</sort_order>
7
+ </bronto>
8
+ </tabs>
9
+ <sections>
10
+ <bronto module="bronto_common">
11
+ <label>General</label>
12
+ <tab>bronto</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
+ <about>
20
+ <frontend_type>text</frontend_type>
21
+ <frontend_model>bronto_common/adminhtml_system_config_about</frontend_model>
22
+ <sort_order>0</sort_order>
23
+ <show_in_default>1</show_in_default>
24
+ <show_in_website>1</show_in_website>
25
+ <show_in_store>1</show_in_store>
26
+ </about>
27
+ <settings>
28
+ <label>Settings</label>
29
+ <frontend_type>text</frontend_type>
30
+ <sort_order>1</sort_order>
31
+ <show_in_default>1</show_in_default>
32
+ <show_in_website>1</show_in_website>
33
+ <show_in_store>1</show_in_store>
34
+ <fields>
35
+ <api_token>
36
+ <label>API Token</label>
37
+ <frontend_type>text</frontend_type>
38
+ <frontend_model>bronto_common/adminhtml_system_config_form_field_apitoken</frontend_model>
39
+ <backend_model>bronto_common/system_config_backend_token</backend_model>
40
+ <sort_order>10</sort_order>
41
+ <show_in_default>1</show_in_default>
42
+ <show_in_website>1</show_in_website>
43
+ <show_in_store>0</show_in_store>
44
+ <validate>validate-length minimum-length-36</validate>
45
+ </api_token>
46
+ <debug>
47
+ <label>Debug</label>
48
+ <frontend_type>select</frontend_type>
49
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
50
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
51
+ <sort_order>20</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
+ <comment><![CDATA[Allow Bronto modules to write logs in <code>var/log</code>.]]></comment>
56
+ </debug>
57
+ <verbose>
58
+ <depends><debug>1</debug></depends>
59
+ <label>Verbose Log Output</label>
60
+ <frontend_type>select</frontend_type>
61
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
62
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
63
+ <sort_order>25</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
+ <comment><![CDATA[If enabled, debug logs will also contain each API call.]]></comment>
68
+ </verbose>
69
+ <test>
70
+ <label>Test Mode</label>
71
+ <frontend_type>select</frontend_type>
72
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
73
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
74
+ <sort_order>30</sort_order>
75
+ <show_in_default>1</show_in_default>
76
+ <show_in_website>1</show_in_website>
77
+ <show_in_store>1</show_in_store>
78
+ <comment><![CDATA[Email sent with <a href="http://community.bronto.com/api/v4/objects/general/deliveryobject" target="_blank"><code>type=test</code></a> only to existing Contacts.]]></comment>
79
+ </test>
80
+ <notices>
81
+ <label>Error Notices</label>
82
+ <frontend_type>select</frontend_type>
83
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
84
+ <source_model>adminhtml/system_config_source_enabledisable</source_model>
85
+ <sort_order>40</sort_order>
86
+ <show_in_default>1</show_in_default>
87
+ <show_in_website>1</show_in_website>
88
+ <show_in_store>1</show_in_store>
89
+ <comment>Show warnings/errors as site notices.</comment>
90
+ </notices>
91
+ </fields>
92
+ </settings>
93
+ </groups>
94
+ </bronto>
95
+ </sections>
96
+ </config>
app/code/community/Bronto/Common/sql/bronto_common_setup/mysql4-install-1.7.0.php ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Bronto_Common_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ $installer->handleOld();
9
+
10
+ $installer->endSetup();
app/code/community/Bronto/ConflictChecker/Block/Adminhtml/System/Config/About.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * About header for admin module config
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+
21
+ /**
22
+ * About header for admin module config
23
+ *
24
+ * @category Bronto
25
+ * @package ConflictChecker
26
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
27
+ * @copyright 2012 Atlantic BT
28
+ * @license http://www.atlanticbt.com/ Atlantic BT
29
+ * @version Release: @package_version@
30
+ * @link <>
31
+ * @see References to other sections (if any)...
32
+ */
33
+ class Bronto_ConflictChecker_Block_Adminhtml_System_Config_About
34
+ extends Bronto_Common_Block_Adminhtml_System_Config_About
35
+ {
36
+ // {{{ properties
37
+
38
+
39
+ /**
40
+ * Module name
41
+ * @var string
42
+ * @access protected
43
+ */
44
+ protected $_module = 'bronto_conflictchecker';
45
+
46
+ /**
47
+ * User descriptive module name
48
+ * @var string
49
+ * @access protected
50
+ */
51
+ protected $_name = 'Bronto Rewrite Conflict Checker Module';
52
+
53
+ // }}}
54
+ }
app/code/community/Bronto/ConflictChecker/Block/Adminhtml/System/Config/Conflictchecker.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Conflict checker
5
+ *
6
+ * This is the heart of the conflict checker that glues together and fires
7
+ * the Chain of responsibility
8
+ *
9
+ * PHP version 5
10
+ *
11
+ * The license text...
12
+ *
13
+ * @category Bronto
14
+ * @package ConflictChecker
15
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
16
+ * @copyright 2012 Atlantic BT
17
+ * @license http://www.atlanticbt.com/ Atlantic BT
18
+ * @version CVS: $Id:$
19
+ * @link <>
20
+ * @see References to other sections (if any)...
21
+ */
22
+
23
+ /**
24
+ * Conflict checker
25
+ *
26
+ * This is the heart of the conflict checker that glues together and fires
27
+ * the Chain of responsibility
28
+ *
29
+ * @category Bronto
30
+ * @package ConflictChecker
31
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
32
+ * @copyright 2012 Atlantic BT
33
+ * @license http://www.atlanticbt.com/ Atlantic BT
34
+ * @version Release: @package_version@
35
+ * @link <>
36
+ * @see References to other sections (if any)...
37
+ */
38
+ class Bronto_ConflictChecker_Block_Adminhtml_System_Config_Conflictchecker
39
+ extends Mage_Adminhtml_Block_Abstract
40
+ implements Varien_Data_Form_Element_Renderer_Interface
41
+ {
42
+ // {{{ properties
43
+
44
+
45
+ /**
46
+ * rewritten xml nodes
47
+ * @var array
48
+ * @access protected
49
+ */
50
+ protected $_rewrittenConfigs = array();
51
+
52
+ // }}}
53
+ // {{{ render()
54
+
55
+
56
+ /**
57
+ * Render all xml names that conflict
58
+ *
59
+ * @param Varien_Data_Form_Element_Abstract $element Form element
60
+ *
61
+ * @return string
62
+ * @access public
63
+ */
64
+ public function render(Varien_Data_Form_Element_Abstract $element)
65
+ {
66
+ $globalDataStore = Mage::getModel('bronto_conflictchecker/config_datastore');
67
+ Mage::register('conflict_datastore', $globalDataStore);
68
+ $config = Mage::getModel('bronto_conflictchecker/core_config');
69
+ $config->reinit();
70
+
71
+ // Chain of Responsibility
72
+ // each checker looks through its designated area for rewrites
73
+ $blocks = Mage::getModel('bronto_conflictchecker/config_blocks');
74
+ $models = Mage::getModel('bronto_conflictchecker/config_models', array($blocks));
75
+ $helpers = Mage::getModel('bronto_conflictchecker/config_helpers', array($models));
76
+ $resources = Mage::getModel('bronto_conflictchecker/config_resources', array($helpers));
77
+ $checker = Mage::getModel('bronto_conflictchecker/config_checker', array($resources));
78
+
79
+ $conflicts = $checker->getConflicts($config->getNode('frontend'));
80
+
81
+ $globalDataStore->getRewriteConflicts();
82
+
83
+ $printer = new Bronto_ConflictChecker_Model_Config_Printer();
84
+ return $printer->render($globalDataStore, 'XML configurations rewritten more than once');
85
+ }
86
+
87
+ // }}}
88
+ }
app/code/community/Bronto/ConflictChecker/Block/Printer.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Table generator
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Table generator
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Block_Printer
33
+ extends Mage_Adminhtml_Block_Template
34
+ {
35
+ // {{{ properties
36
+
37
+
38
+ /**
39
+ * Parity bit
40
+ * @var integer
41
+ * @access protected
42
+ */
43
+ protected $_i = 0;
44
+
45
+ // }}}
46
+ // {{{ _construct()
47
+
48
+
49
+ /**
50
+ * psuedo constructor
51
+ *
52
+ * @return void
53
+ * @access public
54
+ */
55
+ public function _construct()
56
+ {
57
+ parent::_construct();
58
+ $this->setTemplate('bronto/conflictchecker/errors.phtml');
59
+ }
60
+
61
+ // }}}
62
+ // {{{ getParity()
63
+
64
+
65
+ /**
66
+ * Get if even or ordd
67
+ *
68
+ * @return mixed Return description (if any) ...
69
+ * @access public
70
+ */
71
+ public function getParity()
72
+ {
73
+ return $this->_i++ % 2 ? 'even' : '';
74
+ }
75
+
76
+ // }}}
77
+ }
app/code/community/Bronto/ConflictChecker/Helper/Data.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper
5
+ *
6
+ * PHP versions 4 and 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Helper
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Helper_Data extends Bronto_Common_Helper_Data
33
+ {
34
+ }
app/code/community/Bronto/ConflictChecker/Model/Config/Blocks.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Block config checker
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Block config checker
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Model_Config_Blocks
33
+ extends Bronto_ConflictChecker_Model_Config_ConfigAbstract
34
+ {
35
+ // {{{ properties
36
+
37
+
38
+ /**
39
+ * Type of rewrite
40
+ * @var string
41
+ * @access protected
42
+ */
43
+ protected $_type = 'blocks';
44
+
45
+ // }}}
46
+ // {{{ getRewrites()
47
+
48
+
49
+ /**
50
+ * Check block section for rewrites
51
+ *
52
+ * @param Bronto_ConflictChecker_Model_Core_Config_Element $config Config node
53
+ * @param array $rewrites Existing rewrites
54
+ *
55
+ * @return array rewrites
56
+ * @access public
57
+ */
58
+ public function getRewrites(
59
+ Bronto_ConflictChecker_Model_Core_Config_Element $config,
60
+ $rewrites = array()
61
+ ) {
62
+ $blocks = $config->blocks;
63
+ $this->_findRewrites($blocks, $rewrites);
64
+
65
+ return parent::getRewrites($config, $rewrites);
66
+ }
67
+
68
+ // }}}
69
+ }
app/code/community/Bronto/ConflictChecker/Model/Config/Checker.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Conflict checker
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Conflict checker
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Model_Config_Checker
33
+ extends Bronto_ConflictChecker_Model_Config_ConfigAbstract
34
+ {
35
+ // {{{ getConflicts()
36
+
37
+
38
+ /**
39
+ * Get the conflicts
40
+ *
41
+ * @param Bronto_ConflictChecker_Model_Core_Config_Element $config Parameter description (if any) ...
42
+ *
43
+ * @return unknown Return description (if any) ...
44
+ * @access public
45
+ */
46
+ public function getConflicts(
47
+ Bronto_ConflictChecker_Model_Core_Config_Element $config
48
+ ) {
49
+ $rewrites = $this->getRewrites($config);
50
+ foreach ($rewrites as $type => $modules) {
51
+ foreach ($modules as $module => $classes) {
52
+ foreach ($classes as $class => $conflicts) {
53
+ if (count($classes[$class]) > 1) {
54
+ echo "$type : $module : $class is rewrite multiple times by";
55
+ var_dump($conflicts);
56
+ }
57
+ }
58
+ }
59
+ }
60
+ return $this->getRewrites($config);
61
+ }
62
+
63
+ // }}}
64
+ }
app/code/community/Bronto/ConflictChecker/Model/Config/ConfigAbstract.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Rewrite config checker
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Rewrite config checker
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ abstract class Bronto_ConflictChecker_Model_Config_ConfigAbstract
33
+ extends Mage_Core_Model_Abstract
34
+ implements Bronto_ConflictChecker_Model_Config_ConfigInterface
35
+ {
36
+ // {{{ properties
37
+
38
+
39
+ /**
40
+ * Chain of Responsibility link
41
+ * @var object
42
+ * @access protected
43
+ */
44
+ protected $_nextHandler = NULL;
45
+
46
+ // }}}
47
+ // {{{ _construct()
48
+
49
+
50
+ /**
51
+ * psuedo constructor
52
+ *
53
+ * If a handler is passed into the constructor then set it as the next link
54
+ *
55
+ * @return void
56
+ * @access public
57
+ */
58
+ public function _construct()
59
+ {
60
+ if (isset($this->_data[0])) {
61
+ $this->_nextHandler = $this->_data[0];
62
+ }
63
+ }
64
+
65
+ // }}}
66
+ // {{{ getRewrites()
67
+
68
+
69
+ /**
70
+ * Check if there are more handlers and if so get the rewrites from them
71
+
72
+ * @param Bronto_ConflictChecker_Model_Core_Config_Element $config XML node
73
+ * @param array $rewrites existing rewrites
74
+
75
+ * @return array rewrites
76
+ * @access public
77
+ */
78
+ public function getRewrites(
79
+ Bronto_ConflictChecker_Model_Core_Config_Element $config,
80
+ $rewrites = array()
81
+ ) {
82
+ if (!is_null($this->_nextHandler)) {
83
+ return $this->_nextHandler->getRewrites($config, $rewrites);
84
+ } else {
85
+ return $rewrites;
86
+ }
87
+ }
88
+
89
+ // }}}
90
+ // {{{ _findRewrites()
91
+
92
+
93
+ /**
94
+ * Find if XML node has any rewrites and if so append them into list
95
+ *
96
+ * @param Bronto_ConflictChecker_Model_Core_Config_Element $config XML Node
97
+ * @param array &$rewrites existing rewrites
98
+ *
99
+ * @return void
100
+ * @access protected
101
+ */
102
+ protected function _findRewrites(
103
+ Bronto_ConflictChecker_Model_Core_Config_Element $config,
104
+ &$rewrites = array()
105
+ ) {
106
+ $reflect = new ReflectionObject($config);
107
+ $props = $reflect->getProperties(ReflectionProperty::IS_PUBLIC);
108
+
109
+ foreach ($props as $prop) {
110
+ $module = $prop->getName();
111
+ $reflect = new ReflectionObject($config->$module);
112
+ if ($reflect->hasProperty('rewrite')) {
113
+ $rewrite = new ReflectionObject($config->$module->rewrite);
114
+ $properties = $rewrite->getProperties(ReflectionProperty::IS_PUBLIC);
115
+ foreach ($properties as $property) {
116
+ $class = $property->name;
117
+ $rewrites[$this->_type][$module][$class][]
118
+ = (string) $config->$module->rewrite->$class;
119
+ }
120
+ }
121
+ }
122
+ }
123
+
124
+ // }}}
125
+ }
app/code/community/Bronto/ConflictChecker/Model/Config/ConfigInterface.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Rewrite checker interface
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Rewrite checker interface
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ interface Bronto_ConflictChecker_Model_Config_ConfigInterface
33
+ {
34
+ // {{{ getRewrites()
35
+
36
+
37
+ /**
38
+ * find all rewrites on XML node elements
39
+ *
40
+ * @param Bronto_ConflictChecker_Model_Core_Config_Element $config XML node
41
+ * @access public
42
+ */
43
+ public function getRewrites(Bronto_ConflictChecker_Model_Core_Config_Element $config);
44
+
45
+ // }}}
46
+ }
app/code/community/Bronto/ConflictChecker/Model/Config/Datastore.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Short description for file
5
+ *
6
+ * Long description (if any) ...
7
+ *
8
+ * PHP version 5
9
+ *
10
+ * The license text...
11
+ *
12
+ * @category Bronto
13
+ * @package ConflictChecker
14
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
15
+ * @copyright 2012 Atlantic BT
16
+ * @license http://www.atlanticbt.com/ Atlantic BT
17
+ * @version CVS: $Id:$
18
+ * @link <>
19
+ * @see References to other sections (if any)...
20
+ */
21
+
22
+ /**
23
+ * Short description for class
24
+ *
25
+ * Long description (if any) ...
26
+ *
27
+ * @category Bronto
28
+ * @package ConflictChecker
29
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
30
+ * @copyright 2012 Atlantic BT
31
+ * @license http://www.atlanticbt.com/ Atlantic BT
32
+ * @version Release: @package_version@
33
+ * @link <>
34
+ * @see References to other sections (if any)...
35
+ */
36
+ class Bronto_ConflictChecker_Model_Config_Datastore
37
+ extends Mage_Core_Model_Abstract
38
+ {
39
+ // {{{ properties
40
+
41
+
42
+ /**
43
+ * data store
44
+ * @var array
45
+ * @access protected
46
+ */
47
+ protected $_store = array();
48
+
49
+ // }}}
50
+ // {{{ addRewrite()
51
+
52
+
53
+ /**
54
+ * store rewrite
55
+ *
56
+ * @param string $oldValue node name being overwritten
57
+ * @param string $newValue node name that is being set to current
58
+ * @param string|null $configFile (optional) Config file with rewrite
59
+ * @param string|null $path (optional) path to node in XML
60
+ *
61
+ * @return void
62
+ * @access public
63
+ */
64
+ public function addRewrite(
65
+ $oldValue,
66
+ $newValue,
67
+ $configFile = 'Unavailable',
68
+ $path = 'Unavailable'
69
+ ) {
70
+ if ('Unavailable' != $configFile) {
71
+ // +1 just removes the starting '/' from the path
72
+ $configFile = substr($configFile, strlen(Mage::getBaseDir()) + 1, strlen($configFile));
73
+ }
74
+ $this->_store[] = array(
75
+ 'oldValue' => $oldValue,
76
+ 'newValue' => $newValue,
77
+ 'file' => $configFile,
78
+ 'path' => $path
79
+ );
80
+ }
81
+
82
+ // }}}
83
+ // {{{ getRewriteConflicts()
84
+
85
+
86
+ /**
87
+ * Get the datastore
88
+ *
89
+ * @return array
90
+ * @access public
91
+ */
92
+ public function getRewriteConflicts()
93
+ {
94
+ return $this->_store;
95
+ }
96
+
97
+ // }}}
98
+ }
app/code/community/Bronto/ConflictChecker/Model/Config/Helpers.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper config checker
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Helper config checker
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Model_Config_Helpers
33
+ extends Bronto_ConflictChecker_Model_Config_ConfigAbstract
34
+ {
35
+ // {{{ properties
36
+
37
+
38
+ /**
39
+ * Type of rewrite
40
+ * @var string
41
+ * @access protected
42
+ */
43
+ protected $_type = 'helpers';
44
+
45
+ // }}}
46
+ // {{{ getRewrites()
47
+
48
+
49
+ /**
50
+ * Check helper section for rewrites
51
+ *
52
+ * @param Bronto_ConflictChecker_Model_Core_Config_Element $config Config node
53
+ * @param array $rewrites Existing rewrites
54
+ *
55
+ * @return array rewrites
56
+ * @access public
57
+ */
58
+ public function getRewrites(
59
+ Bronto_ConflictChecker_Model_Core_Config_Element $config,
60
+ $rewrites = array()
61
+ ) {
62
+ $helpers = $config->helpers;
63
+ $this->_findRewrites($helpers, $rewrites);
64
+
65
+ return parent::getRewrites($config, $rewrites);
66
+ }
67
+
68
+ // }}}
69
+ }
app/code/community/Bronto/ConflictChecker/Model/Config/Models.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Model config checker
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Model config checker
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Model_Config_Models
33
+ extends Bronto_ConflictChecker_Model_Config_ConfigAbstract
34
+ {
35
+ // {{{ properties
36
+
37
+
38
+ /**
39
+ * Type of rewrite
40
+ * @var string
41
+ * @access protected
42
+ */
43
+ protected $_type = 'models';
44
+
45
+ // }}}
46
+ // {{{ getRewrites()
47
+
48
+ /**
49
+ * Check models section for rewrites
50
+ *
51
+ * @param Bronto_ConflictChecker_Model_Core_Config_Element $config Config node
52
+ * @param array $rewrites Existing rewrites
53
+ *
54
+ * @return array rewrites
55
+ * @access public
56
+ */
57
+ public function getRewrites(
58
+ Bronto_ConflictChecker_Model_Core_Config_Element $config,
59
+ $rewrites = array()
60
+ ) {
61
+ $models = $config->models;
62
+ $this->_findRewrites($models, $rewrites);
63
+
64
+ return parent::getRewrites($config, $rewrites);
65
+ }
66
+
67
+ // }}}
68
+ }
app/code/community/Bronto/ConflictChecker/Model/Config/Printer.php ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Datastore printer
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Datastore printer
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Model_Config_Printer
33
+ {
34
+ // {{{ render()
35
+
36
+
37
+ /**
38
+ * Rewrite printer
39
+ *
40
+ * @param Bronto_ConflictChecker_Model_Config_Datastore $datastore Datastore to print from
41
+ * @param string $title Title to print
42
+
43
+ * @return string
44
+ * @access public
45
+ */
46
+ public function render(
47
+ Bronto_ConflictChecker_Model_Config_Datastore $datastore,
48
+ $title
49
+ ) {
50
+ $block = Mage::app()->getLayout()->createBlock('bronto_conflictchecker/printer');
51
+ $block->setRewrites($datastore->getRewriteConflicts());
52
+ $block->setTitle($title);
53
+
54
+ return $block->toHtml();
55
+ }
56
+
57
+ // }}}
58
+ }
app/code/community/Bronto/ConflictChecker/Model/Config/Resources.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Helper config checker
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Helper config checker
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Model_Config_Resources
33
+ extends Bronto_ConflictChecker_Model_Config_ConfigAbstract
34
+ {
35
+ // {{{ properties
36
+
37
+
38
+ /**
39
+ * Type of rewrite
40
+ * @var string
41
+ * @access protected
42
+ */
43
+ protected $_type = 'resources';
44
+
45
+ // }}}
46
+ // {{{ getRewrites()
47
+
48
+
49
+ /**
50
+ * Check resources section for rewrites
51
+ *
52
+ * @param Bronto_ConflictChecker_Model_Core_Config_Element $config Config node
53
+ * @param array $rewrites Existing rewrites
54
+ *
55
+ * @return array rewrites
56
+ * @access public
57
+ */
58
+ public function getRewrites(
59
+ Bronto_ConflictChecker_Model_Core_Config_Element $config,
60
+ $rewrites = array()
61
+ ) {
62
+ $resources = $config->resources;
63
+ $this->_findRewrites($resources, $rewrites);
64
+
65
+ return parent::getRewrites($config, $rewrites);
66
+ }
67
+
68
+ // }}}
69
+ }
app/code/community/Bronto/ConflictChecker/Model/Core/Config.php ADDED
@@ -0,0 +1,2024 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Short description for file
5
+ *
6
+ * Long description (if any) ...
7
+ *
8
+ * PHP version 5
9
+ *
10
+ * The license text...
11
+ *
12
+ * @category Bronto
13
+ * @package ConflictChecker
14
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
15
+ * @copyright 2012 Atlantic BT
16
+ * @license http://www.atlanticbt.com/ Atlantic BT
17
+ * @version CVS: $Id:$
18
+ * @link <>
19
+ * @see References to other sections (if any)...
20
+ */
21
+
22
+ /**
23
+ * Short description for class
24
+ *
25
+ * Long description (if any) ...
26
+ *
27
+ * @category Bronto
28
+ * @package ConflictChecker
29
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
30
+ * @copyright 2012 Atlantic BT
31
+ * @license http://www.atlanticbt.com/ Atlantic BT
32
+ * @version Release: @package_version@
33
+ * @link <>
34
+ * @see References to other sections (if any)...
35
+ */
36
+ class Bronto_ConflictChecker_Model_Core_Config
37
+ extends Bronto_ConflictChecker_Model_Core_Config_Base
38
+ {
39
+ // {{{ properties
40
+
41
+
42
+ /**
43
+ * Description for const
44
+ */
45
+ const CACHE_TAG = 'CONFIG';
46
+
47
+ /**
48
+ * Flag which allow use cache logic
49
+ *
50
+ * @var bool
51
+ * @access protected
52
+ */
53
+ protected $_useCache = false;
54
+
55
+ /**
56
+ * Instructions for spitting config cache
57
+ * array(
58
+ * $sectionName => $recursionLevel
59
+ * )
60
+ * Recursion level provide availability cache subnodes separatly
61
+ *
62
+ * @var array
63
+ * @access protected
64
+ */
65
+ protected $_cacheSections = array(
66
+ 'admin' => 0,
67
+ 'adminhtml' => 0,
68
+ 'crontab' => 0,
69
+ 'install' => 0,
70
+ 'stores' => 1,
71
+ 'websites' => 0
72
+ );
73
+
74
+ /**
75
+ * Loaded Configuration by cached sections
76
+ *
77
+ * @var array
78
+ * @access protected
79
+ */
80
+ protected $_cacheLoadedSections = array();
81
+
82
+ /**
83
+ * Configuration options
84
+ *
85
+ * @var Mage_Core_Model_Config_Options
86
+ * @access protected
87
+ */
88
+ protected $_options;
89
+
90
+ /**
91
+ * Storage for generated class names
92
+ *
93
+ * @var array
94
+ * @access protected
95
+ */
96
+ protected $_classNameCache = array();
97
+
98
+ /**
99
+ * Storage for generated block class names
100
+ *
101
+ * @var unknown_type
102
+ * @access protected
103
+ */
104
+ protected $_blockClassNameCache = array();
105
+
106
+ /**
107
+ * Storage of validated secure urls
108
+ *
109
+ * @var array
110
+ * @access protected
111
+ */
112
+ protected $_secureUrlCache = array();
113
+
114
+ /**
115
+ * System environment server variables
116
+ *
117
+ * @var array
118
+ * @access protected
119
+ */
120
+ protected $_distroServerVars;
121
+
122
+ /**
123
+ * Array which is using for replace placeholders of server variables
124
+ *
125
+ * @var array
126
+ * @access protected
127
+ */
128
+ protected $_substServerVars;
129
+
130
+ /**
131
+ * Resource model
132
+ * Used for operations with DB
133
+ *
134
+ * @var Mage_Core_Model_Mysql4_Config
135
+ * @access protected
136
+ */
137
+ protected $_resourceModel;
138
+
139
+ /**
140
+ * Configuration for events by area
141
+ *
142
+ * @var array
143
+ * @access protected
144
+ */
145
+ protected $_eventAreas;
146
+
147
+ /**
148
+ * Flag cache for existing or already created directories
149
+ *
150
+ * @var array
151
+ * @access protected
152
+ */
153
+ protected $_dirExists = array();
154
+
155
+ /**
156
+ * Flach which allow using cache for config initialization
157
+ *
158
+ * @var bool
159
+ * @access protected
160
+ */
161
+ protected $_allowCacheForInit = true;
162
+
163
+ /**
164
+ * Property used during cache save process
165
+ *
166
+ * @var array
167
+ * @access protected
168
+ */
169
+ protected $_cachePartsForSave = array();
170
+
171
+ /**
172
+ * Empty configuration object for loading and megring configuration parts
173
+ *
174
+ * @var Mage_Core_Model_Config_Base
175
+ * @access protected
176
+ */
177
+ protected $_prototype;
178
+
179
+ /**
180
+ * Flag which identify what local configuration is loaded
181
+ *
182
+ * @var bool
183
+ * @access protected
184
+ */
185
+ protected $_isLocalConfigLoaded = false;
186
+
187
+ /**
188
+ * Depricated properties
189
+ *
190
+ * @deprecated
191
+ * @access protected
192
+ */
193
+ protected $_baseDirCache = array();
194
+
195
+ /**
196
+ * Description for protected
197
+ * @var unknown
198
+ * @access protected
199
+ */
200
+ protected $_customEtcDir = null;
201
+
202
+ /**
203
+ * Flag which allow to use modules from local code pool
204
+ *
205
+ * @var bool
206
+ * @access protected
207
+ */
208
+ protected $_canUseLocalModules = null;
209
+
210
+ /**
211
+ * Active modules array per namespace
212
+ * @var array
213
+ * @access private
214
+ */
215
+ private $_moduleNamespaces = null;
216
+
217
+ /**
218
+ * Modules allowed to load
219
+ * If empty - all modules are allowed
220
+ *
221
+ * @var array
222
+ * @access protected
223
+ */
224
+ protected $_allowedModules = array();
225
+
226
+ // }}}
227
+ // {{{ __construct
228
+
229
+ /**
230
+ * Class construct
231
+ *
232
+ * @param mixed $sourceData
233
+ *
234
+ * @return void
235
+ * @access public
236
+ */
237
+ public function __construct($sourceData=null)
238
+ {
239
+ $this->setCacheId('config_global');
240
+ $this->_options = new Mage_Core_Model_Config_Options($sourceData);
241
+ $this->_prototype = new Bronto_ConflictChecker_Model_Core_Config_Base();
242
+ $this->_cacheChecksum = null;
243
+ parent::__construct($sourceData);
244
+ }
245
+
246
+ // }}}
247
+ // {{{ getResourceModel()
248
+
249
+ /**
250
+ * Get config resource model
251
+ *
252
+ * @return Mage_Core_Store_Mysql4_Config
253
+ * @access public
254
+ */
255
+ public function getResourceModel()
256
+ {
257
+ if (is_null($this->_resourceModel)) {
258
+ $this->_resourceModel = Mage::getResourceModel('bronto_conflictchecker/core_config');
259
+ }
260
+ return $this->_resourceModel;
261
+ }
262
+
263
+ // }}}
264
+ // {{{ getOptions()
265
+
266
+ /**
267
+ * Get configuration options object
268
+ *
269
+ * @return Mage_Core_Model_Config_Options
270
+ * @access public
271
+ */
272
+ public function getOptions()
273
+ {
274
+ return $this->_options;
275
+ }
276
+
277
+ // }}}
278
+ // {{{ setOptions()
279
+
280
+ /**
281
+ * Set configuration options
282
+ *
283
+ * @param array $options
284
+ *
285
+ * @return Mage_Core_Model_Config
286
+ * @access public
287
+ */
288
+ public function setOptions($options)
289
+ {
290
+ if (is_array($options)) {
291
+ $this->getOptions()->addData($options);
292
+ }
293
+ return $this;
294
+ }
295
+
296
+ // }}}
297
+ // {{{ init()
298
+
299
+ /**
300
+ * Initialization of core configuration
301
+ *
302
+ * @return Mage_Core_Model_Config
303
+ * @access public
304
+ */
305
+ public function init($options=array())
306
+ {
307
+ $this->setCacheChecksum(null);
308
+ $this->_cacheLoadedSections = array();
309
+ $this->setOptions($options);
310
+ $this->loadBase();
311
+
312
+ $cacheLoad = $this->loadModulesCache();
313
+ if ($cacheLoad) {
314
+ return $this;
315
+ }
316
+ $this->loadModules();
317
+ $this->loadDb();
318
+ $this->saveCache();
319
+ return $this;
320
+ }
321
+
322
+ // }}}
323
+ // {{{ loadBase()
324
+
325
+ /**
326
+ * Load base system configuration (config.xml and local.xml files)
327
+ *
328
+ * @return Mage_Core_Model_Config
329
+ * @access public
330
+ */
331
+ public function loadBase()
332
+ {
333
+ $etcDir = $this->getOptions()->getEtcDir();
334
+ $files = glob($etcDir.DS.'*.xml');
335
+ $this->loadFile(current($files));
336
+ while ($file = next($files)) {
337
+ $merge = clone $this->_prototype;
338
+ $merge->loadFile($file);
339
+ $this->extend($merge);
340
+ }
341
+ if (in_array($etcDir.DS.'local.xml', $files)) {
342
+ $this->_isLocalConfigLoaded = true;
343
+ }
344
+ return $this;
345
+ }
346
+
347
+ // }}}
348
+ // {{{ loadModulesCache()
349
+
350
+ /**
351
+ * Load cached modules configuration
352
+ *
353
+ * @return bool
354
+ * @access public
355
+ */
356
+ public function loadModulesCache()
357
+ {
358
+ if (Mage::isInstalled(array('etc_dir' => $this->getOptions()->getEtcDir()))) {
359
+ if ($this->_canUseCacheForInit()) {
360
+ Varien_Profiler::start('mage::app::init::config::load_cache');
361
+ $loaded = $this->loadCache();
362
+ Varien_Profiler::stop('mage::app::init::config::load_cache');
363
+ if ($loaded) {
364
+ $this->_useCache = true;
365
+ return true;
366
+ }
367
+ }
368
+ }
369
+ return false;
370
+ }
371
+
372
+ // }}}
373
+ // {{{ loadModules()
374
+
375
+ /**
376
+ * Load modules configuration
377
+ *
378
+ * @return Mage_Core_Model_Config
379
+ * @access public
380
+ */
381
+ public function loadModules()
382
+ {
383
+ Varien_Profiler::start('config/load-modules');
384
+ $this->_loadDeclaredModules();
385
+
386
+ $resourceConfig = sprintf('config.%s.xml', $this->_getResourceConnectionModel('core'));
387
+ $mergeToObject = Mage::getModel('bronto_conflictchecker/core_config_base');
388
+ $mergeToObject->setXml($this->getNode());
389
+ $this->loadModulesConfiguration(array('config.xml',$resourceConfig), $mergeToObject);
390
+
391
+ /**
392
+ * Prevent local.xml directives overwriting
393
+ */
394
+ $mergeConfig = clone $this->_prototype;
395
+ $this->_isLocalConfigLoaded = $mergeConfig->loadFile($this->getOptions()->getEtcDir().DS.'local.xml');
396
+ if ($this->_isLocalConfigLoaded) {
397
+ $this->extend($mergeConfig);
398
+ }
399
+
400
+ $this->applyExtends();
401
+ Varien_Profiler::stop('config/load-modules');
402
+ return $this;
403
+ }
404
+
405
+ // }}}
406
+ // {{{ isLocalConfigLoaded()
407
+
408
+ /**
409
+ * Check if local configuration (DB connection, etc) is loaded
410
+ *
411
+ * @return bool
412
+ * @access public
413
+ */
414
+ public function isLocalConfigLoaded()
415
+ {
416
+ return $this->_isLocalConfigLoaded;
417
+ }
418
+
419
+ // }}}
420
+ // {{{ loadDb()
421
+
422
+ /**
423
+ * Load config data from DB
424
+ *
425
+ * @return Mage_Core_Model_Config
426
+ * @access public
427
+ */
428
+ public function loadDb()
429
+ {
430
+ if ($this->_isLocalConfigLoaded && Mage::isInstalled()) {
431
+ Varien_Profiler::start('config/load-db');
432
+ $dbConf = $this->getResourceModel();
433
+ $dbConf->loadToXml($this);
434
+ Varien_Profiler::stop('config/load-db');
435
+ }
436
+ return $this;
437
+ }
438
+
439
+ // }}}
440
+ // {{{ reinit()
441
+
442
+ /**
443
+ * Reinitialize configuration
444
+ *
445
+ * @param array $options
446
+ *
447
+ * @return Mage_Core_Model_Config
448
+ * @access public
449
+ */
450
+ public function reinit($options = array())
451
+ {
452
+ $this->_allowCacheForInit = false;
453
+ $this->_useCache = false;
454
+ return $this->init($options);
455
+ }
456
+
457
+ // }}}
458
+ // {{{ _canUseLocalModules()
459
+
460
+ /**
461
+ * Check local modules enable/disable flag
462
+ * If local modules are disbled remove local modules path from include dirs
463
+ *
464
+ * @return bool return true if local modules enabled and false if disabled
465
+ * @access protected
466
+ */
467
+ protected function _canUseLocalModules()
468
+ {
469
+ if ($this->_canUseLocalModules !== null) {
470
+ return $this->_canUseLocalModules;
471
+ }
472
+
473
+ $disableLocalModules = (string)$this->getNode('global/disable_local_modules');
474
+ if (!empty($disableLocalModules)) {
475
+ $disableLocalModules = (('true' === $disableLocalModules) || ('1' === $disableLocalModules));
476
+ } else {
477
+ $disableLocalModules = false;
478
+ }
479
+
480
+ if ($disableLocalModules && !defined('COMPILER_INCLUDE_PATH')) {
481
+ set_include_path(
482
+ // excluded '/app/code/local'
483
+ BP . DS . 'app' . DS . 'code' . DS . 'community' . PS .
484
+ BP . DS . 'app' . DS . 'code' . DS . 'core' . PS .
485
+ BP . DS . 'lib' . PS .
486
+ Mage::registry('original_include_path')
487
+ );
488
+ }
489
+ $this->_canUseLocalModules = !$disableLocalModules;
490
+ return $this->_canUseLocalModules;
491
+ }
492
+
493
+ // }}}
494
+ // {{{ _canUseCacheForInit()
495
+
496
+ /**
497
+ * Check if cache can be used for config initialization
498
+ *
499
+ * @return bool
500
+ * @access protected
501
+ */
502
+ protected function _canUseCacheForInit()
503
+ {
504
+ return Mage::app()->useCache('config') && $this->_allowCacheForInit
505
+ && !$this->_loadCache($this->_getCacheLockId());
506
+ }
507
+
508
+ // }}}
509
+ // {{{ getCache()
510
+
511
+ /**
512
+ * Retrieve cache object
513
+ *
514
+ * @return Zend_Cache_Frontend_File
515
+ * @access public
516
+ */
517
+ public function getCache()
518
+ {
519
+ return Mage::app()->getCache();
520
+ }
521
+
522
+ // }}}
523
+ // {{{ _getCacheLockId()
524
+
525
+ /**
526
+ * Get lock flag cache identifier
527
+ *
528
+ * @return string
529
+ * @access protected
530
+ */
531
+ protected function _getCacheLockId()
532
+ {
533
+ return $this->getCacheId().'.lock';
534
+ }
535
+
536
+ // }}}
537
+ // {{{ saveCache()
538
+
539
+ /**
540
+ * Save configuration cache
541
+ *
542
+ * @param array $tags cache tags
543
+ *
544
+ * @return Mage_Core_Model_Config
545
+ * @access public
546
+ */
547
+ public function saveCache($tags=array())
548
+ {
549
+ if (!Mage::app()->useCache('config')) {
550
+ return $this;
551
+ }
552
+ if (!in_array(self::CACHE_TAG, $tags)) {
553
+ $tags[] = self::CACHE_TAG;
554
+ }
555
+ $cacheLockId = $this->_getCacheLockId();
556
+ if ($this->_loadCache($cacheLockId)) {
557
+ return $this;
558
+ }
559
+
560
+ if (!empty($this->_cacheSections)) {
561
+ $xml = clone $this->_xml;
562
+ foreach ($this->_cacheSections as $sectionName => $level) {
563
+ $this->_saveSectionCache($this->getCacheId(), $sectionName, $xml, $level, $tags);
564
+ unset($xml->$sectionName);
565
+ }
566
+ $this->_cachePartsForSave[$this->getCacheId()] = $xml->asNiceXml('', false);
567
+ } else {
568
+ return parent::saveCache($tags);
569
+ }
570
+
571
+ $this->_saveCache(time(), $cacheLockId, array(), 60);
572
+ $this->removeCache();
573
+ foreach ($this->_cachePartsForSave as $cacheId => $cacheData) {
574
+ $this->_saveCache($cacheData, $cacheId, $tags, $this->getCacheLifetime());
575
+ }
576
+ unset($this->_cachePartsForSave);
577
+ $this->_removeCache($cacheLockId);
578
+ return $this;
579
+ }
580
+
581
+ // }}}
582
+ // {{{ _saveSectionCache()
583
+
584
+ /**
585
+ * Save cache of specified
586
+ *
587
+ * @param string $idPrefix cache id prefix
588
+ * @param string $sectionName
589
+ * @param Varien_Simplexml_Element $source
590
+ * @param int $recursionLevel
591
+ *
592
+ * @return Mage_Core_Model_Config
593
+ * @access protected
594
+ */
595
+ protected function _saveSectionCache($idPrefix, $sectionName, $source, $recursionLevel=0, $tags=array())
596
+ {
597
+ if ($source && $source->$sectionName) {
598
+ $cacheId = $idPrefix . '_' . $sectionName;
599
+ if ($recursionLevel > 0) {
600
+ foreach ($source->$sectionName->children() as $subSectionName => $node) {
601
+ $this->_saveSectionCache(
602
+ $cacheId, $subSectionName, $source->$sectionName, $recursionLevel-1, $tags
603
+ );
604
+ }
605
+ }
606
+ $this->_cachePartsForSave[$cacheId] = $source->$sectionName->asNiceXml('', false);
607
+ }
608
+ return $this;
609
+ }
610
+
611
+ // }}}
612
+ // {{{ _loadSectionCache()
613
+
614
+ /**
615
+ * Load config section cached data
616
+ *
617
+ * @param string $sectionName
618
+ *
619
+ * @return Varien_Simplexml_Element
620
+ * @access protected
621
+ */
622
+ protected function _loadSectionCache($sectionName)
623
+ {
624
+ $cacheId = $this->getCacheId() . '_' . $sectionName;
625
+ $xmlString = $this->_loadCache($cacheId);
626
+
627
+ /**
628
+ * If we can't load section cache (problems with cache storage)
629
+ */
630
+ if (!$xmlString) {
631
+ $this->_useCache = false;
632
+ $this->reinit($this->_options);
633
+ return false;
634
+ } else {
635
+ $xml = simplexml_load_string($xmlString, $this->_elementClass);
636
+ return $xml;
637
+ }
638
+ }
639
+
640
+ // }}}
641
+ // {{{ _loadCache()
642
+
643
+ /**
644
+ * Load cached data by identifier
645
+ *
646
+ * @param string $id
647
+ *
648
+ * @return string
649
+ * @access protected
650
+ */
651
+ protected function _loadCache($id)
652
+ {
653
+ return Mage::app()->loadCache($id);
654
+ }
655
+
656
+ // }}}
657
+ // {{{ _saveCache()
658
+
659
+ /**
660
+ * Save cache data
661
+ *
662
+ * @param string $data
663
+ * @param string $id
664
+ * @param array $tags
665
+ * @param false|int $lifetime
666
+ *
667
+ * @return Mage_Core_Model_Config
668
+ * @access protected
669
+ */
670
+ protected function _saveCache($data, $id, $tags=array(), $lifetime=false)
671
+ {
672
+ return Mage::app()->saveCache($data, $id, $tags, $lifetime);
673
+ }
674
+
675
+ // }}}
676
+ // {{{ _removeCache()
677
+
678
+ /**
679
+ * Clear cache data by id
680
+ *
681
+ * @param string $id
682
+ *
683
+ * @return Mage_Core_Model_Config
684
+ * @access protected
685
+ */
686
+ protected function _removeCache($id)
687
+ {
688
+ return Mage::app()->removeCache($id);
689
+ }
690
+
691
+ // }}}
692
+ // {{{ removeCache()
693
+
694
+ /**
695
+ * Remove configuration cache
696
+ *
697
+ * @return Mage_Core_Model_Config
698
+ * @access public
699
+ */
700
+ public function removeCache()
701
+ {
702
+ Mage::app()->cleanCache(array(self::CACHE_TAG));
703
+ return parent::removeCache();
704
+ }
705
+
706
+ // }}}
707
+ // {{{ cleanCache()
708
+
709
+ /**
710
+ * Configuration cache clean process
711
+ *
712
+ * @return Mage_Core_Model_Config
713
+ * @access public
714
+ */
715
+ public function cleanCache()
716
+ {
717
+ return $this->reinit();
718
+ }
719
+
720
+ // }}}
721
+ // {{{ _getSectionConfig()
722
+
723
+ /**
724
+ * Getter for section configuration object
725
+ *
726
+ * @param array $path
727
+ *
728
+ * @return Mage_Core_Model_Config_Element
729
+ * @access protected
730
+ */
731
+ protected function _getSectionConfig($path)
732
+ {
733
+ $section = $path[0];
734
+ if (!isset($this->_cacheSections[$section])) {
735
+ return false;
736
+ }
737
+ $sectioPath = array_slice($path, 0, $this->_cacheSections[$section]+1);
738
+ $sectionKey = implode('_', $sectioPath);
739
+
740
+ if (!isset($this->_cacheLoadedSections[$sectionKey])) {
741
+ Varien_Profiler::start('init_config_section:' . $sectionKey);
742
+ $this->_cacheLoadedSections[$sectionKey] = $this->_loadSectionCache($sectionKey);
743
+ Varien_Profiler::stop('init_config_section:' . $sectionKey);
744
+ }
745
+
746
+ if ($this->_cacheLoadedSections[$sectionKey] === false) {
747
+ return false;
748
+ }
749
+ return $this->_cacheLoadedSections[$sectionKey];
750
+ }
751
+
752
+ // }}}
753
+ // {{{ getSectionNode()
754
+
755
+ /**
756
+ * Get node value from cached section data
757
+ *
758
+ * @param array $path
759
+ *
760
+ * @return Mage_Core_Model_Config
761
+ * @access public
762
+ */
763
+ public function getSectionNode($path)
764
+ {
765
+ $section = $path[0];
766
+ $config = $this->_getSectionConfig($path);
767
+ $path = array_slice($path, $this->_cacheSections[$section]+1);
768
+ if ($config) {
769
+ return $config->descend($path);
770
+ }
771
+ return false;
772
+ }
773
+
774
+ // }}}
775
+ // {{{ getNode()
776
+
777
+ /**
778
+ * Returns node found by the $path and scope info
779
+ *
780
+ * @param string $path
781
+ * @param string $scope
782
+ * @param string $scopeCode
783
+ *
784
+ * @return Mage_Core_Model_Config_Element
785
+ * @access public
786
+ */
787
+ public function getNode($path=null, $scope='', $scopeCode=null)
788
+ {
789
+ if ($scope !== '') {
790
+ if (('store' === $scope) || ('website' === $scope)) {
791
+ $scope .= 's';
792
+ }
793
+ if (('default' !== $scope) && is_int($scopeCode)) {
794
+ if ('stores' == $scope) {
795
+ $scopeCode = Mage::app()->getStore($scopeCode)->getCode();
796
+ } elseif ('websites' == $scope) {
797
+ $scopeCode = Mage::app()->getWebsite($scopeCode)->getCode();
798
+ } else {
799
+ Mage::throwException(Mage::helper('core')->__('Unknown scope "%s".', $scope));
800
+ }
801
+ }
802
+ $path = $scope . ($scopeCode ? '/' . $scopeCode : '' ) . (empty($path) ? '' : '/' . $path);
803
+ }
804
+
805
+ /**
806
+ * Check path cache loading
807
+ */
808
+ if ($this->_useCache && ($path !== null)) {
809
+ $path = explode('/', $path);
810
+ $section= $path[0];
811
+ if (isset($this->_cacheSections[$section])) {
812
+ $res = $this->getSectionNode($path);
813
+ if ($res !== false) {
814
+ return $res;
815
+ }
816
+ }
817
+ }
818
+ return parent::getNode($path);
819
+ }
820
+
821
+ // }}}
822
+ // {{{ setNode()
823
+
824
+ /**
825
+ * Create node by $path and set its value.
826
+ *
827
+ * @param string $path separated by slashes
828
+ * @param string $value
829
+ * @param bool $overwrite
830
+ *
831
+ * @return Varien_Simplexml_Config
832
+ * @access public
833
+ */
834
+ public function setNode($path, $value, $overwrite = true)
835
+ {
836
+ if ($this->_useCache && ($path !== null)) {
837
+ $sectionPath = explode('/', $path);
838
+ $config = $this->_getSectionConfig($sectionPath);
839
+ if ($config) {
840
+ $sectionPath = array_slice($sectionPath, $this->_cacheSections[$sectionPath[0]]+1);
841
+ $sectionPath = implode('/', $sectionPath);
842
+ $config->setNode($sectionPath, $value, $overwrite);
843
+ }
844
+ }
845
+ return parent::setNode($path, $value, $overwrite);
846
+ }
847
+
848
+ // }}}
849
+ // {{{ _getDeclaredModuleFiles()
850
+
851
+ /**
852
+ * Retrive Declared Module file list
853
+ *
854
+ * @return array
855
+ * @access protected
856
+ */
857
+ protected function _getDeclaredModuleFiles()
858
+ {
859
+ $etcDir = $this->getOptions()->getEtcDir();
860
+ $moduleFiles = glob($etcDir . DS . 'modules' . DS . '*.xml');
861
+
862
+ if (!$moduleFiles) {
863
+ return false;
864
+ }
865
+
866
+ $collectModuleFiles = array(
867
+ 'base' => array(),
868
+ 'mage' => array(),
869
+ 'custom' => array()
870
+ );
871
+
872
+ foreach ($moduleFiles as $v) {
873
+ $name = explode(DIRECTORY_SEPARATOR, $v);
874
+ $name = substr($name[count($name) - 1], 0, -4);
875
+
876
+ if ($name == 'Mage_All') {
877
+ $collectModuleFiles['base'][] = $v;
878
+ } else if (substr($name, 0, 5) == 'Mage_') {
879
+ $collectModuleFiles['mage'][] = $v;
880
+ } else {
881
+ $collectModuleFiles['custom'][] = $v;
882
+ }
883
+ }
884
+
885
+ return array_merge(
886
+ $collectModuleFiles['base'],
887
+ $collectModuleFiles['mage'],
888
+ $collectModuleFiles['custom']
889
+ );
890
+ }
891
+
892
+ // }}}
893
+ // {{{ addAllowedModules()
894
+
895
+ /**
896
+ * Add module(s) to allowed list
897
+ *
898
+ * @param strung|array $module
899
+ *
900
+ * @return Mage_Core_Model_Config
901
+ * @access public
902
+ */
903
+ public function addAllowedModules($module)
904
+ {
905
+ if (is_array($module)) {
906
+ foreach ($module as $moduleName) {
907
+ $this->addAllowedModules($moduleName);
908
+ }
909
+ } elseif (!in_array($module, $this->_allowedModules)) {
910
+ $this->_allowedModules[] = $module;
911
+ }
912
+
913
+ return $this;
914
+ }
915
+
916
+ // }}}
917
+ // {{{ _isAllowedModule()
918
+
919
+ /**
920
+ * Define if module is allowed
921
+ *
922
+ * @param string $moduleName
923
+ *
924
+ * @return bool
925
+ * @access protected
926
+ */
927
+ protected function _isAllowedModule($moduleName)
928
+ {
929
+ if (empty($this->_allowedModules)) {
930
+ return true;
931
+ } else {
932
+ return in_array($moduleName, $this->_allowedModules);
933
+ }
934
+ }
935
+
936
+ // }}}
937
+ // {{{ _loadDeclaredModules()
938
+
939
+ /**
940
+ * Load declared modules configuration
941
+ *
942
+ * @param null $mergeConfig depricated
943
+ *
944
+ * @return Mage_Core_Model_Config
945
+ * @access protected
946
+ */
947
+ protected function _loadDeclaredModules($mergeConfig = null)
948
+ {
949
+ $moduleFiles = $this->_getDeclaredModuleFiles();
950
+ if (!$moduleFiles) {
951
+ return ;
952
+ }
953
+
954
+ Varien_Profiler::start('config/load-modules-declaration');
955
+
956
+ $unsortedConfig = new Bronto_ConflictChecker_Model_Core_Config_Base();
957
+ $unsortedConfig->loadString('<config/>');
958
+ $fileConfig = new Bronto_ConflictChecker_Model_Core_Config_Base();
959
+
960
+ // load modules declarations
961
+ foreach ($moduleFiles as $file) {
962
+ $fileConfig->loadFile($file);
963
+ $unsortedConfig->extend($fileConfig);
964
+ }
965
+
966
+ $moduleDepends = array();
967
+ foreach ($unsortedConfig->getNode('modules')->children() as $moduleName => $moduleNode) {
968
+ if (!$this->_isAllowedModule($moduleName)) {
969
+ continue;
970
+ }
971
+
972
+ $depends = array();
973
+ if ($moduleNode->depends) {
974
+ foreach ($moduleNode->depends->children() as $depend) {
975
+ $depends[$depend->getName()] = true;
976
+ }
977
+ }
978
+ $moduleDepends[$moduleName] = array(
979
+ 'module' => $moduleName,
980
+ 'depends' => $depends,
981
+ 'active' => ('true' === (string)$moduleNode->active ? true : false),
982
+ );
983
+ }
984
+
985
+ // check and sort module dependence
986
+ $moduleDepends = $this->_sortModuleDepends($moduleDepends);
987
+
988
+ // create sorted config
989
+ $sortedConfig = new Bronto_ConflictChecker_Model_Core_Config_Base();
990
+ $sortedConfig->loadString('<config><modules/></config>');
991
+
992
+ foreach ($unsortedConfig->getNode()->children() as $nodeName => $node) {
993
+ if ($nodeName != 'modules') {
994
+ $sortedConfig->getNode()->appendChild($node);
995
+ }
996
+ }
997
+
998
+ foreach ($moduleDepends as $moduleProp) {
999
+ $node = $unsortedConfig->getNode('modules/'.$moduleProp['module']);
1000
+ $sortedConfig->getNode('modules')->appendChild($node);
1001
+ }
1002
+
1003
+ $this->extend($sortedConfig);
1004
+
1005
+ Varien_Profiler::stop('config/load-modules-declaration');
1006
+ return $this;
1007
+ }
1008
+
1009
+ // }}}
1010
+ // {{{ _sortModuleDepends()
1011
+
1012
+ /**
1013
+ * Sort modules and check depends
1014
+ *
1015
+ * @param array $modules
1016
+ *
1017
+ * @return array
1018
+ * @access protected
1019
+ */
1020
+ protected function _sortModuleDepends($modules)
1021
+ {
1022
+ foreach ($modules as $moduleName => $moduleProps) {
1023
+ $depends = $moduleProps['depends'];
1024
+ foreach ($moduleProps['depends'] as $depend => $true) {
1025
+ if ($moduleProps['active'] && ((!isset($modules[$depend])) || empty($modules[$depend]['active']))) {
1026
+ Mage::throwException(
1027
+ Mage::helper('core')->__('Module "%1$s" requires module "%2$s".', $moduleName, $depend)
1028
+ );
1029
+ }
1030
+ $depends = array_merge($depends, $modules[$depend]['depends']);
1031
+ }
1032
+ $modules[$moduleName]['depends'] = $depends;
1033
+ }
1034
+ $modules = array_values($modules);
1035
+
1036
+ $size = count($modules) - 1;
1037
+ for ($i = $size; $i >= 0; $i--) {
1038
+ for ($j = $size; $i < $j; $j--) {
1039
+ if (isset($modules[$i]['depends'][$modules[$j]['module']])) {
1040
+ $value = $modules[$i];
1041
+ $modules[$i] = $modules[$j];
1042
+ $modules[$j] = $value;
1043
+ }
1044
+ }
1045
+ }
1046
+
1047
+ $definedModules = array();
1048
+ foreach ($modules as $moduleProp) {
1049
+ foreach ($moduleProp['depends'] as $dependModule => $true) {
1050
+ if (!isset($definedModules[$dependModule])) {
1051
+ Mage::throwException(
1052
+ Mage::helper('core')->__(
1053
+ 'Module "%1$s" cannot depend on "%2$s".', $moduleProp['module'], $dependModule
1054
+ )
1055
+ );
1056
+ }
1057
+ }
1058
+ $definedModules[$moduleProp['module']] = true;
1059
+ }
1060
+
1061
+ return $modules;
1062
+ }
1063
+
1064
+ // }}}
1065
+ // {{{ determineOmittedNamespace()
1066
+
1067
+ /**
1068
+ * Determine whether provided name begins from any available modules, according to namespaces priority
1069
+ * If matched, returns as the matched module "factory" name or a fully qualified module name
1070
+ *
1071
+ * @param string $name
1072
+ * @param bool $asFullModuleName
1073
+ *
1074
+ * @return string
1075
+ * @access public
1076
+ */
1077
+ public function determineOmittedNamespace($name, $asFullModuleName = false)
1078
+ {
1079
+ if (null === $this->_moduleNamespaces) {
1080
+ $this->_moduleNamespaces = array();
1081
+ foreach ($this->_xml->xpath('modules/*') as $m) {
1082
+ if ((string)$m->active == 'true') {
1083
+ $moduleName = $m->getName();
1084
+ $module = strtolower($moduleName);
1085
+ $this->_moduleNamespaces[substr($module, 0, strpos($module, '_'))][$module] = $moduleName;
1086
+ }
1087
+ }
1088
+ }
1089
+
1090
+ $name = explode('_', strtolower($name));
1091
+ $partsNum = count($name);
1092
+ $defaultNamespaceFlag = false;
1093
+ foreach ($this->_moduleNamespaces as $namespaceName => $namespace) {
1094
+ // assume the namespace is omitted (default namespace only, which comes first)
1095
+ if ($defaultNamespaceFlag === false) {
1096
+ $defaultNamespaceFlag = true;
1097
+ $defaultNS = $namespaceName . '_' . $name[0];
1098
+ if (isset($namespace[$defaultNS])) {
1099
+ return $asFullModuleName ? $namespace[$defaultNS] : $name[0]; // return omitted as well
1100
+ }
1101
+ }
1102
+ // assume namespace is qualified
1103
+ if (isset($name[1])) {
1104
+ $fullNS = $name[0] . '_' . $name[1];
1105
+ if (2 <= $partsNum && isset($namespace[$fullNS])) {
1106
+ return $asFullModuleName ? $namespace[$fullNS] : $fullNS;
1107
+ }
1108
+ }
1109
+ }
1110
+ return '';
1111
+ }
1112
+
1113
+ // }}}
1114
+ // {{{ loadModulesConfiguration()
1115
+
1116
+ /**
1117
+ * Iterate all active modules "etc" folders and combine data from
1118
+ * specidied xml file name to one object
1119
+ *
1120
+ * @param string $fileName
1121
+ * @param null|Mage_Core_Model_Config_Base $mergeToObject
1122
+ *
1123
+ * @return Mage_Core_Model_Config_Base
1124
+ * @access public
1125
+ */
1126
+ public function loadModulesConfiguration($fileName, $mergeToObject = null, $mergeModel=null)
1127
+ {
1128
+ $disableLocalModules = !$this->_canUseLocalModules();
1129
+
1130
+ if ($mergeToObject === null) {
1131
+ $mergeToObject = clone $this->_prototype;
1132
+ $mergeToObject->loadString('<config/>');
1133
+ }
1134
+ if ($mergeModel === null) {
1135
+ $mergeModel = clone $this->_prototype;
1136
+ }
1137
+ $modules = $this->getNode('modules')->children();
1138
+ foreach ($modules as $modName=>$module) {
1139
+ if ($module->is('active')) {
1140
+ if ($disableLocalModules && ('local' === (string)$module->codePool)) {
1141
+ continue;
1142
+ }
1143
+ if (!is_array($fileName)) {
1144
+ $fileName = array($fileName);
1145
+ }
1146
+
1147
+ switch ((string) $module->codePool) {
1148
+ case 'local' :
1149
+ case 'community' :
1150
+ Mage::register('conflict_datastore_enabled', true);
1151
+ break;
1152
+
1153
+ default :
1154
+ Mage::register('conflict_datastore_enabled', false);
1155
+ break;
1156
+ }
1157
+
1158
+ foreach ($fileName as $configFile) {
1159
+ $configFile = $this->getModuleDir('etc', $modName).DS.$configFile;
1160
+ if ($mergeModel->loadFile($configFile)) {
1161
+ Mage::register('conflict_datastore_config_file', $configFile);
1162
+ $mergeToObject->extend($mergeModel, true);
1163
+ Mage::unregister('conflict_datastore_config_file');
1164
+ }
1165
+ }
1166
+ Mage::unregister('conflict_datastore_enabled');
1167
+ }
1168
+ }
1169
+ return $mergeToObject;
1170
+ }
1171
+
1172
+ // }}}
1173
+ // {{{ getTempVarDir()
1174
+
1175
+ /**
1176
+ * Retrieve temporary directory path
1177
+ *
1178
+ * @return string
1179
+ * @access public
1180
+ */
1181
+ public function getTempVarDir()
1182
+ {
1183
+ return $this->getOptions()->getVarDir();
1184
+ }
1185
+
1186
+ // }}}
1187
+ // {{{ getDistroServerVars()
1188
+
1189
+ /**
1190
+ * Get default server variables values
1191
+ *
1192
+ * @return array
1193
+ * @access public
1194
+ */
1195
+ public function getDistroServerVars()
1196
+ {
1197
+ if (!$this->_distroServerVars) {
1198
+
1199
+ if (isset($_SERVER['SCRIPT_NAME']) && isset($_SERVER['HTTP_HOST'])) {
1200
+ $secure = (!empty($_SERVER['HTTPS']) && ($_SERVER['HTTPS']!='off')) || $_SERVER['SERVER_PORT']=='443';
1201
+ $scheme = ($secure ? 'https' : 'http') . '://' ;
1202
+
1203
+ $hostArr = explode(':', $_SERVER['HTTP_HOST']);
1204
+ $host = $hostArr[0];
1205
+ $port = isset(
1206
+ $hostArr[1]) && (!$secure && $hostArr[1]!=80 || $secure && $hostArr[1]!=443
1207
+ ) ? ':'.$hostArr[1] : '';
1208
+ $path = Mage::app()->getRequest()->getBasePath();
1209
+
1210
+ $baseUrl = $scheme.$host.$port.rtrim($path, '/').'/';
1211
+ } else {
1212
+ $baseUrl = 'http://localhost/';
1213
+ }
1214
+
1215
+ $options = $this->getOptions();
1216
+ $this->_distroServerVars = array(
1217
+ 'root_dir' => $options->getBaseDir(),
1218
+ 'app_dir' => $options->getAppDir(),
1219
+ 'var_dir' => $options->getVarDir(),
1220
+ 'base_url' => $baseUrl,
1221
+ );
1222
+
1223
+ foreach ($this->_distroServerVars as $k=>$v) {
1224
+ $this->_substServerVars['{{'.$k.'}}'] = $v;
1225
+ }
1226
+ }
1227
+ return $this->_distroServerVars;
1228
+ }
1229
+
1230
+ // }}}
1231
+ // {{{ substDistroServerVars()
1232
+
1233
+
1234
+ /**
1235
+ * Short description for function
1236
+ *
1237
+ * Long description (if any) ...
1238
+ *
1239
+ * @param unknown $data Parameter description (if any) ...
1240
+ *
1241
+ * @return array Return description (if any) ...
1242
+ * @access public
1243
+ */
1244
+ public function substDistroServerVars($data)
1245
+ {
1246
+ $this->getDistroServerVars();
1247
+ return str_replace(
1248
+ array_keys($this->_substServerVars),
1249
+ array_values($this->_substServerVars),
1250
+ $data
1251
+ );
1252
+ }
1253
+
1254
+ // }}}
1255
+ // {{{ getModuleConfig()
1256
+
1257
+ /**
1258
+ * Get module config node
1259
+ *
1260
+ * @param string $moduleName
1261
+ *
1262
+ * @return Varien_Simplexml_Object
1263
+ * @access public
1264
+ */
1265
+ public function getModuleConfig($moduleName='')
1266
+ {
1267
+ $modules = $this->getNode('modules');
1268
+ if (''===$moduleName) {
1269
+ return $modules;
1270
+ } else {
1271
+ return $modules->$moduleName;
1272
+ }
1273
+ }
1274
+
1275
+ // }}}
1276
+ // {{{ getModuleSetup()
1277
+
1278
+ /**
1279
+ * Get module setup class instance.
1280
+ *
1281
+ * Defaults to Mage_Core_Setup
1282
+ *
1283
+ * @param string|Varien_Simplexml_Object $module
1284
+ *
1285
+ * @return object
1286
+ * @access public
1287
+ */
1288
+ public function getModuleSetup($module='')
1289
+ {
1290
+ $className = 'Mage_Core_Setup';
1291
+ if (''!==$module) {
1292
+ if (is_string($module)) {
1293
+ $module = $this->getModuleConfig($module);
1294
+ }
1295
+ if (isset($module->setup)) {
1296
+ $moduleClassName = $module->setup->getClassName();
1297
+ if (!empty($moduleClassName)) {
1298
+ $className = $moduleClassName;
1299
+ }
1300
+ }
1301
+ }
1302
+ return new $className($module);
1303
+ }
1304
+
1305
+ // }}}
1306
+ // {{{ getBaseDir()
1307
+
1308
+ /**
1309
+ * Get base filesystem directory. depends on $type
1310
+ *
1311
+ * If $moduleName is specified retrieves specific value for the module.
1312
+ *
1313
+ * @param string $type
1314
+ *
1315
+ * @deprecated in favor of Mage_Core_Model_Config_Options
1316
+ * @todo get global dir config
1317
+ * @return string
1318
+ * @access public
1319
+ */
1320
+ public function getBaseDir($type='base')
1321
+ {
1322
+ return $this->getOptions()->getDir($type);
1323
+ }
1324
+
1325
+ // }}}
1326
+ // {{{ getVarDir()
1327
+
1328
+ /**
1329
+ * Get temporary data directory name
1330
+ *
1331
+ * @param string $path
1332
+ * @param string $type
1333
+ *
1334
+ * @return string
1335
+ * @access public
1336
+ */
1337
+ public function getVarDir($path=null, $type='var')
1338
+ {
1339
+ $dir = Mage::getBaseDir($type).($path!==null ? DS.$path : '');
1340
+ if (!$this->createDirIfNotExists($dir)) {
1341
+ return false;
1342
+ }
1343
+ return $dir;
1344
+ }
1345
+
1346
+ // }}}
1347
+ // {{{ createDirIfNotExists()
1348
+
1349
+
1350
+ /**
1351
+ * Short description for function
1352
+ *
1353
+ * Long description (if any) ...
1354
+ *
1355
+ * @param unknown $dir Parameter description (if any) ...
1356
+ *
1357
+ * @return unknown Return description (if any) ...
1358
+ * @access public
1359
+ */
1360
+ public function createDirIfNotExists($dir)
1361
+ {
1362
+ return $this->getOptions()->createDirIfNotExists($dir);
1363
+ }
1364
+
1365
+ // }}}
1366
+ // {{{ getModuleDir()
1367
+
1368
+ /**
1369
+ * Get module directory by directory type
1370
+ *
1371
+ * @param string $type
1372
+ * @param string $moduleName
1373
+ *
1374
+ * @return string
1375
+ * @access public
1376
+ */
1377
+ public function getModuleDir($type, $moduleName)
1378
+ {
1379
+ $codePool = (string)$this->getModuleConfig($moduleName)->codePool;
1380
+ $dir = $this->getOptions()->getCodeDir().DS.$codePool.DS.uc_words($moduleName, DS);
1381
+
1382
+ switch ($type) {
1383
+ case 'etc':
1384
+ $dir .= DS.'etc';
1385
+ break;
1386
+
1387
+ case 'controllers':
1388
+ $dir .= DS.'controllers';
1389
+ break;
1390
+
1391
+ case 'sql':
1392
+ $dir .= DS.'sql';
1393
+ break;
1394
+ case 'data':
1395
+ $dir .= DS.'data';
1396
+ break;
1397
+
1398
+ case 'locale':
1399
+ $dir .= DS.'locale';
1400
+ break;
1401
+ }
1402
+
1403
+ $dir = str_replace('/', DS, $dir);
1404
+ return $dir;
1405
+ }
1406
+
1407
+ // }}}
1408
+ // {{{ loadEventObservers()
1409
+
1410
+ /**
1411
+ * Load event observers for an area (front, admin)
1412
+ *
1413
+ * @param string $area
1414
+ *
1415
+ * @return boolean
1416
+ * @access public
1417
+ */
1418
+ public function loadEventObservers($area)
1419
+ {
1420
+ $events = $this->getNode("$area/events");
1421
+ if ($events) {
1422
+ $events = $events->children();
1423
+ } else {
1424
+ return false;
1425
+ }
1426
+
1427
+ foreach ($events as $event) {
1428
+ $eventName = $event->getName();
1429
+ $observers = $event->observers->children();
1430
+ foreach ($observers as $observer) {
1431
+ switch ((string)$observer->type) {
1432
+ case 'singleton':
1433
+ $callback = array(
1434
+ Mage::getSingleton((string)$observer->class),
1435
+ (string)$observer->method
1436
+ );
1437
+ break;
1438
+ case 'object':
1439
+ case 'model':
1440
+ $callback = array(
1441
+ Mage::getModel((string)$observer->class),
1442
+ (string)$observer->method
1443
+ );
1444
+ break;
1445
+ default:
1446
+ $callback = array($observer->getClassName(), (string)$observer->method);
1447
+ break;
1448
+ }
1449
+
1450
+ $args = (array)$observer->args;
1451
+ $observerClass = $observer->observer_class ? (string)$observer->observer_class : '';
1452
+ Mage::addObserver($eventName, $callback, $args, $observer->getName(), $observerClass);
1453
+ }
1454
+ }
1455
+ return true;
1456
+ }
1457
+
1458
+ // }}}
1459
+ // {{{ getPathVars()
1460
+
1461
+ /**
1462
+ * Get standard path variables.
1463
+ *
1464
+ * To be used in blocks, templates, etc.
1465
+ *
1466
+ * @param array|string $args Module name if string
1467
+ *
1468
+ * @return array
1469
+ * @access public
1470
+ */
1471
+ public function getPathVars($args=null)
1472
+ {
1473
+ $path = array();
1474
+
1475
+ $path['baseUrl'] = Mage::getBaseUrl();
1476
+ $path['baseSecureUrl'] = Mage::getBaseUrl('link', true);
1477
+
1478
+ return $path;
1479
+ }
1480
+
1481
+ // }}}
1482
+ // {{{ getGroupedClassName()
1483
+
1484
+ /**
1485
+ * Retrieve class name by class group
1486
+ *
1487
+ * @param string $groupType currently supported model, block, helper
1488
+ * @param string $classId slash separated class identifier, ex. group/class
1489
+ * @param string $groupRootNode optional config path for group config
1490
+ *
1491
+ * @return string
1492
+ * @access public
1493
+ */
1494
+ public function getGroupedClassName($groupType, $classId, $groupRootNode=null)
1495
+ {
1496
+ if (empty($groupRootNode)) {
1497
+ $groupRootNode = 'global/'.$groupType.'s';
1498
+ }
1499
+
1500
+ $classArr = explode('/', trim($classId));
1501
+ $group = $classArr[0];
1502
+ $class = !empty($classArr[1]) ? $classArr[1] : null;
1503
+
1504
+ if (isset($this->_classNameCache[$groupRootNode][$group][$class])) {
1505
+ return $this->_classNameCache[$groupRootNode][$group][$class];
1506
+ }
1507
+
1508
+ $config = $this->_xml->global->{$groupType.'s'}->{$group};
1509
+
1510
+ // First - check maybe the entity class was rewritten
1511
+ $className = null;
1512
+ if (isset($config->rewrite->$class)) {
1513
+ $className = (string)$config->rewrite->$class;
1514
+ } else {
1515
+ /**
1516
+ * Backwards compatibility for pre-MMDB extensions.
1517
+ * In MMDB release resource nodes <..._mysql4> were renamed to <..._resource>. So <deprecatedNode> is left
1518
+ * to keep name of previously used nodes, that still may be used by non-updated extensions.
1519
+ */
1520
+ if ($config->deprecatedNode) {
1521
+ $deprecatedNode = $config->deprecatedNode;
1522
+ $configOld = $this->_xml->global->{$groupType.'s'}->$deprecatedNode;
1523
+ if (isset($configOld->rewrite->$class)) {
1524
+ $className = (string) $configOld->rewrite->$class;
1525
+ }
1526
+ }
1527
+ }
1528
+
1529
+ // Second - if entity is not rewritten then use class prefix to form class name
1530
+ if (empty($className)) {
1531
+ if (!empty($config)) {
1532
+ $className = $config->getClassName();
1533
+ }
1534
+ if (empty($className)) {
1535
+ $className = 'mage_'.$group.'_'.$groupType;
1536
+ }
1537
+ if (!empty($class)) {
1538
+ $className .= '_'.$class;
1539
+ }
1540
+ $className = uc_words($className);
1541
+ }
1542
+
1543
+ $this->_classNameCache[$groupRootNode][$group][$class] = $className;
1544
+ return $className;
1545
+ }
1546
+
1547
+ // }}}
1548
+ // {{{ getBlockClassName()
1549
+
1550
+ /**
1551
+ * Retrieve block class name
1552
+ *
1553
+ * @param string $blockType
1554
+ *
1555
+ * @return string
1556
+ * @access public
1557
+ */
1558
+ public function getBlockClassName($blockType)
1559
+ {
1560
+ if (strpos($blockType, '/')===false) {
1561
+ return $blockType;
1562
+ }
1563
+ return $this->getGroupedClassName('block', $blockType);
1564
+ }
1565
+
1566
+ // }}}
1567
+ // {{{ getHelperClassName()
1568
+
1569
+ /**
1570
+ * Retrieve helper class name
1571
+ *
1572
+ * @param string $name
1573
+ *
1574
+ * @return string
1575
+ * @access public
1576
+ */
1577
+ public function getHelperClassName($helperName)
1578
+ {
1579
+ if (strpos($helperName, '/') === false) {
1580
+ $helperName .= '/data';
1581
+ }
1582
+ return $this->getGroupedClassName('helper', $helperName);
1583
+ }
1584
+
1585
+ // }}}
1586
+ // {{{ getResourceHelper()
1587
+
1588
+ /**
1589
+ * Retreive resource helper instance
1590
+ *
1591
+ * Example:
1592
+ * $config->getResourceHelper('cms')
1593
+ * will instantiate Mage_Cms_Model_Resource_Helper_<db_adapter_name>
1594
+ *
1595
+ * @param string $moduleName
1596
+ *
1597
+ * @return Mage_Core_Model_Resource_Helper_Abstract|false
1598
+ * @access public
1599
+ */
1600
+ public function getResourceHelper($moduleName)
1601
+ {
1602
+ $connectionModel = $this->_getResourceConnectionModel($moduleName);
1603
+ $helperClass = sprintf('%s/helper_%s', $moduleName, $connectionModel);
1604
+ $helperClassName = $this->_getResourceModelFactoryClassName($helperClass);
1605
+ if ($helperClassName) {
1606
+ return $this->getModelInstance($helperClassName, $moduleName);
1607
+ }
1608
+
1609
+ return false;
1610
+ }
1611
+
1612
+ // }}}
1613
+ // {{{ getModelClassName()
1614
+
1615
+ /**
1616
+ * Retrieve module class name
1617
+ *
1618
+ * @param sting $modelClass
1619
+ *
1620
+ * @return string
1621
+ * @access public
1622
+ */
1623
+ public function getModelClassName($modelClass)
1624
+ {
1625
+ $modelClass = trim($modelClass);
1626
+ if (strpos($modelClass, '/')===false) {
1627
+ return $modelClass;
1628
+ }
1629
+ return $this->getGroupedClassName('model', $modelClass);
1630
+ }
1631
+
1632
+ // }}}
1633
+ // {{{ getModelInstance()
1634
+
1635
+ /**
1636
+ * Get model class instance.
1637
+ *
1638
+ * Example:
1639
+ * $config->getModelInstance('catalog/product')
1640
+ *
1641
+ * Will instantiate Mage_Catalog_Model_Mysql4_Product
1642
+ *
1643
+ * @param string $modelClass
1644
+ * @param array|object $constructArguments
1645
+ *
1646
+ * @return Mage_Core_Model_Abstract
1647
+ * @access public
1648
+ */
1649
+ public function getModelInstance($modelClass='', $constructArguments=array())
1650
+ {
1651
+ $className = $this->getModelClassName($modelClass);
1652
+ if (class_exists($className)) {
1653
+ Varien_Profiler::start('CORE::create_object_of::'.$className);
1654
+ $obj = new $className($constructArguments);
1655
+ Varien_Profiler::stop('CORE::create_object_of::'.$className);
1656
+ return $obj;
1657
+ } else {
1658
+ /* throw Mage::exception(
1659
+ 'Mage_Core',
1660
+ Mage::helper('core')->__('Model class does not exist: %s.', $modelClass)
1661
+ ); */
1662
+ return false;
1663
+ }
1664
+ }
1665
+
1666
+ // }}}
1667
+ // {{{ getNodeClassInstance()
1668
+
1669
+
1670
+ /**
1671
+ * Short description for function
1672
+ *
1673
+ * Long description (if any) ...
1674
+ *
1675
+ * @param unknown $path Parameter description (if any) ...
1676
+ *
1677
+ * @return mixed Return description (if any) ...
1678
+ * @access public
1679
+ */
1680
+ public function getNodeClassInstance($path)
1681
+ {
1682
+ $config = Mage::getConfig()->getNode($path);
1683
+ if (!$config) {
1684
+ return false;
1685
+ } else {
1686
+ $className = $config->getClassName();
1687
+ return new $className();
1688
+ }
1689
+ }
1690
+
1691
+ // }}}
1692
+ // {{{ getResourceModelInstance()
1693
+
1694
+ /**
1695
+ * Get resource model object by alias
1696
+ *
1697
+ * @param string $modelClass
1698
+ * @param array $constructArguments
1699
+ *
1700
+ * @return object
1701
+ * @access public
1702
+ */
1703
+ public function getResourceModelInstance($modelClass='', $constructArguments=array())
1704
+ {
1705
+ $factoryName = $this->_getResourceModelFactoryClassName($modelClass);
1706
+ if (!$factoryName) {
1707
+ return false;
1708
+ }
1709
+ return $this->getModelInstance($factoryName, $constructArguments);
1710
+ }
1711
+
1712
+ // }}}
1713
+ // {{{ getResourceConfig()
1714
+
1715
+ /**
1716
+ * Get resource configuration for resource name
1717
+ *
1718
+ * @param string $name
1719
+ *
1720
+ * @return Varien_Simplexml_Object
1721
+ * @access public
1722
+ */
1723
+ public function getResourceConfig($name)
1724
+ {
1725
+ return $this->_xml->global->resources->{$name};
1726
+ }
1727
+
1728
+ // }}}
1729
+ // {{{ getResourceConnectionConfig()
1730
+
1731
+ /**
1732
+ * Get connection configuration
1733
+ *
1734
+ * @param string $name
1735
+ *
1736
+ * @return Varien_Simplexml_Element
1737
+ * @access public
1738
+ */
1739
+ public function getResourceConnectionConfig($name)
1740
+ {
1741
+ $config = $this->getResourceConfig($name);
1742
+ if ($config) {
1743
+ $conn = $config->connection;
1744
+ if ($conn) {
1745
+ if (!empty($conn->use)) {
1746
+ return $this->getResourceConnectionConfig((string)$conn->use);
1747
+ } else {
1748
+ return $conn;
1749
+ }
1750
+ }
1751
+ }
1752
+ return false;
1753
+ }
1754
+
1755
+ // }}}
1756
+ // {{{ getResourceTypeConfig()
1757
+
1758
+ /**
1759
+ * Retrieve resource type configuration for resource name
1760
+ *
1761
+ * @param string $type
1762
+ *
1763
+ * @return Varien_Simplexml_Object
1764
+ * @access public
1765
+ */
1766
+ public function getResourceTypeConfig($type)
1767
+ {
1768
+ return $this->_xml->global->resource->connection->types->{$type};
1769
+ }
1770
+
1771
+ // }}}
1772
+ // {{{ getStoresConfigByPath()
1773
+
1774
+ /**
1775
+ * Retrieve store Ids for $path with checking
1776
+ *
1777
+ * if empty $allowValues then retrieve all stores values
1778
+ *
1779
+ * return array($storeId=>$pathValue)
1780
+ *
1781
+ * @param string $path
1782
+ * @param array $allowValues
1783
+ *
1784
+ * @return array
1785
+ * @access public
1786
+ */
1787
+ public function getStoresConfigByPath($path, $allowValues = array(), $useAsKey = 'id')
1788
+ {
1789
+ $storeValues = array();
1790
+ $stores = $this->getNode('stores');
1791
+ foreach ($stores->children() as $code => $store) {
1792
+ switch ($useAsKey) {
1793
+ case 'id':
1794
+ $key = (int) $store->descend('system/store/id');
1795
+ break;
1796
+
1797
+ case 'code':
1798
+ $key = $code;
1799
+ break;
1800
+
1801
+ case 'name':
1802
+ $key = (string) $store->descend('system/store/name');
1803
+ }
1804
+ if ($key === false) {
1805
+ continue;
1806
+ }
1807
+
1808
+ $pathValue = (string) $store->descend($path);
1809
+
1810
+ if (empty($allowValues)) {
1811
+ $storeValues[$key] = $pathValue;
1812
+ } else if (in_array($pathValue, $allowValues)) {
1813
+ $storeValues[$key] = $pathValue;
1814
+ }
1815
+ }
1816
+ return $storeValues;
1817
+ }
1818
+
1819
+ // }}}
1820
+ // {{{ shouldUrlBeSecure()
1821
+
1822
+ /**
1823
+ * Check security requirements for url
1824
+ *
1825
+ * @param string $url
1826
+ *
1827
+ * @return bool
1828
+ * @access public
1829
+ */
1830
+ public function shouldUrlBeSecure($url)
1831
+ {
1832
+ if (!isset($this->_secureUrlCache[$url])) {
1833
+ $this->_secureUrlCache[$url] = false;
1834
+ $secureUrls = $this->getNode('frontend/secure_url');
1835
+ foreach ($secureUrls->children() as $match) {
1836
+ if (strpos($url, (string)$match)===0) {
1837
+ $this->_secureUrlCache[$url] = true;
1838
+ break;
1839
+ }
1840
+ }
1841
+ }
1842
+
1843
+ return $this->_secureUrlCache[$url];
1844
+ }
1845
+
1846
+ // }}}
1847
+ // {{{ getTablePrefix()
1848
+
1849
+ /**
1850
+ * Get DB table names prefix
1851
+ *
1852
+ * @return string
1853
+ * @access public
1854
+ */
1855
+ public function getTablePrefix()
1856
+ {
1857
+ return $this->_xml->global->resources->db->table_prefix;
1858
+ }
1859
+
1860
+ // }}}
1861
+ // {{{ getEventConfig()
1862
+
1863
+ /**
1864
+ * Get events configuration
1865
+ *
1866
+ * @param string $area event area
1867
+ * @param string $eventName event name
1868
+ *
1869
+ * @return Mage_Core_Model_Config_Element
1870
+ * @access public
1871
+ */
1872
+ public function getEventConfig($area, $eventName)
1873
+ {
1874
+ //return $this->getNode($area)->events->{$eventName};
1875
+ if (!isset($this->_eventAreas[$area])) {
1876
+ $this->_eventAreas[$area] = $this->getNode($area)->events;
1877
+ }
1878
+ return $this->_eventAreas[$area]->{$eventName};
1879
+ }
1880
+
1881
+ // }}}
1882
+ // {{{ saveConfig()
1883
+
1884
+ /**
1885
+ * Save config value to DB
1886
+ *
1887
+ * @param string $path
1888
+ * @param string $value
1889
+ * @param string $scope
1890
+ * @param int $scopeId
1891
+ *
1892
+ * @return Mage_Core_Store_Config
1893
+ * @access public
1894
+ */
1895
+ public function saveConfig($path, $value, $scope = 'default', $scopeId = 0)
1896
+ {
1897
+ $resource = $this->getResourceModel();
1898
+ $resource->saveConfig(rtrim($path, '/'), $value, $scope, $scopeId);
1899
+
1900
+ return $this;
1901
+ }
1902
+
1903
+ // }}}
1904
+ // {{{ deleteConfig()
1905
+
1906
+ /**
1907
+ * Delete config value from DB
1908
+ *
1909
+ * @param string $path
1910
+ * @param string $scope
1911
+ * @param int $scopeId
1912
+ *
1913
+ * @return Mage_Core_Model_Config
1914
+ * @access public
1915
+ */
1916
+ public function deleteConfig($path, $scope = 'default', $scopeId = 0)
1917
+ {
1918
+ $resource = $this->getResourceModel();
1919
+ $resource->deleteConfig(rtrim($path, '/'), $scope, $scopeId);
1920
+
1921
+ return $this;
1922
+ }
1923
+
1924
+ // }}}
1925
+ // {{{ getFieldset()
1926
+
1927
+ /**
1928
+ * Get fieldset from configuration
1929
+ *
1930
+ * @param string $name fieldset name
1931
+ * @param string $root fieldset area, could be 'admin'
1932
+ *
1933
+ * @return null|array
1934
+ * @access public
1935
+ */
1936
+ public function getFieldset($name, $root = 'global')
1937
+ {
1938
+ $rootNode = $this->getNode($root.'/fieldsets');
1939
+ if (!$rootNode) {
1940
+ return null;
1941
+ }
1942
+ return $rootNode->$name ? $rootNode->$name->children() : null;
1943
+ }
1944
+
1945
+ // }}}
1946
+ // {{{ _getResourceConnectionModel()
1947
+
1948
+ /**
1949
+ * Retrieve resource connection model name
1950
+ *
1951
+ * @param string $moduleName
1952
+ *
1953
+ * @return string
1954
+ * @access protected
1955
+ */
1956
+ protected function _getResourceConnectionModel($moduleName = null)
1957
+ {
1958
+ $config = null;
1959
+ if (!is_null($moduleName)) {
1960
+ $setupResource = $moduleName . '_setup';
1961
+ $config = $this->getResourceConnectionConfig($setupResource);
1962
+ }
1963
+ if (!$config) {
1964
+ $config = $this->getResourceConnectionConfig(Mage_Core_Model_Resource::DEFAULT_SETUP_RESOURCE);
1965
+ }
1966
+
1967
+ return (string)$config->model;
1968
+ }
1969
+
1970
+ // }}}
1971
+ // {{{ _getResourceModelFactoryClassName()
1972
+
1973
+ /**
1974
+ * Get factory class name for a resource
1975
+ *
1976
+ * @param string $modelClass
1977
+ *
1978
+ * @return string|false
1979
+ * @access protected
1980
+ */
1981
+ protected function _getResourceModelFactoryClassName($modelClass)
1982
+ {
1983
+ $classArray = explode('/', $modelClass);
1984
+ if (count($classArray) != 2) {
1985
+ return false;
1986
+ }
1987
+
1988
+ list($module, $model) = $classArray;
1989
+ if (!isset($this->_xml->global->models->{$module})) {
1990
+ return false;
1991
+ }
1992
+
1993
+ $moduleNode = $this->_xml->global->models->{$module};
1994
+ if (!empty($moduleNode->resourceModel)) {
1995
+ $resourceModel = (string)$moduleNode->resourceModel;
1996
+ } else {
1997
+ return false;
1998
+ }
1999
+
2000
+ return $resourceModel . '/' . $model;
2001
+ }
2002
+
2003
+ // }}}
2004
+ // {{{ getResourceModelClassName()
2005
+
2006
+ /**
2007
+ * Get a resource model class name
2008
+ *
2009
+ * @param string $modelClass
2010
+ *
2011
+ * @return string|false
2012
+ * @access public
2013
+ */
2014
+ public function getResourceModelClassName($modelClass)
2015
+ {
2016
+ $factoryName = $this->_getResourceModelFactoryClassName($modelClass);
2017
+ if ($factoryName) {
2018
+ return $this->getModelClassName($factoryName);
2019
+ }
2020
+ return false;
2021
+ }
2022
+
2023
+ // }}}
2024
+ }
app/code/community/Bronto/ConflictChecker/Model/Core/Config/Base.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * XML configuration base
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * XML configuration base
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Model_Core_Config_Base
33
+ extends Bronto_ConflictChecker_Model_Lib_Varien_Simplexml_Config
34
+ {
35
+ // {{{ __construct()
36
+
37
+ /**
38
+ * Constructor
39
+ *
40
+ * @return void
41
+ * @access public
42
+ */
43
+ public function __construct($sourceData = null)
44
+ {
45
+ $this->_elementClass = 'Bronto_ConflictChecker_Model_Core_Config_Element';
46
+ parent::__construct($sourceData);
47
+ }
48
+
49
+ // }}}
50
+ }
app/code/community/Bronto/ConflictChecker/Model/Core/Config/Element.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * XML Configuation element
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * XML Configuation element
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Model_Core_Config_Element
33
+ extends Bronto_ConflictChecker_Model_Lib_Varien_Simplexml_Element
34
+ {
35
+ // {{{ is()
36
+
37
+ /**
38
+ * Is element enabled
39
+ *
40
+ * @param string $var
41
+ * @param boolean $value
42
+ *
43
+ * @return boolean
44
+ * @access public
45
+ */
46
+ public function is($var, $value = true)
47
+ {
48
+ $flag = $this->$var;
49
+
50
+ if ($value === true) {
51
+ $flag = strtolower((string)$flag);
52
+ if (!empty($flag) && 'false' !== $flag && 'off' !== $flag) {
53
+ return true;
54
+ } else {
55
+ return false;
56
+ }
57
+ }
58
+
59
+ return !empty($flag) && (0 === strcasecmp($value, (string)$flag));
60
+ }
61
+
62
+ // }}}
63
+ // {{{ getClassName()
64
+
65
+ /**
66
+ * Get node class name
67
+ *
68
+ * @return string
69
+ * @access public
70
+ */
71
+ public function getClassName()
72
+ {
73
+ if ($this->class) {
74
+ $model = (string)$this->class;
75
+ } elseif ($this->model) {
76
+ $model = (string)$this->model;
77
+ } else {
78
+ return false;
79
+ }
80
+ return Mage::getConfig()->getModelClassName($model);
81
+ }
82
+
83
+ // }}}
84
+ }
app/code/community/Bronto/ConflictChecker/Model/Lib/Varien/Simplexml/Config.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * SimpleXML Config element
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * SimpleXML Config element
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Model_Lib_Varien_Simplexml_Config
33
+ extends Varien_Simplexml_Config
34
+ {
35
+ // {{{ properties
36
+
37
+
38
+ /**
39
+ * Description for protected
40
+ * @var string
41
+ * @access protected
42
+ */
43
+ protected $_elementClass = 'Bronto_ConflictChecker_Model_Lib_Varien_Simplexml_Element';
44
+
45
+ // }}}
46
+ }
app/code/community/Bronto/ConflictChecker/Model/Lib/Varien/Simplexml/Element.php ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * SimpleXML Element
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * SimpleXML Element
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Model_Lib_Varien_Simplexml_Element
33
+ extends Varien_Simplexml_Element
34
+ {
35
+ // {{{ extend()
36
+
37
+ /**
38
+ * Extends current node with xml from $source
39
+ *
40
+ * If $overwrite is false will merge only missing nodes
41
+ * Otherwise will overwrite existing nodes
42
+ *
43
+ * @param Varien_Simplexml_Element $source
44
+ * @param boolean $overwrite
45
+ *
46
+ * @return Varien_Simplexml_Element
47
+ * @access public
48
+ */
49
+ public function extend($source, $overwrite=false)
50
+ {
51
+ if (!$source instanceof Varien_Simplexml_Element) {
52
+ return $this;
53
+ }
54
+
55
+ foreach ($source->children() as $child) {
56
+ $this->extendChild($child, $overwrite);
57
+ }
58
+
59
+ return $this;
60
+ }
61
+
62
+ // }}}
63
+ // {{{ extendChild()
64
+
65
+ /**
66
+ * Extends one node
67
+ *
68
+ * @param Varien_Simplexml_Element $source
69
+ * @param boolean $overwrite
70
+ *
71
+ * @return Varien_Simplexml_Element
72
+ * @access public
73
+ */
74
+ public function extendChild($source, $overwrite=false)
75
+ {
76
+ // this will be our new target node
77
+ $targetChild = null;
78
+
79
+ // name of the source node
80
+ $sourceName = $source->getName();
81
+
82
+ // here we have children of our source node
83
+ $sourceChildren = $source->children();
84
+
85
+ if (!$source->hasChildren()) {
86
+ // handle string node
87
+ if (isset($this->$sourceName)) {
88
+ // if target already has children return without regard
89
+ if ($this->$sourceName->children()) {
90
+ return $this;
91
+ }
92
+ if ($overwrite) {
93
+ if (Mage::registry('conflict_datastore_enabled')) {
94
+ $factory = new Bronto_ConflictChecker_Model_Path_Locator_Factory;
95
+ $locator = $factory->getLocator();
96
+ $dataStore = Mage::registry('conflict_datastore');
97
+ $dataStore->addRewrite(
98
+ (string) $this->$sourceName,
99
+ (string) $source,
100
+ Mage::registry('conflict_datastore_config_file'),
101
+ $locator->getPath($source)
102
+ );
103
+ }
104
+ unset($this->$sourceName);
105
+ } else {
106
+ return $this;
107
+ }
108
+ }
109
+
110
+ $targetChild = $this->addChild($sourceName, $source->xmlentities());
111
+ $targetChild->setParent($this);
112
+ foreach ($source->attributes() as $key=>$value) {
113
+ $targetChild->addAttribute($key, $this->xmlentities($value));
114
+ }
115
+ return $this;
116
+ }
117
+
118
+ if (isset($this->$sourceName)) {
119
+ $targetChild = $this->$sourceName;
120
+ }
121
+
122
+ if (is_null($targetChild)) {
123
+ // if child target is not found create new and descend
124
+ $targetChild = $this->addChild($sourceName);
125
+ $targetChild->setParent($this);
126
+ foreach ($source->attributes() as $key=>$value) {
127
+ $targetChild->addAttribute($key, $this->xmlentities($value));
128
+ }
129
+ }
130
+
131
+ // finally add our source node children to resulting new target node
132
+ foreach ($sourceChildren as $childKey=>$childNode) {
133
+ $targetChild->extendChild($childNode, $overwrite);
134
+ }
135
+
136
+ return $this;
137
+ }
138
+
139
+ // }}}
140
+ // {{{ setNode()
141
+
142
+
143
+ /**
144
+ * Short description for function
145
+ *
146
+ * Long description (if any) ...
147
+ *
148
+ * @param unknown $path Parameter description (if any) ...
149
+ * @param unknown $value Parameter description (if any) ...
150
+ * @param boolean $overwrite Parameter description (if any) ...
151
+ *
152
+ * @return mixed Return description (if any) ...
153
+ * @access public
154
+ */
155
+ public function setNode($path, $value, $overwrite=true)
156
+ {
157
+ $arr1 = explode('/', $path);
158
+ $arr = array();
159
+ foreach ($arr1 as $v) {
160
+ if (!empty($v)) $arr[] = $v;
161
+ }
162
+ $last = sizeof($arr)-1;
163
+ $node = $this;
164
+ foreach ($arr as $i=>$nodeName) {
165
+ if ($last===$i) {
166
+ /*
167
+ if (isset($xml->$nodeName)) {
168
+ if ($overwrite) {
169
+ unset($xml->$nodeName);
170
+ } else {
171
+ continue;
172
+ }
173
+ }
174
+ $xml->addChild($nodeName, $xml->xmlentities($value));
175
+ */
176
+ if (!isset($node->$nodeName) || $overwrite) {
177
+ // http://bugs.php.net/bug.php?id=36795
178
+ // comment on [8 Feb 8:09pm UTC]
179
+ if (isset($node->$nodeName) && (version_compare(phpversion(), '5.2.6', '<')===true)) {
180
+ $node->$nodeName = $node->xmlentities($value);
181
+ } else {
182
+ $node->$nodeName = $value;
183
+ }
184
+ }
185
+ } else {
186
+ if (!isset($node->$nodeName)) {
187
+ $node = $node->addChild($nodeName);
188
+ } else {
189
+ $node = $node->$nodeName;
190
+ }
191
+ }
192
+
193
+ }
194
+ return $this;
195
+ }
196
+
197
+ // }}}
198
+ // {{{ getSafeParent()
199
+
200
+ /**
201
+ * Returns parent node for the element
202
+ *
203
+ * Currently using xpath
204
+ * If xpath value doesn't exist - return null
205
+ *
206
+ * @return Varien_Simplexml_Element|null
207
+ */
208
+ public function getSafeParent()
209
+ {
210
+ if (!empty($this->_parent)) {
211
+ $parent = $this->_parent;
212
+ } else {
213
+ $arr = $this->xpath('..');
214
+ if (is_array($arr) && isset($arr[0])) {
215
+ $parent = $arr[0];
216
+ } else {
217
+ $parent = null;
218
+ }
219
+ }
220
+ return $parent;
221
+ }
222
+
223
+ // }}}
224
+ }
app/code/community/Bronto/ConflictChecker/Model/Mysql4/Core/Config.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Mysql config
5
+ *
6
+ * PHP versions 4 and 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Mysql config
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Model_Mysql4_Core_Config
33
+ extends Bronto_ConflictChecker_Model_Resource_Core_Config
34
+ {
35
+ }
app/code/community/Bronto/ConflictChecker/Model/Path/Locator/Array.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Array implementation of XML path locator
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+
21
+ /**
22
+ * Array implementation of XML path locator
23
+ *
24
+ * @category Bronto
25
+ * @package ConflictChecker
26
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
27
+ * @copyright 2012 Atlantic BT
28
+ * @license http://www.atlanticbt.com/ Atlantic BT
29
+ * @version Release: @package_version@
30
+ * @link <>
31
+ * @see References to other sections (if any)...
32
+ */
33
+ class Bronto_ConflictChecker_Model_Path_Locator_Array
34
+ extends Bronto_ConflictChecker_Model_Path_Locator_IteratorAbstract
35
+ implements Bronto_ConflictChecker_Model_Path_Locator_LocatorInterface
36
+ {
37
+ // {{{ getPath()
38
+
39
+ /**
40
+ * Gets a path to a node via array implementation
41
+ *
42
+ * Pass in the child node and will recurse up the XML tree to print out
43
+ * the path in the tree to that node
44
+ *
45
+ * <config>
46
+ * <path>
47
+ * <to>
48
+ * <node>
49
+ * Node Value
50
+ * </node>
51
+ * </to>
52
+ * </path>
53
+ * </config>
54
+ *
55
+ * If you pass in the "node" object, this will print out
56
+ * config/path/to/node/
57
+ *
58
+ * @param SimpleXmlElement $element Child element to find path to
59
+ *
60
+ * @return string
61
+ * @access public
62
+ */
63
+ public function getPath(SimpleXmlElement $element)
64
+ {
65
+ $this->_iterator[] = $element->getName() . '/';
66
+ if (!$element->getSafeParent()) {
67
+ return array_pop($this->_iterator);
68
+ }
69
+ return $this->getPath($element->getParent()) . array_pop($this->_iterator);
70
+ }
71
+
72
+ // }}}
73
+ }
app/code/community/Bronto/ConflictChecker/Model/Path/Locator/Factory.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Locator factory
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+
21
+ /**
22
+ * Locator factory
23
+ *
24
+ * @category Bronto
25
+ * @package ConflictChecker
26
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
27
+ * @copyright 2012 Atlantic BT
28
+ * @license http://www.atlanticbt.com/ Atlantic BT
29
+ * @version Release: @package_version@
30
+ * @link <>
31
+ * @see References to other sections (if any)...
32
+ */
33
+ class Bronto_ConflictChecker_Model_Path_Locator_Factory
34
+ {
35
+ // {{{ getLocator()
36
+
37
+ /**
38
+ * Get path locator implementation based on PHP version
39
+ *
40
+ * @return Bronto_ConflictChecker_Model_Path_Locator_LocatorInterface
41
+ * @access public
42
+ */
43
+ public function getLocator()
44
+ {
45
+ if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
46
+ $model = new Bronto_ConflictChecker_Model_Path_Locator_Stack(new SplStack());
47
+ } else {
48
+ $model = new Bronto_ConflictChecker_Model_Path_Locator_Array(array());
49
+ }
50
+
51
+ return $model;
52
+ }
53
+
54
+ // }}}
55
+ }
app/code/community/Bronto/ConflictChecker/Model/Path/Locator/IteratorAbstract.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Locator Iterator
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Locator Iterator
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ abstract class Bronto_ConflictChecker_Model_Path_Locator_IteratorAbstract
33
+ {
34
+ // {{{ properties
35
+
36
+ /**
37
+ * Locator implementation
38
+ * @var Bronto_ConflictChecker_Model_Path_Locator_LocatorInterface
39
+ * @access protected
40
+ */
41
+ protected $_iterator = null;
42
+
43
+ // }}}
44
+ // {{{ __construct()
45
+
46
+ /**
47
+ * Constructor
48
+ *
49
+ * @param Bronto_ConflictChecker_Model_Path_Locator_LocatorInterface $iterator
50
+ *
51
+ * @return void
52
+ * @access public
53
+ */
54
+ public function __construct($iterator)
55
+ {
56
+ $this->_iterator = $iterator;
57
+ }
58
+
59
+ // }}}
60
+ }
app/code/community/Bronto/ConflictChecker/Model/Path/Locator/LocatorInterface.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Path locator interface
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Path locator interface
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ interface Bronto_ConflictChecker_Model_Path_Locator_LocatorInterface
33
+ {
34
+ // {{{ getPath()
35
+
36
+ /**
37
+ * Gets a path to a node
38
+ *
39
+ * Pass in the child node and will recurse up the XML tree to print out
40
+ * the path in the tree to that node
41
+ *
42
+ * <config>
43
+ * <path>
44
+ * <to>
45
+ * <node>
46
+ * Node Value
47
+ * </node>
48
+ * </to>
49
+ * </path>
50
+ * </config>
51
+ *
52
+ * If you pass in the "node" object, this will print out
53
+ * config/path/to/node/
54
+ *
55
+ * @param SimpleXmlElement $element Child element to find path to
56
+ *
57
+ * @return string
58
+ * @access public
59
+ */
60
+ public function getPath(SimpleXmlElement $element);
61
+
62
+ // }}}
63
+ }
app/code/community/Bronto/ConflictChecker/Model/Path/Locator/Stack.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * SPL Stack implementation of XML path locator
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+
21
+ /**
22
+ * SPL Stack implementation of XML path locator
23
+ *
24
+ * @category Bronto
25
+ * @package ConflictChecker
26
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
27
+ * @copyright 2012 Atlantic BT
28
+ * @license http://www.atlanticbt.com/ Atlantic BT
29
+ * @version Release: @package_version@
30
+ * @link <>
31
+ * @see References to other sections (if any)...
32
+ */
33
+ class Bronto_ConflictChecker_Model_Path_Locator_Stack
34
+ extends Bronto_ConflictChecker_Model_Path_Locator_IteratorAbstract
35
+ implements Bronto_ConflictChecker_Model_Path_Locator_LocatorInterface
36
+ {
37
+ // {{{ getPath()
38
+
39
+ /**
40
+ * Gets a path to a node via SPL Stack implementation
41
+ *
42
+ * Pass in the child node and will recurse up the XML tree to print out
43
+ * the path in the tree to that node
44
+ *
45
+ * <config>
46
+ * <path>
47
+ * <to>
48
+ * <node>
49
+ * Node Value
50
+ * </node>
51
+ * </to>
52
+ * </path>
53
+ * </config>
54
+ *
55
+ * If you pass in the "node" object, this will print out
56
+ * config/path/to/node/
57
+ *
58
+ * @param SimpleXmlElement $element Child element to find path to
59
+ *
60
+ * @return string
61
+ * @access public
62
+ */
63
+ public function getPath(SimpleXmlElement $element)
64
+ {
65
+ $this->_iterator->push($element->getName() . '/');
66
+ if (!$element->getSafeParent()) {
67
+ return $this->_iterator->pop();
68
+ }
69
+ return $this->getPath($element->getParent()) . $this->_iterator->pop();
70
+ }
71
+
72
+ // }}}
73
+ }
app/code/community/Bronto/ConflictChecker/Model/Resource/Core/Config.php ADDED
@@ -0,0 +1,260 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * DB config
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package ConflictChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * DB config
22
+ *
23
+ * @category Bronto
24
+ * @package ConflictChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_ConflictChecker_Model_Resource_Core_Config
33
+ extends Mage_Core_Model_Resource_Db_Abstract
34
+ {
35
+ // {{{ _construct()
36
+
37
+ /**
38
+ * psuedo constructor
39
+ *
40
+ * Define main table
41
+ *
42
+ * @return void
43
+ * @access protected
44
+ */
45
+ protected function _construct()
46
+ {
47
+ $this->_init('core/config_data', 'config_id');
48
+ }
49
+
50
+ // }}}
51
+ // {{{ loadToXml()
52
+
53
+ /**
54
+ * Load configuration values into xml config object
55
+ *
56
+ * @param Mage_Core_Model_Config $xmlConfig
57
+ * @param string $condition
58
+ *
59
+ * @return Mage_Core_Model_Resource_Config
60
+ * @access public
61
+ */
62
+ public function loadToXml(
63
+ Bronto_ConflictChecker_Model_Core_Config $xmlConfig,
64
+ $condition = null
65
+ ) {
66
+ $read = $this->_getReadAdapter();
67
+ if (!$read) {
68
+ return $this;
69
+ }
70
+
71
+ $websites = array();
72
+ $select = $read->select()
73
+ ->from($this->getTable('core/website'), array('website_id', 'code', 'name'));
74
+ $rowset = $read->fetchAssoc($select);
75
+ foreach ($rowset as $w) {
76
+ $xmlConfig->setNode('websites/'.$w['code'].'/system/website/id', $w['website_id']);
77
+ $xmlConfig->setNode('websites/'.$w['code'].'/system/website/name', $w['name']);
78
+ $websites[$w['website_id']] = array('code' => $w['code']);
79
+ }
80
+
81
+ $stores = array();
82
+ $select = $read->select()
83
+ ->from($this->getTable('core/store'), array('store_id', 'code', 'name', 'website_id'))
84
+ ->order('sort_order ' . Varien_Db_Select::SQL_ASC);
85
+ $rowset = $read->fetchAssoc($select);
86
+ foreach ($rowset as $s) {
87
+ if (!isset($websites[$s['website_id']])) {
88
+ continue;
89
+ }
90
+ $xmlConfig->setNode('stores/'.$s['code'].'/system/store/id', $s['store_id']);
91
+ $xmlConfig->setNode('stores/'.$s['code'].'/system/store/name', $s['name']);
92
+ $xmlConfig->setNode('stores/'.$s['code'].'/system/website/id', $s['website_id']);
93
+ $xmlConfig->setNode('websites/'.$websites[$s['website_id']]['code'].'/system/stores/'.$s['code'], $s['store_id']);
94
+ $stores[$s['store_id']] = array('code'=>$s['code']);
95
+ $websites[$s['website_id']]['stores'][$s['store_id']] = $s['code'];
96
+ }
97
+
98
+ $substFrom = array();
99
+ $substTo = array();
100
+
101
+ // load all configuration records from database, which are not inherited
102
+ $select = $read->select()
103
+ ->from($this->getMainTable(), array('scope', 'scope_id', 'path', 'value'));
104
+ if (!is_null($condition)) {
105
+ $select->where($condition);
106
+ }
107
+ $rowset = $read->fetchAll($select);
108
+
109
+
110
+ // set default config values from database
111
+ foreach ($rowset as $r) {
112
+ if ($r['scope'] !== 'default') {
113
+ continue;
114
+ }
115
+ $value = str_replace($substFrom, $substTo, $r['value']);
116
+ $xmlConfig->setNode('default/' . $r['path'], $value);
117
+ }
118
+
119
+ // inherit default config values to all websites
120
+ $extendSource = $xmlConfig->getNode('default');
121
+ foreach ($websites as $id=>$w) {
122
+ $websiteNode = $xmlConfig->getNode('websites/' . $w['code']);
123
+ $websiteNode->extend($extendSource);
124
+ }
125
+
126
+ $deleteWebsites = array();
127
+ // set websites config values from database
128
+ foreach ($rowset as $r) {
129
+ if ($r['scope'] !== 'websites') {
130
+ continue;
131
+ }
132
+ $value = str_replace($substFrom, $substTo, $r['value']);
133
+ if (isset($websites[$r['scope_id']])) {
134
+ $nodePath = sprintf('websites/%s/%s', $websites[$r['scope_id']]['code'], $r['path']);
135
+ $xmlConfig->setNode($nodePath, $value);
136
+ } else {
137
+ $deleteWebsites[$r['scope_id']] = $r['scope_id'];
138
+ }
139
+ }
140
+
141
+ // extend website config values to all associated stores
142
+ foreach ($websites as $website) {
143
+ $extendSource = $xmlConfig->getNode('websites/' . $website['code']);
144
+ if (isset($website['stores'])) {
145
+ foreach ($website['stores'] as $sCode) {
146
+ $storeNode = $xmlConfig->getNode('stores/'.$sCode);
147
+ /**
148
+ * $extendSource DO NOT need overwrite source
149
+ */
150
+ $storeNode->extend($extendSource, false);
151
+ }
152
+ }
153
+ }
154
+
155
+ $deleteStores = array();
156
+ // set stores config values from database
157
+ foreach ($rowset as $r) {
158
+ if ($r['scope'] !== 'stores') {
159
+ continue;
160
+ }
161
+ $value = str_replace($substFrom, $substTo, $r['value']);
162
+ if (isset($stores[$r['scope_id']])) {
163
+ $nodePath = sprintf('stores/%s/%s', $stores[$r['scope_id']]['code'], $r['path']);
164
+ $xmlConfig->setNode($nodePath, $value);
165
+ } else {
166
+ $deleteStores[$r['scope_id']] = $r['scope_id'];
167
+ }
168
+ }
169
+
170
+ if ($deleteWebsites) {
171
+ $this->_getWriteAdapter()->delete(
172
+ $this->getMainTable(),
173
+ array(
174
+ 'scope = ?' => 'websites',
175
+ 'scope_id IN(?)' => $deleteWebsites,
176
+ )
177
+ );
178
+ }
179
+
180
+ if ($deleteStores) {
181
+ $this->_getWriteAdapter()->delete(
182
+ $this->getMainTable(),
183
+ array(
184
+ 'scope=?' => 'stores',
185
+ 'scope_id IN(?)' => $deleteStores,
186
+ )
187
+ );
188
+ }
189
+ return $this;
190
+ }
191
+
192
+ // }}}
193
+ // {{{ saveConfig()
194
+
195
+ /**
196
+ * Save config value
197
+ *
198
+ * @param string $path
199
+ * @param string $value
200
+ * @param string $scope
201
+ * @param int $scopeId
202
+ *
203
+ * @return Mage_Core_Model_Resource_Config
204
+ * @access public
205
+ */
206
+ public function saveConfig($path, $value, $scope, $scopeId)
207
+ {
208
+ $writeAdapter = $this->_getWriteAdapter();
209
+ $select = $writeAdapter->select()
210
+ ->from($this->getMainTable())
211
+ ->where('path = ?', $path)
212
+ ->where('scope = ?', $scope)
213
+ ->where('scope_id = ?', $scopeId);
214
+ $row = $writeAdapter->fetchRow($select);
215
+
216
+ $newData = array(
217
+ 'scope' => $scope,
218
+ 'scope_id' => $scopeId,
219
+ 'path' => $path,
220
+ 'value' => $value
221
+ );
222
+
223
+ if ($row) {
224
+ $whereCondition = array($this->getIdFieldName() . '=?' => $row[$this->getIdFieldName()]);
225
+ $writeAdapter->update($this->getMainTable(), $newData, $whereCondition);
226
+ } else {
227
+ $writeAdapter->insert($this->getMainTable(), $newData);
228
+ }
229
+ return $this;
230
+ }
231
+
232
+ // }}}
233
+ // {{{ deleteConfig()
234
+
235
+ /**
236
+ * Delete config value
237
+ *
238
+ * @param string $path
239
+ * @param string $scope
240
+ * @param int $scopeId
241
+ *
242
+ * @return Mage_Core_Model_Resource_Config
243
+ * @access public
244
+ */
245
+ public function deleteConfig($path, $scope, $scopeId)
246
+ {
247
+ $adapter = $this->_getWriteAdapter();
248
+ $adapter->delete(
249
+ $this->getMainTable(),
250
+ array(
251
+ $adapter->quoteInto('path = ?', $path),
252
+ $adapter->quoteInto('scope = ?', $scope),
253
+ $adapter->quoteInto('scope_id = ?', $scopeId)
254
+ )
255
+ );
256
+ return $this;
257
+ }
258
+
259
+ // }}}
260
+ }
app/code/community/Bronto/ConflictChecker/Test/Config/Config.php ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_ConflictChecker_Test_Config_Config
3
+ extends EcomDev_PHPUnit_Test_Case_Config
4
+ {
5
+ // {{{ blocksProvider()
6
+
7
+ public function blocksProvider()
8
+ {
9
+ return array(
10
+ array('bronto_conflictchecker/adminhtml_system_config_conflictchecker', 'Bronto_ConflictChecker_Block_Adminhtml_System_Config_Conflictchecker'),
11
+ );
12
+ }
13
+
14
+ // }}}
15
+ // {{{ resourceModelProvider()
16
+
17
+ public function resourceModelProvider()
18
+ {
19
+ return array(
20
+ array('bronto_conflictchecker/mysql4_core_config', 'Bronto_ConflictChecker_Model_Mysql4_Core_Config'),
21
+ array('bronto_conflictchecker/resource_core_config', 'Bronto_ConflictChecker_Model_Resource_Core_Config'),
22
+ );
23
+ }
24
+
25
+ // }}}
26
+ // {{{ modelsProvider()
27
+
28
+ public function modelsProvider()
29
+ {
30
+ return array(
31
+ array('bronto_conflictchecker/core_config_element', 'Bronto_ConflictChecker_Model_Core_Config_Element'),
32
+ array('bronto_conflictchecker/core_config_base', 'Bronto_ConflictChecker_Model_Core_Config_Base'),
33
+ array('bronto_conflictchecker/core_config', 'Bronto_ConflictChecker_Model_Core_Config'),
34
+ array('bronto_conflictchecker/config_blocks', 'Bronto_ConflictChecker_Model_Config_Blocks'),
35
+ array('bronto_conflictchecker/config_printer', 'Bronto_ConflictChecker_Model_Config_Printer'),
36
+ array('bronto_conflictchecker/config_checker', 'Bronto_ConflictChecker_Model_Config_Checker'),
37
+ array('bronto_conflictchecker/config_configabstract', 'Bronto_ConflictChecker_Model_Config_Configabstract'),
38
+ array('bronto_conflictchecker/config_configinterface', 'Bronto_ConflictChecker_Model_Config_Configinterface'),
39
+ array('bronto_conflictchecker/config_datastore', 'Bronto_ConflictChecker_Model_Config_Datastore'),
40
+ array('bronto_conflictchecker/config_helpers', 'Bronto_ConflictChecker_Model_Config_Helpers'),
41
+ array('bronto_conflictchecker/config_models', 'Bronto_ConflictChecker_Model_Config_Models'),
42
+ array('bronto_conflictchecker/config_printer', 'Bronto_ConflictChecker_Model_Config_Printer'),
43
+ array('bronto_conflictchecker/config_resources', 'Bronto_ConflictChecker_Model_Config_Resources'),
44
+ );
45
+ }
46
+
47
+ // }}}
48
+ // {{{ helpersProvider()
49
+
50
+ public function helpersProvider()
51
+ {
52
+ return array(
53
+ array('bronto_conflictchecker/data', 'Bronto_ConflictChecker_Helper_Data'),
54
+ );
55
+ }
56
+
57
+ // }}}
58
+ // {{{ observersProvider()
59
+
60
+ public function observersProvider()
61
+ {
62
+ return array(
63
+ /*array('global', 'customer_save_before', 'user/observer', 'accountUpgrade'),*/
64
+ );
65
+ }
66
+
67
+ // }}}
68
+ // {{{ definedLayoutFilesProvider()
69
+
70
+ public function definedLayoutFilesProvider()
71
+ {
72
+ return array(
73
+ /*array('frontend', 'bronto/user.xml'),*/
74
+ );
75
+ }
76
+
77
+ // }}}
78
+ // {{{ themeLayoutFilesExistProvider()
79
+
80
+ public function themeLayoutFilesExistProvider()
81
+ {
82
+ return array(
83
+ /*array('frontend', 'bronto/user.xml', 'adsinc', 'adsinc'),*/
84
+ );
85
+ }
86
+
87
+ // }}}
88
+
89
+ public function dependsProvider()
90
+ {
91
+ return array(
92
+ array('Bronto_Common'),
93
+ );
94
+ }
95
+
96
+ // {{{ assertConflictCheckerModuleInLocalCodePool()
97
+
98
+
99
+ /**
100
+ * @test
101
+ * @group amd
102
+ * @group config
103
+ */
104
+ public function assertCommonModuleVersionGreaterThanOrEquals()
105
+ {
106
+ $this->assertModuleVersionGreaterThanOrEquals('0.1.0');
107
+ }
108
+
109
+
110
+ /**
111
+ * @test
112
+ * @group jmk
113
+ * @group config
114
+ */
115
+ public function assertConflictCheckerModuleInCommunityCodePool()
116
+ {
117
+ $this->assertModuleCodePool('community');
118
+ }
119
+
120
+ // }}}
121
+
122
+ /**
123
+ * Note: Switched to NotDepends to ensure this module doesn't become dependent upon common
124
+ * @test
125
+ * @group amd
126
+ * @group config
127
+ * @dataProvider dependsProvider
128
+ */
129
+ public function assertConflictCheckerNotDepends(
130
+ $requiredModuleName
131
+ ) {
132
+ $this->assertModuleNotDepends($requiredModuleName);
133
+ }
134
+
135
+ // {{{ assertConflictCheckerModelAliases()
136
+
137
+ /**
138
+ * @test
139
+ * @group jmk
140
+ * @group config
141
+ * @dataProvider modelsProvider
142
+ */
143
+ public function assertConflictCheckerModelAliases(
144
+ $classAlias,
145
+ $expectedClassName
146
+ ) {
147
+ $this->assertModelAlias($classAlias, $expectedClassName);
148
+ }
149
+
150
+ // }}}
151
+ // {{{ assertConflictCheckerResourceModelAliases()
152
+
153
+ /**
154
+ * test
155
+ * @group jmk
156
+ * @group config
157
+ * @dataProvider resourceModelProvider
158
+ */
159
+ public function assertConflictCheckerResourceModelAliases(
160
+ $classAlias,
161
+ $expectedClassName
162
+ ) {
163
+ $this->assertResourceModelAlias($classAlias, $expectedClassName);
164
+ }
165
+
166
+ // }}}
167
+ // {{{ assertConflictCheckerBlockAliases()
168
+
169
+ /**
170
+ * @test
171
+ * @group jmk
172
+ * @group config
173
+ * @dataProvider blocksProvider
174
+ */
175
+ public function assertConflictCheckerBlockAliases(
176
+ $classAlias,
177
+ $expectedClassName
178
+ ) {
179
+ $this->assertBlockAlias($classAlias, $expectedClassName);
180
+ }
181
+
182
+ // }}}
183
+ // {{{ assertConflictCheckerHelperAliases()
184
+
185
+ /**
186
+ * @test
187
+ * @group jmk
188
+ * @group config
189
+ * @dataProvider helpersProvider
190
+ */
191
+ public function assertConflictCheckerHelperAliases(
192
+ $classAlias,
193
+ $expectedClassName
194
+ ) {
195
+ $this->assertHelperAlias($classAlias, $expectedClassName);
196
+ }
197
+
198
+ // }}}
199
+ // {{{ assertConflictCheckerEventObserversDefined()
200
+
201
+ /**
202
+ * test
203
+ * @group config
204
+ * @group jmk
205
+ * @dataProvider observersProvider
206
+ */
207
+ public function assertConflictCheckerEventObserversDefined(
208
+ $area,
209
+ $eventName,
210
+ $observerClassAlias,
211
+ $observerMethod
212
+ ) {
213
+ $this->assertEventObserverDefined(
214
+ $area,
215
+ $eventName,
216
+ $observerClassAlias,
217
+ $observerMethod
218
+ );
219
+ }
220
+
221
+ // }}}
222
+ // {{{ assertConflictCheckerLayoutFileDefined()
223
+
224
+ /**
225
+ * test
226
+ * @group config
227
+ * @group jmk
228
+ * @dataProvider definedLayoutFilesProvider
229
+ */
230
+ public function assertConflictCheckerLayoutFileDefined($area, $expectedFileName)
231
+ {
232
+ $this->assertLayoutFileDefined($area, $expectedFileName);
233
+ }
234
+
235
+ // }}}
236
+ // {{{ assertConflictCheckerLayoutFileExistsForDefaultTheme()
237
+
238
+ /**
239
+ * test
240
+ * @group config
241
+ * @group jmk
242
+ * @dataProvider themeLayoutFilesExistProvider
243
+ */
244
+ public function assertConflictCheckerLayoutFileExistsForDefaultTheme(
245
+ $area,
246
+ $filename,
247
+ $theme,
248
+ $designPackage
249
+ ) {
250
+ $this->assertLayoutFileExistsInTheme(
251
+ $area,
252
+ $filename,
253
+ $theme,
254
+ $designPackage
255
+ );
256
+ }
257
+
258
+ // }}}
259
+ }
app/code/community/Bronto/ConflictChecker/Test/Model/Path/Locator/Array.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_ConflictChecker_Test_Model_Path_Locator_Array
3
+ extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+ // {{{ getPathWithArrayShouldReturnPathAsString()
6
+
7
+ /**
8
+ * @test
9
+ * @group jmk
10
+ * @group model
11
+ */
12
+ public function getPathWithArrayShouldReturnPathAsString()
13
+ {
14
+ $locator = new Bronto_ConflictChecker_Model_Path_Locator_Array(array());
15
+
16
+ $xmlString = "<config><path><to><node>node value</node></to></path></config>";
17
+ $xml = new Bronto_ConflictChecker_Model_Lib_Varien_Simplexml_Element($xmlString);
18
+ list($element) = $xml->xpath('/config/path/to/node');
19
+
20
+ $path = $locator->getPath($element);
21
+ $this->assertEquals('config/path/to/node/', $locator->getpath($element));
22
+ }
23
+
24
+ // }}}
25
+ }
app/code/community/Bronto/ConflictChecker/Test/Model/Path/Locator/Factory.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Bronto_ConflictChecker_Test_Model_Path_Locator_Factory
4
+ extends EcomDev_PHPUnit_Test_Case
5
+ {
6
+ // {{{ getLocatorShouldReturnCorrectModel()
7
+
8
+ /**
9
+ * @test
10
+ * @group jmk
11
+ * @group model
12
+ */
13
+ public function getLocatorShouldReturnCorrectModel()
14
+ {
15
+ $factory = new Bronto_ConflictChecker_Model_Path_Locator_Factory;
16
+
17
+ $locator = $factory->getLocator();
18
+ }
19
+
20
+ // }}}
21
+ }
app/code/community/Bronto/ConflictChecker/Test/Model/Path/Locator/Stack.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_ConflictChecker_Test_Model_Path_Locator_Stack
3
+ extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+ // {{{ getPathWithStackShouldReturnPathAsString()
6
+
7
+ /**
8
+ * @test
9
+ * @group jmk
10
+ * @group model
11
+ */
12
+ public function getPathWithStackShouldReturnPathAsString()
13
+ {
14
+ $locator = new Bronto_ConflictChecker_Model_Path_Locator_Stack(new SplStack);
15
+
16
+ $xmlString = "<config><path><to><node>node value</node></to></path></config>";
17
+ $xml = new Bronto_ConflictChecker_Model_Lib_Varien_Simplexml_Element($xmlString);
18
+ list($element) = $xml->xpath('/config/path/to/node');
19
+
20
+ $path = $locator->getPath($element);
21
+ $this->assertEquals('config/path/to/node/', $locator->getpath($element));
22
+ }
23
+
24
+ // }}}
25
+ }
app/code/community/Bronto/ConflictChecker/etc/adminhtml.xml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * @category Bronto
5
+ * @package Bronto_ConflictChecker
6
+ * @author Jamie Kahgee <jamie.kahgee@atlanticBT.com>
7
+ * @copyright 2012 Atlantic BT
8
+ * @license http://www.atlanticbt.com/ Atlantic BT
9
+ */
10
+ -->
11
+ <config>
12
+ <acl>
13
+ <resources>
14
+ <admin>
15
+ <children>
16
+ <system>
17
+ <children>
18
+ <config>
19
+ <children>
20
+ <conflicted_modules translate="title" module="bronto_conflictchecker">
21
+ <title>Conflict Checker</title>
22
+ <sort_order>0</sort_order>
23
+ </conflicted_modules>
24
+ </children>
25
+ </config>
26
+ </children>
27
+ </system>
28
+ </children>
29
+ </admin>
30
+ </resources>
31
+ </acl>
32
+ </config>
app/code/community/Bronto/ConflictChecker/etc/config.xml ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * @category Bronto
5
+ * @package Bronto_ConflictChecker
6
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
7
+ * @copyright 2012 Atlantic BT
8
+ * @license http://www.atlanticbt.com/ Atlantic BT
9
+ */
10
+ -->
11
+ <config>
12
+ <modules>
13
+ <Bronto_ConflictChecker>
14
+ <version>0.1.0</version>
15
+ </Bronto_ConflictChecker>
16
+ </modules>
17
+
18
+ <global>
19
+ <blocks>
20
+ <bronto_conflictchecker>
21
+ <class>Bronto_ConflictChecker_Block</class>
22
+ </bronto_conflictchecker>
23
+ </blocks>
24
+
25
+ <helpers>
26
+ <bronto_conflictchecker>
27
+ <class>Bronto_ConflictChecker_Helper</class>
28
+ </bronto_conflictchecker>
29
+ </helpers>
30
+
31
+ <models>
32
+ <bronto_conflictchecker>
33
+ <class>Bronto_ConflictChecker_Model</class>
34
+ <resourceModel>bronto_conflictchecker_mysql4</resourceModel>
35
+ </bronto_conflictchecker>
36
+ <bronto_conflictchecker_mysql4>
37
+ <class>Bronto_ConflictChecker_Model_Mysql4</class>
38
+ </bronto_conflictchecker_mysql4>
39
+ </models>
40
+ </global>
41
+ <admin>
42
+ <routers>
43
+ <adminhtml>
44
+ <args>
45
+ <modules>
46
+ <bronto_conflictchecker before="Mage_Adminhtml">Bronto_ConflictChecker_Adminhtml</bronto_conflictchecker>
47
+ </modules>
48
+ </args>
49
+ </adminhtml>
50
+ </routers>
51
+ </admin>
52
+
53
+ <phpunit>
54
+ <suite>
55
+ <modules>
56
+ <Bronto_ConflictChecker />
57
+ </modules>
58
+ </suite>
59
+ </phpunit>
60
+ </config>
app/code/community/Bronto/ConflictChecker/etc/system.xml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <conflicted_modules translate="label" module="core">
5
+ <label>Conflict Checker</label>
6
+ <tab>bronto</tab>
7
+ <frontend_type>text</frontend_type>
8
+ <sort_order>1100</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
+ <about>
14
+ <frontend_type>text</frontend_type>
15
+ <frontend_model>bronto_conflictchecker/adminhtml_system_config_about</frontend_model>
16
+ <sort_order>1</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
+ </about>
21
+ <conflictchecker>
22
+ <frontend_type>text</frontend_type>
23
+ <frontend_model>bronto_conflictchecker/adminhtml_system_config_conflictchecker</frontend_model>
24
+ <sort_order>2</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ </conflictchecker>
29
+ </groups>
30
+ </conflicted_modules>
31
+ </sections>
32
+ </config>
app/code/community/Bronto/Customer/Block/Adminhtml/System/Config/About.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.0.0
7
+ */
8
+ class Bronto_Customer_Block_Adminhtml_System_Config_About extends Bronto_Common_Block_Adminhtml_System_Config_About
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_module = 'bronto_customer';
14
+
15
+ /**
16
+ * @var string
17
+ */
18
+ protected $_name = 'Bronto Customer Import for Magento';
19
+ }
app/code/community/Bronto/Customer/Block/Adminhtml/System/Config/Cron.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Customer_Block_Adminhtml_System_Config_Cron extends Bronto_Common_Block_Adminhtml_System_Config_Cron
9
+ {
10
+ protected $_jobCode = 'bronto_customer_import';
11
+ protected $_hasProgressBar = true;
12
+
13
+ /**
14
+ * @return Bronto_Order_Block_Adminhtml_System_Config_Cron
15
+ */
16
+ protected function _prepareLayout()
17
+ {
18
+ $this->addButton($this->getLayout()->createBlock('bronto_customer/adminhtml_widget_button_reset'));
19
+ $this->addButton($this->getLayout()->createBlock('bronto_customer/adminhtml_widget_button_run'));
20
+
21
+ return parent::_prepareLayout();
22
+ }
23
+
24
+ /**
25
+ * @return int
26
+ */
27
+ protected function getProgressBarTotal()
28
+ {
29
+ return $this->getCustomerResourceCollection()
30
+ ->getSize()
31
+ ;
32
+ }
33
+
34
+ /**
35
+ * @return int
36
+ */
37
+ protected function getProgressBarPending()
38
+ {
39
+ return $this->getCustomerResourceCollection()
40
+ ->addBrontoNotImportedFilter()
41
+ ->getSize()
42
+ ;
43
+ }
44
+
45
+ /**
46
+ * @return Bronto_Customer_Model_Resource_Customer_Collection
47
+ */
48
+ protected function getCustomerResourceCollection()
49
+ {
50
+ $collection = Mage::getModel('bronto_customer/resource_customer_collection');
51
+
52
+ if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
53
+ $store = Mage::app()->getStore($storeCode);
54
+ $collection->addStoreFilter($store->getId());
55
+ } else if ($websiteCode = Mage::app()->getRequest()->getParam('website')){
56
+ $website = Mage::app()->getWebsite($websiteCode);
57
+ $collection->addStoreFilter($website->getStoreids());
58
+ } else if ($groupCode = Mage::app()->getRequest()->getParam('group')){
59
+ $website = Mage::app()->getGroup($groupCode)->getWebsite();
60
+ $collection->addStoreFilter($website->getStoreids());
61
+ }
62
+
63
+ return $collection;
64
+ }
65
+ }
app/code/community/Bronto/Customer/Block/Adminhtml/System/Config/Form/Fieldset/Attributes.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.0.0
7
+ */
8
+ abstract class Bronto_Customer_Block_Adminhtml_System_Config_Form_Fieldset_Attributes extends Mage_Adminhtml_Block_System_Config_Form_Fieldset
9
+ {
10
+ protected $_ignoreAttributes = array();
11
+ protected $_clonedSelect;
12
+ protected $_clonedSelectName;
13
+ protected $_clonedText;
14
+ protected $_clonedTextName;
15
+
16
+ /**
17
+ * Return header html for fieldset
18
+ *
19
+ * @param Varien_Data_Form_Element_Fieldset $fieldset
20
+ * @return string
21
+ */
22
+ protected function _getHeaderHtml($fieldset)
23
+ {
24
+ $ignoreAttributeCodes = $this->_getUsedAttributeCodes($fieldset);
25
+ $ignoreAttributeCodes = array_merge($ignoreAttributeCodes, $this->_ignoreAttributes);
26
+
27
+ // Append any extra Customer attributes
28
+ foreach ($this->_getAttributes() as $_attributeId => $_attribute) {
29
+ $_attributeCode = $_attribute->getAttributeCode();
30
+ if (in_array($_attributeCode, $ignoreAttributeCodes)) {
31
+ continue;
32
+ }
33
+
34
+ if ($_label = $_attribute->getFrontendLabel()) {
35
+ // Add select
36
+ $appendSelect = clone $this->_clonedSelect;
37
+ $appendSelect->setLabel($_label);
38
+ $appendSelect->setId(str_replace($this->_clonedSelectName, $_attributeCode, $appendSelect->getId()));
39
+ $appendSelect->setHtmlId(str_replace($this->_clonedSelectName, $_attributeCode, $appendSelect->getHtmlId()));
40
+ $appendSelect->setName(str_replace($this->_clonedSelectName, $_attributeCode, $appendSelect->getName()));
41
+ $fieldset->addElement($appendSelect);
42
+
43
+ // Add custom field name input
44
+ $appendText = clone $this->_clonedText;
45
+ $appendText->setId(str_replace($this->_clonedTextName, "new_{$_attributeCode}", $appendText->getId()));
46
+ $appendText->setHtmlId(str_replace($this->_clonedTextName, "new_{$_attributeCode}", $appendText->getHtmlId()));
47
+ $appendText->setName(str_replace($this->_clonedTextName, "new_{$_attributeCode}", $appendText->getName()));
48
+ $fieldset->addElement($appendText);
49
+
50
+ // Field dependencies
51
+ $this->getForm()->getChild('element_dependense')
52
+ ->addFieldMap($appendSelect->getHtmlId(), $appendSelect->getName())
53
+ ->addFieldMap($appendText->getHtmlId(), $appendText->getName())
54
+ ->addFieldDependence($appendText->getName(), $appendSelect->getName(), '_new_')
55
+ ;
56
+ }
57
+ }
58
+
59
+ return parent::_getHeaderHtml($fieldset);
60
+ }
61
+
62
+ abstract protected function _getAttributes();
63
+
64
+ /**
65
+ * @param Varien_Data_Form_Element_Fieldset $fieldset
66
+ * @return array<string>
67
+ */
68
+ protected function _getUsedAttributeCodes(Varien_Data_Form_Element_Fieldset $fieldset)
69
+ {
70
+ $usedAttributeCodes = array();
71
+ foreach ($fieldset->getSortedElements() as $_element) {
72
+ // Determine the *actual* name for this select box
73
+ preg_match('/\[(\w+)\]\[value\]/', $_element->getName(), $matches);
74
+ if (isset($matches[1])) {
75
+ if (stripos($_element->getName(), 'new_') === false) {
76
+ $this->_clonedSelect = $_element;
77
+ $this->_clonedSelectName = $matches[1];
78
+ } else {
79
+ $this->_clonedText = $_element;
80
+ $this->_clonedTextName = $matches[1];
81
+ }
82
+
83
+ // Add to list
84
+ $usedAttributeCodes[] = $matches[1];
85
+ }
86
+ }
87
+
88
+ return $usedAttributeCodes;
89
+ }
90
+ }
app/code/community/Bronto/Customer/Block/Adminhtml/System/Config/Form/Fieldset/Attributes/Address.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.0.0
7
+ */
8
+ class Bronto_Customer_Block_Adminhtml_System_Config_Form_Fieldset_Attributes_Address extends Bronto_Customer_Block_Adminhtml_System_Config_Form_Fieldset_Attributes
9
+ {
10
+ /**
11
+ * @var array<Mage_Customer_Model_Attribute>
12
+ */
13
+ private $_addressAttributes;
14
+
15
+ /**
16
+ * @var array<string>
17
+ */
18
+ protected $_ignoreAttributes = array(
19
+ 'firstname',
20
+ 'lastname',
21
+ 'middlename',
22
+ 'prefix',
23
+ 'region_id',
24
+ 'suffix',
25
+ );
26
+
27
+ /**
28
+ * @return array
29
+ */
30
+ protected function _getAttributes()
31
+ {
32
+ return $this->_getAddressAttributes();
33
+ }
34
+
35
+ /**
36
+ * @return array
37
+ */
38
+ private function _getAddressAttributes()
39
+ {
40
+ if ($this->_addressAttributes === null) {
41
+ $this->_addressAttributes = Mage::getModel('customer/entity_address_attribute_collection')->addVisibleFilter();
42
+ }
43
+
44
+ return $this->_addressAttributes;
45
+ }
46
+ }
app/code/community/Bronto/Customer/Block/Adminhtml/System/Config/Form/Fieldset/Attributes/Customer.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.0.0
7
+ */
8
+ class Bronto_Customer_Block_Adminhtml_System_Config_Form_Fieldset_Attributes_Customer extends Bronto_Customer_Block_Adminhtml_System_Config_Form_Fieldset_Attributes
9
+ {
10
+ /**
11
+ * @var array<Mage_Customer_Model_Attribute>
12
+ */
13
+ private $_customerAttributes;
14
+
15
+ /**
16
+ * @var array<string>
17
+ */
18
+ protected $_ignoreAttributes = array(
19
+ 'increment_id',
20
+ 'updated_at',
21
+ 'entity_id',
22
+ 'attribute_set_id',
23
+ 'entity_type_id',
24
+ 'password_hash',
25
+ 'default_billing',
26
+ 'default_shipping',
27
+ 'email',
28
+ 'confirmation',
29
+ 'reward_update_notification',
30
+ 'reward_warning_notification',
31
+ );
32
+
33
+ /**
34
+ * @return array
35
+ */
36
+ protected function _getAttributes()
37
+ {
38
+ return $this->_getCustomerAttributes();
39
+ }
40
+
41
+ /**
42
+ * @return array
43
+ */
44
+ private function _getCustomerAttributes()
45
+ {
46
+ if ($this->_customerAttributes === null) {
47
+ $this->_customerAttributes = Mage::getModel('customer/entity_attribute_collection')->addVisibleFilter();
48
+ }
49
+
50
+ return $this->_customerAttributes;
51
+ }
52
+ }
app/code/community/Bronto/Customer/Block/Adminhtml/Widget/Button/Reset.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Customer_Block_Adminhtml_Widget_Button_Reset extends Mage_Adminhtml_Block_Widget_Button
9
+ {
10
+ /**
11
+ * Internal constructor not depended on params. Can be used for object initialization
12
+ */
13
+ protected function _construct()
14
+ {
15
+ $this->setLabel('Reset All Customers');
16
+ $this->setOnClick("deleteConfirm('This will mark all customers as not-imported and will cause the importer to re-process each customer again.\\n\\nAre you sure you want to do this?', '" . Mage::helper('adminhtml')->getUrl('*/customer/reset') . "'); return false;");
17
+ $this->setClass('delete');
18
+
19
+ if (!extension_loaded('soap') || !extension_loaded('openssl') || !Mage::helper('bronto_common')->getApiToken() || !Mage::helper('bronto_customer')->isEnabled() || (!Mage::helper('bronto_customer')->isDebugEnabled() && !Mage::helper('bronto_customer')->isTestModeEnabled())) {
20
+ $this->setDisabled(true)->setClass('disabled');
21
+ }
22
+ }
23
+ }
app/code/community/Bronto/Customer/Block/Adminhtml/Widget/Button/Run.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Customer_Block_Adminhtml_Widget_Button_Run extends Mage_Adminhtml_Block_Widget_Button
9
+ {
10
+ /**
11
+ * Internal constructor not depended on params. Can be used for object initialization
12
+ */
13
+ protected function _construct()
14
+ {
15
+ $this->setLabel('Run Now');
16
+ $this->setOnClick("setLocation('" . Mage::helper('adminhtml')->getUrl('*/customer/run') . "'); return false;");
17
+
18
+ if (!extension_loaded('soap') || !extension_loaded('openssl') || !Mage::helper('bronto_common')->getApiToken() || !Mage::helper('bronto_customer')->isEnabled()) {
19
+ $this->setDisabled(true)->setClass('disabled');
20
+ }
21
+ }
22
+ }
app/code/community/Bronto/Customer/Helper/Data.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.0.0
7
+ */
8
+ class Bronto_Customer_Helper_Data extends Bronto_Common_Helper_Data implements Bronto_Common_Helper_DataInterface
9
+ {
10
+ const XML_PATH_ENABLED = 'bronto_customer/settings/enabled';
11
+ const XML_PATH_LIMIT = 'bronto_customer/settings/limit';
12
+ const XML_PATH_INSTALL_DATE = 'bronto_customer/settings/install_date';
13
+ const XML_PATH_UPGRADE_DATE = 'bronto_customer/settings/upgrade_date';
14
+
15
+ const XML_PREFIX_CUSTOMER_ATTR = 'bronto_customer/attributes/';
16
+ const XML_PREFIX_ADDRESS_ATTR = 'bronto_customer/attributes/';
17
+
18
+ /**
19
+ * @return bool
20
+ */
21
+ public function isEnabled()
22
+ {
23
+ return (bool) Mage::getStoreConfig(self::XML_PATH_ENABLED);
24
+ }
25
+
26
+ /**
27
+ * @param string $attribute
28
+ * @param int|string $store
29
+ * @return mixed
30
+ */
31
+ public function getCustomerAttributeField($attribute, $store = null)
32
+ {
33
+ return Mage::getStoreConfig(self::XML_PREFIX_CUSTOMER_ATTR . $attribute, $store);
34
+ }
35
+
36
+ /**
37
+ * @param string $attribute
38
+ * @param int|string $store
39
+ * @return mixed
40
+ */
41
+ public function getAddressAttributeField($attribute, $store = null)
42
+ {
43
+ return Mage::getStoreConfig(self::XML_PREFIX_ADDRESS_ATTR . $attribute, $store);
44
+ }
45
+
46
+ /**
47
+ * @param string $path
48
+ * @return bool
49
+ */
50
+ public function disableModule($scope = 'default', $scopeId = 0)
51
+ {
52
+ return $this->_disableModule(self::XML_PATH_ENABLED, $scope, $scopeId);
53
+ }
54
+
55
+ /**
56
+ * Retrieve helper module name
57
+ * @return string
58
+ */
59
+ protected function _getModuleName()
60
+ {
61
+ return 'bronto_customer';
62
+ }
63
+ }
app/code/community/Bronto/Customer/Model/Customer/Observer.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.0.0
7
+ */
8
+ class Bronto_Customer_Model_Customer_Observer
9
+ {
10
+ /**
11
+ * @param Varien_Event_Observer $observer
12
+ */
13
+ public function markCustomerForReimport(Varien_Event_Observer $observer)
14
+ {
15
+ /* @var $customer Mage_Customer_Model_Customer */
16
+ $customer = $observer->getCustomer();
17
+ $customer->setBrontoImported(null);
18
+ }
19
+ }
app/code/community/Bronto/Customer/Model/Observer.php ADDED
@@ -0,0 +1,186 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.3.5
7
+ */
8
+ class Bronto_Customer_Model_Observer extends Mage_Core_Model_Abstract
9
+ {
10
+ /**
11
+ * @param mixed $storeId
12
+ * @return array
13
+ */
14
+ public function processCustomersForStore($storeId = null)
15
+ {
16
+ if (is_object($storeId)) {
17
+ $store = $storeId;
18
+ $storeId = $store->getId();
19
+ } else {
20
+ $store = Mage::app()->getStore($storeId);
21
+ $storeId = $store->getId();
22
+ }
23
+
24
+ $result = array('total' => 0, 'success' => 0, 'error' => 0);
25
+ Mage::helper('bronto_customer')->writeDebug("Starting Customer Import process for store: {$store->getName()} ({$storeId})");
26
+
27
+ if (!$store->getConfig(Bronto_Customer_Helper_Data::XML_PATH_ENABLED)) {
28
+ Mage::helper('bronto_customer')->writeDebug(' Module disabled for this store. Skipping...');
29
+ return false;
30
+ }
31
+
32
+ // Retrieve Store's configured API Token
33
+ $token = $store->getConfig(Bronto_Common_Helper_Data::XML_PATH_API_TOKEN);
34
+
35
+ /* @var $api Bronto_Common_Model_Api */
36
+ $api = Mage::helper('bronto_customer')->getApi($token);
37
+
38
+ /* @var $contactObject Bronto_Api_Contact */
39
+ $contactObject = $api->getContactObject();
40
+
41
+ $limit = $store->getConfig(Bronto_Customer_Helper_Data::XML_PATH_LIMIT);
42
+ if (!$limit) {
43
+ Mage::helper('bronto_customer')->writeDebug(' Limit empty. Skipping...');
44
+ return false;
45
+ }
46
+
47
+ $customerIds = Mage::getModel('bronto_customer/resource_customer_collection')
48
+ ->addStoreFilter($storeId)
49
+ ->addBrontoNotImportedFilter()
50
+ ->orderByUpdatedAt()
51
+ ->getAllIds($limit);
52
+
53
+ if (empty($customerIds)) {
54
+ Mage::helper('bronto_customer')->writeVerboseDebug(' No Customers to process. Skipping...');
55
+ return $result;
56
+ }
57
+
58
+ $customerAttributes = Mage::getModel('customer/entity_attribute_collection')->addVisibleFilter();
59
+ $addressAttributes = Mage::getModel('customer/entity_address_attribute_collection')->addVisibleFilter();
60
+ $customerCache = array();
61
+
62
+ // For each Customer...
63
+ foreach ($customerIds as $customerId) {
64
+ if ($customer = Mage::getModel('customer/customer')->load($customerId) /* @var $customer Mage_Customer_Model_Customer */) {
65
+ Mage::helper('bronto_customer')->writeDebug(" Processing Customer ID: {$customerId}");
66
+ $customerCache[] = $customerId;
67
+
68
+ /* @var $brontoContact Bronto_Api_Contact_Row */
69
+ $brontoContact = $contactObject->createRow();
70
+ $brontoContact->email = $customer->getEmail();
71
+
72
+ // For each Customer attribute
73
+ foreach ($customerAttributes as $attributeId => $attribute) {
74
+ $_attributeCode = $_attribute->getAttributeCode();
75
+ $_fieldName = Mage::helper('bronto_customer')->getCustomerAttributeField($_attributeCode, $store);
76
+ if (!empty($_fieldName)) {
77
+ $brontoContact->setField($_fieldName, $customer->getAttribute($_attributeCode));
78
+ }
79
+ }
80
+
81
+ // For each Customer Address attribute
82
+ $primaryAddress = $customer->getPrimaryShippingAddress();
83
+ if (!empty($primaryAddress)) {
84
+ foreach ($addressAttributes as $attributeId => $attribute) {
85
+ $_attributeCode = $_attribute->getAttributeCode();
86
+ $_fieldName = Mage::helper('bronto_customer')->getAddressAttributeField($_attributeCode, $store);
87
+ if (!empty($_fieldName)) {
88
+ $brontoContact->setField($_fieldName, $primaryAddress->getAttribute($_attributeCode));
89
+ }
90
+ }
91
+ }
92
+
93
+ $brontoContact->persist();
94
+
95
+ try {
96
+ // Mark Customer as imported
97
+ $customer->setBrontoImported(Mage::getSingleton('core/date')->gmtDate());
98
+ $customer->save();
99
+
100
+ // Flush every 10 Customers
101
+ if ($result['total'] % 100 === 0) {
102
+ $result = $this->flushCustomers($customerObject, $customerCache, $result);
103
+ $customerCache = array();
104
+ }
105
+ } catch (Exception $e) {
106
+ Mage::helper('bronto_customer')->writeError($e);
107
+
108
+ // Mark Customer as *not* imported
109
+ $customer->setBrontoImported(null);
110
+ $customer->save();
111
+
112
+ $result['error']++;
113
+ }
114
+
115
+ $result['total']++;
116
+ }
117
+ }
118
+
119
+ // Final flush (for any we miss)
120
+ $result = $this->flushCustomers($customerObject, $customerCache, $result);
121
+
122
+ Mage::helper('bronto_customer')->writeDebug(' Success: ' . $result['success']);
123
+ Mage::helper('bronto_customer')->writeDebug(' Error: ' . $result['error']);
124
+ Mage::helper('bronto_customer')->writeDebug(' Total: ' . $result['total']);
125
+
126
+ return $result;
127
+ }
128
+
129
+ /**
130
+ * @param Bronto_Api_Customer $customerObject
131
+ * @param array $customerCache
132
+ * @param array $result
133
+ * @return array
134
+ */
135
+ public function flushCustomers($customerObject, $customerCache, $result)
136
+ {
137
+ $flushResult = $customerObject->flush();
138
+
139
+ Mage::helper('bronto_customer')->writeVerboseDebug('===== FLUSH =====', 'bronto_customer_api.log');
140
+ Mage::helper('bronto_customer')->writeVerboseDebug(var_export($customerObject->getApi()->getLastRequest(), true), 'bronto_customer_api.log');
141
+ Mage::helper('bronto_customer')->writeVerboseDebug(var_export($customerObject->getApi()->getLastResponse(), true), 'bronto_customer_api.log');
142
+
143
+ foreach ($flushResult as $i => $flushResultRow) {
144
+ if ($flushResultRow->hasError()) {
145
+ $errorCode = $flushResultRow->getErrorCode();
146
+ $errorMessage = $flushResultRow->getErrorMessage();
147
+ if (isset($customerCache[$i])) {
148
+ // Reset Bronto Import status
149
+ $customer = Mage::getModel('sales/customer')->load($customerCache[$i]);
150
+ $customer->setBrontoImported(null);
151
+ $customer->save();
152
+ Mage::helper('bronto_customer')->writeError("[{$errorCode}] {$errorMessage} ({$customer->getIncrementId})");
153
+ } else {
154
+ Mage::helper('bronto_customer')->writeError("[{$errorCode}] {$errorMessage}");
155
+ }
156
+ $result['error']++;
157
+ } else {
158
+ $result['success']++;
159
+ }
160
+ }
161
+
162
+ return $result;
163
+ }
164
+
165
+ /**
166
+ * @return array
167
+ */
168
+ public function processCustomers()
169
+ {
170
+ $result = array(
171
+ 'total' => 0,
172
+ 'success' => 0,
173
+ 'error' => 0,
174
+ );
175
+
176
+ $stores = Mage::app()->getStores();
177
+ foreach ($stores as $_storeId => $_store) {
178
+ $storeResult = $this->processCustomersForStore($_store);
179
+ $result['total'] += $storeResult['total'];
180
+ $result['success'] += $storeResult['success'];
181
+ $result['error'] += $storeResult['error'];
182
+ }
183
+
184
+ return $result;
185
+ }
186
+ }
app/code/community/Bronto/Customer/Model/Resource/Customer/Collection.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Customer_Model_Resource_Customer_Collection extends Mage_Customer_Model_Entity_Customer_Collection
9
+ {
10
+ /**
11
+ * @return Bronto_Customer_Model_Resource_Customer_Collection
12
+ */
13
+ public function addBrontoImportedFilter()
14
+ {
15
+ $this->addAttributeToFilter('bronto_imported', array('notnull' => true));
16
+ return $this;
17
+ }
18
+
19
+ /**
20
+ * @return Bronto_Customer_Model_Resource_Customer_Collection
21
+ */
22
+ public function addBrontoNotImportedFilter()
23
+ {
24
+ $this->addAttributeToFilter('bronto_imported', array('null' => true));
25
+ return $this;
26
+ }
27
+
28
+ /**
29
+ * @param mixed $storeIds (null, int|string, array, array may contain null)
30
+ * @return Bronto_Customer_Model_Resource_Customer_Collection
31
+ */
32
+ public function addStoreFilter($storeIds)
33
+ {
34
+ $nullCheck = false;
35
+
36
+ if (!is_array($storeIds)) {
37
+ $storeIds = array($storeIds);
38
+ }
39
+
40
+ $storeIds = array_unique($storeIds);
41
+
42
+ if ($index = array_search(null, $storeIds)) {
43
+ unset($storeIds[$index]);
44
+ $nullCheck = true;
45
+ }
46
+
47
+ $storeIds[0] = ($storeIds[0] == '') ? 0 : $storeIds[0];
48
+
49
+ if ($nullCheck) {
50
+ $this->getSelect()->where('store_id IN(?) OR store_id IS NULL', $storeIds);
51
+ } else {
52
+ $this->getSelect()->where('store_id IN(?)', $storeIds);
53
+ }
54
+
55
+ return $this;
56
+ }
57
+
58
+ /**
59
+ * Sort order by order created_at date
60
+ *
61
+ * @param string $dir
62
+ * @return Bronto_Customer_Model_Resource_Customer_Collection
63
+ */
64
+ public function orderByCreatedAt($dir = self::SORT_ORDER_DESC)
65
+ {
66
+ $this->setOrder('created_at', $dir);
67
+ return $this;
68
+ }
69
+
70
+ /**
71
+ * Sort order by order updated_at date
72
+ *
73
+ * @param string $dir
74
+ * @return Bronto_Customer_Model_Resource_Customer_Collection
75
+ */
76
+ public function orderByUpdatedAt($dir = self::SORT_ORDER_DESC)
77
+ {
78
+ $this->setOrder('updated_at', $dir);
79
+ return $this;
80
+ }
81
+ }
app/code/community/Bronto/Customer/Model/Resource/Setup.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Customer_Model_Resource_Setup extends Mage_Customer_Model_Entity_Setup
9
+ {
10
+ protected function _getAttributeColumnDefinition($code, $data)
11
+ {
12
+ $definition = parent::_getAttributeColumnDefinition($code, $data);
13
+
14
+ if ($code === 'bronto_imported' && is_string($definition)) {
15
+ return 'datetime NULL DEFAULT NULL';
16
+ }
17
+
18
+ return $definition;
19
+ }
20
+ }
app/code/community/Bronto/Customer/Model/System/Config/Backend/Cron.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ */
7
+ class Bronto_Customer_Model_System_Config_Backend_Cron extends Bronto_Common_Model_System_Config_Backend_Cron
8
+ {
9
+ protected $_cron_string_path = 'crontab/jobs/bronto_customer_import/schedule/cron_expr';
10
+ protected $_cron_model_path = 'crontab/jobs/bronto_customer_import/run/model';
11
+ }
app/code/community/Bronto/Customer/Model/System/Config/Backend/Newfield.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Customer
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ */
7
+ class Bronto_Customer_Model_System_Config_Backend_Newfield extends Mage_Core_Model_Config_Data
8
+ {
9
+ /**
10
+ * Processing object before save data
11
+ *
12
+ * @return Mage_Core_Model_Abstract
13
+ */
14
+ protected function _beforeSave()
15
+ {
16
+ if ($this->isValueChanged()) {
17
+ /* @var $fieldObject Bronto_Api_Field */
18
+ $fieldObject = Mage::helper('bronto_common')->getApi()->getFieldObject();
19
+
20
+ $field = $fieldObject->createRow();
21
+ $field->name = $fieldObject->normalize($this->getValue());
22
+ $field->label = $this->getValue();
23
+ $field->type = Bronto_Api_Field::TYPE_TEXT;
24
+
25
+ try {
26
+ $field->save();
27
+ $fieldObject->addToCache($field->name, $field);
28
+
29
+ $this->_saveConfigData(str_replace('new_', '', $this->getPath()), $field->name);
30
+ $this->setValue(null);
31
+ } catch (Exception $e) {
32
+ Mage::throwException(Mage::helper('adminhtml')->__('Unable to save new field'));
33
+ }
34
+ }
35
+
36
+ return parent::_beforeSave();
37
+ }
38
+
39
+ /**
40
+ * @param type $path
41
+ * @param type $value
42
+ * @return Bronto_Customer_Model_System_Config_Backend_Newfield
43
+ */
44
+ protected function _saveConfigData($path, $value)
45
+ {
46
+ Mage::getModel('core/config_data')
47
+ ->load($path, 'path')
48
+ ->setValue($value)
49
+ ->setPath($path)
50
+ ->save();
51
+
52
+ return $this;
53
+ }
54
+ }
app/code/community/Bronto/Customer/Test/Config/Config.php ADDED
@@ -0,0 +1,148 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_Customer_Test_Config_Config
3
+ extends EcomDev_PHPUnit_Test_Case_Config
4
+ {
5
+ public function blocksProvider()
6
+ {
7
+ return array(
8
+ array('bronto_customer/adminhtml_system_config_about', 'Bronto_Customer_Block_Adminhtml_System_Config_About'),
9
+ array('bronto_customer/adminhtml_system_config_form_fieldset_attributes', 'Bronto_Customer_Block_Adminhtml_System_Config_Form_Fieldset_Attributes'),
10
+ array('bronto_customer/adminhtml_system_config_form_fieldset_attributes_address', 'Bronto_Customer_Block_Adminhtml_System_Config_Form_Fieldset_Attributes_Address'),
11
+ array('bronto_customer/adminhtml_system_config_form_fieldset_attributes_customer', 'Bronto_Customer_Block_Adminhtml_System_Config_Form_Fieldset_Attributes_Customer'),
12
+ );
13
+ }
14
+
15
+ public function modelsProvider()
16
+ {
17
+ return array();
18
+ }
19
+
20
+ public function resourceModelProvider()
21
+ {
22
+ return array();
23
+ }
24
+
25
+ public function observersProvider()
26
+ {
27
+ return array();
28
+ }
29
+
30
+ public function helpersProvider()
31
+ {
32
+ return array(
33
+ array('bronto_customer/data', 'Bronto_Customer_Helper_Data'),
34
+ );
35
+ }
36
+
37
+ public function dependsProvider()
38
+ {
39
+ return array(
40
+ array('Bronto_Common'),
41
+ );
42
+ }
43
+
44
+ /**
45
+ * @test
46
+ * @group amd
47
+ * @group config
48
+ */
49
+ public function assertCustomerModuleVersionGreaterThanOrEquals()
50
+ {
51
+ $this->assertModuleVersionGreaterThanOrEquals('1.0.0');
52
+ }
53
+
54
+
55
+ /**
56
+ * @test
57
+ * @group amd
58
+ * @group config
59
+ */
60
+ public function assertCustomerModuleInCommunityCodePool()
61
+ {
62
+ $this->assertModuleCodePool('community');
63
+ }
64
+
65
+ /**
66
+ * @test
67
+ * @group amd
68
+ * @group config
69
+ * @dataProvider dependsProvider
70
+ */
71
+ public function assertCustomerModuleDepends(
72
+ $requiredModuleName
73
+ ) {
74
+ $this->assertModuleDepends($requiredModuleName);
75
+ }
76
+
77
+ /**
78
+ * test
79
+ * @group amd
80
+ * @group config
81
+ * @dataProvider modelsProvider
82
+ */
83
+ public function assertCustomerModelAliases(
84
+ $classAlias,
85
+ $expectedClassName
86
+ ) {
87
+ $this->assertModelAlias($classAlias, $expectedClassName);
88
+ }
89
+
90
+ /**
91
+ * test
92
+ * @group amd
93
+ * @group config
94
+ * @dataProvider resourceModelProvider
95
+ */
96
+ public function assertCustomerResourceModelAliases(
97
+ $classAlias,
98
+ $expectedClassName
99
+ ) {
100
+ $this->assertResourceModelAlias($classAlias, $expectedClassName);
101
+ }
102
+
103
+ /**
104
+ * test
105
+ * @group config
106
+ * @group amd
107
+ * @dataProvider observersProvider
108
+ */
109
+ public function assertCustomerEventObserversDefined(
110
+ $area,
111
+ $eventName,
112
+ $observerClassAlias,
113
+ $observerMethod
114
+ ) {
115
+ $this->assertEventObserverDefined(
116
+ $area,
117
+ $eventName,
118
+ $observerClassAlias,
119
+ $observerMethod
120
+ );
121
+ }
122
+
123
+ /**
124
+ * @test
125
+ * @group amd
126
+ * @group config
127
+ * @dataProvider blocksProvider
128
+ */
129
+ public function assertCustomerBlockAliases(
130
+ $classAlias,
131
+ $expectedClassName
132
+ ) {
133
+ $this->assertBlockAlias($classAlias, $expectedClassName);
134
+ }
135
+
136
+ /**
137
+ * @test
138
+ * @group amd
139
+ * @group config
140
+ * @dataProvider helpersProvider
141
+ */
142
+ public function assertCustomerHelperAliases(
143
+ $classAlias,
144
+ $expectedClassName
145
+ ) {
146
+ $this->assertHelperAlias($classAlias, $expectedClassName);
147
+ }
148
+ }
app/code/community/Bronto/Customer/controllers/Adminhtml/CustomerController.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Bronto
5
+ * @package Bronto_Customer
6
+ */
7
+ class Bronto_Customer_Adminhtml_CustomerController extends Mage_Adminhtml_Controller_Action
8
+ {
9
+ /**
10
+ * Run immediately
11
+ */
12
+ public function runAction()
13
+ {
14
+ try {
15
+ $result = array('total' => 0, 'success' => 0, 'error' => 0);
16
+ $model = Mage::getModel('bronto_customer/observer');
17
+
18
+ if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
19
+ $store = Mage::app()->getStore($storeCode);
20
+ $storeIds[] = $store->getId();
21
+ } else if ($websiteCode = Mage::app()->getRequest()->getParam('website')){
22
+ $website = Mage::app()->getWebsite($websiteCode);
23
+ $storeIds = $website->getStoreIds();
24
+ } else if ($groupCode = Mage::app()->getRequest()->getParam('group')){
25
+ $website = Mage::app()->getGroup($groupCode)->getWebsite();
26
+ $storeIds = $website->getStoreIds();
27
+ } else {
28
+ $storeIds = false;
29
+ }
30
+
31
+ if ($storeIds) {
32
+ foreach ($storeIds as $storeId) {
33
+ $storeResult = $model->processCustomersForStore($storeId);
34
+ $result['total'] += $storeResult['total'];
35
+ $result['success'] += $storeResult['success'];
36
+ $result['error'] += $storeResult['error'];
37
+ }
38
+ } else {
39
+ $result = $model->processCustomers();
40
+ }
41
+
42
+ if (is_array($result)) {
43
+ $this->_getSession()->addSuccess(sprintf("Processed %d Customers (%d Error / %d Success)", $result['total'], $result['error'], $result['success']));
44
+ } else {
45
+ $this->_getSession()->addError('Scheduled Import failed: ' . $result);
46
+ }
47
+
48
+ } catch (Exception $e) {
49
+ $this->_getSession()->addError($e->getMessage());
50
+ Mage::helper('bronto_customer')->writeError($e);
51
+ }
52
+
53
+ $this->_redirect('*/system_config/edit', array('section' => 'bronto_customer'));
54
+ }
55
+
56
+ /**
57
+ * Reset all Customers
58
+ */
59
+ public function resetAction()
60
+ {
61
+ $storeIds = array();
62
+ $writeConnection = Mage::getSingleton('core/resource')->getConnection('core_write');
63
+ $tablePrefix = Mage::getConfig()->getTablePrefix();
64
+
65
+ if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
66
+ $store = Mage::app()->getStore($storeCode);
67
+ $storeIds[] = $store->getId();
68
+ } else if ($websiteCode = Mage::app()->getRequest()->getParam('website')){
69
+ $website = Mage::app()->getWebsite($websiteCode);
70
+ $storeIds = $website->getStoreIds();
71
+ } else if ($groupCode = Mage::app()->getRequest()->getParam('group')){
72
+ $website = Mage::app()->getGroup($groupCode)->getWebsite();
73
+ $storeIds = $website->getStoreIds();
74
+ } else {
75
+ $storeIds[] = null;
76
+ }
77
+
78
+ foreach ($storeIds as $storeId) {
79
+ //
80
+ }
81
+
82
+ $this->_redirect('*/system_config/edit', array('section' => 'bronto_customer'));
83
+ }
84
+
85
+ /**
86
+ * @return bool
87
+ */
88
+ protected function _isAllowed()
89
+ {
90
+ return $this->_isSectionAllowed('bronto_customer');
91
+ }
92
+
93
+ /**
94
+ * Check if specified section allowed in ACL
95
+ *
96
+ * Will forward to deniedAction(), if not allowed.
97
+ *
98
+ * @param string $section
99
+ * @return bool
100
+ */
101
+ protected function _isSectionAllowed($section)
102
+ {
103
+ try {
104
+ $session = Mage::getSingleton('admin/session');
105
+ $resourceLookup = "admin/system/config/{$section}";
106
+ if ($session->getData('acl') instanceof Mage_Admin_Model_Acl) {
107
+ $resourceId = $session->getData('acl')->get($resourceLookup)->getResourceId();
108
+ if (!$session->isAllowed($resourceId)) {
109
+ throw new Exception('');
110
+ }
111
+ return true;
112
+ }
113
+ } catch (Zend_Acl_Exception $e) {
114
+ $this->norouteAction();
115
+ $this->setFlag('', self::FLAG_NO_DISPATCH, true);
116
+ return false;
117
+ } catch (Exception $e) {
118
+ $this->deniedAction();
119
+ $this->setFlag('', self::FLAG_NO_DISPATCH, true);
120
+ return false;
121
+ }
122
+ }
123
+ }
app/code/community/Bronto/Customer/etc/adminhtml.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <admin>
6
+ <children>
7
+ <system>
8
+ <children>
9
+ <config>
10
+ <children>
11
+ <bronto_customer module="bronto_customer">
12
+ <title>Bronto Customer Import Section</title>
13
+ </bronto_customer>
14
+ </children>
15
+ </config>
16
+ </children>
17
+ </system>
18
+ </children>
19
+ </admin>
20
+ </resources>
21
+ </acl>
22
+ </config>
app/code/community/Bronto/Customer/etc/config.xml ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Bronto_Customer>
5
+ <version>1.0.0</version>
6
+ </Bronto_Customer>
7
+ </modules>
8
+ <global>
9
+ <blocks>
10
+ <bronto_customer>
11
+ <class>Bronto_Customer_Block</class>
12
+ </bronto_customer>
13
+ </blocks>
14
+ <helpers>
15
+ <bronto_customer>
16
+ <class>Bronto_Customer_Helper</class>
17
+ </bronto_customer>
18
+ </helpers>
19
+ <models>
20
+ <bronto_customer>
21
+ <class>Bronto_Customer_Model</class>
22
+ <resourceModel>bronto_customer_resource</resourceModel>
23
+ </bronto_customer>
24
+ <bronto_customer_resource>
25
+ <class>Bronto_Customer_Model_Resource</class>
26
+ </bronto_customer_resource>
27
+ </models>
28
+ <resources>
29
+ <bronto_customer_setup>
30
+ <setup>
31
+ <module>Bronto_Customer</module>
32
+ <class>Bronto_Customer_Model_Resource_Setup</class>
33
+ </setup>
34
+ <connection>
35
+ <use>core_setup</use>
36
+ </connection>
37
+ </bronto_customer_setup>
38
+ <bronto_customer_write>
39
+ <connection>
40
+ <use>core_write</use>
41
+ </connection>
42
+ </bronto_customer_write>
43
+ <bronto_customer_read>
44
+ <connection>
45
+ <use>core_read</use>
46
+ </connection>
47
+ </bronto_customer_read>
48
+ </resources>
49
+ <events>
50
+ <customer_save_before>
51
+ <observers>
52
+ <bronto_customer_sales_customer_save_before>
53
+ <type>singleton</type>
54
+ <class>bronto_customer/customer_observer</class>
55
+ <method>markCustomerForReimport</method>
56
+ </bronto_customer_sales_customer_save_before>
57
+ </observers>
58
+ </customer_save_before>
59
+ </events>
60
+ </global>
61
+ <adminhtml>
62
+ <acl>
63
+ <resources>
64
+ <admin>
65
+ <children>
66
+ <system>
67
+ <children>
68
+ <config>
69
+ <children>
70
+ <bronto>
71
+ <title>Bronto Customer Import Section</title>
72
+ </bronto>
73
+ </children>
74
+ </config>
75
+ </children>
76
+ </system>
77
+ </children>
78
+ </admin>
79
+ </resources>
80
+ </acl>
81
+ </adminhtml>
82
+ <admin>
83
+ <routers>
84
+ <adminhtml>
85
+ <args>
86
+ <modules>
87
+ <bronto_customer before="Mage_Adminhtml">Bronto_Customer_Adminhtml</bronto_customer>
88
+ </modules>
89
+ </args>
90
+ </adminhtml>
91
+ </routers>
92
+ </admin>
93
+ <default>
94
+ <bronto_customer>
95
+ <settings>
96
+ <enabled>0</enabled>
97
+ <frequency>D</frequency>
98
+ <interval>15</interval>
99
+ <minutes>0</minutes>
100
+ <limit>100</limit>
101
+ </settings>
102
+ <attributes>
103
+ <prefix>_none_</prefix>
104
+ <firstname>firstname</firstname>
105
+ <middlename>_none_</middlename>
106
+ <lastname>lastname</lastname>
107
+ <suffix>_none_</suffix>
108
+ <gender>gender</gender>
109
+ <dob>birthday</dob>
110
+ <taxvat>_none_</taxvat>
111
+ <website_id>_none_</website_id>
112
+ <group_id>_none_</group_id>
113
+ <created_at>_none_</created_at>
114
+ <created_in>_none_</created_in>
115
+ </attributes>
116
+ <address_attributes>
117
+ <street>address1</street>
118
+ <city>city</city>
119
+ <region>state</region>
120
+ <postcode>postal_code</postcode>
121
+ <country_id>country</country_id>
122
+ <company>_none_</company>
123
+ <telephone>phone_home</telephone>
124
+ <fax>_none_</fax>
125
+ </address_attributes>
126
+ </bronto_customer>
127
+ </default>
128
+ <crontab>
129
+ <jobs>
130
+ <bronto_customer_import>
131
+ <schedule><cron_expr>*/15 * * * *</cron_expr></schedule>
132
+ <run><model>bronto_customer/observer::processCustomers</model></run>
133
+ </bronto_customer_import>
134
+ </jobs>
135
+ </crontab>
136
+ <phpunit>
137
+ <suite>
138
+ <modules>
139
+ <Bronto_Customer />
140
+ </modules>
141
+ </suite>
142
+ </phpunit>
143
+ </config>
app/code/community/Bronto/Customer/etc/system.xml ADDED
@@ -0,0 +1,547 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <bronto_customer module="bronto_customer">
5
+ <label>Contact Import</label>
6
+ <tab>bronto</tab>
7
+ <frontend_type>text</frontend_type>
8
+ <sort_order>200</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
+ <about>
14
+ <frontend_type>text</frontend_type>
15
+ <frontend_model>bronto_customer/adminhtml_system_config_about</frontend_model>
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
+ </about>
21
+ <settings>
22
+ <label>Settings</label>
23
+ <frontend_type>text</frontend_type>
24
+ <sort_order>5</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ <expanded>1</expanded>
29
+ <fields>
30
+ <enabled>
31
+ <label>Enable Module</label>
32
+ <frontend_type>select</frontend_type>
33
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
34
+ <source_model>adminhtml/system_config_source_yesno</source_model>
35
+ <sort_order>0</sort_order>
36
+ <show_in_default>1</show_in_default>
37
+ <show_in_website>1</show_in_website>
38
+ <show_in_store>1</show_in_store>
39
+ </enabled>
40
+ <frequency>
41
+ <label>Frequency</label>
42
+ <depends><enabled>1</enabled></depends>
43
+ <frontend_type>select</frontend_type>
44
+ <source_model>bronto_common/system_config_source_cron_frequency</source_model>
45
+ <backend_model>bronto_customer/system_config_backend_cron</backend_model>
46
+ <sort_order>20</sort_order>
47
+ <show_in_default>1</show_in_default>
48
+ <show_in_website>1</show_in_website>
49
+ <show_in_store>0</show_in_store>
50
+ </frequency>
51
+ <interval>
52
+ <label>Interval</label>
53
+ <depends><frequency>I</frequency></depends>
54
+ <frontend_type>select</frontend_type>
55
+ <source_model>bronto_common/system_config_source_cron_minutes</source_model>
56
+ <sort_order>30</sort_order>
57
+ <show_in_default>1</show_in_default>
58
+ <show_in_website>1</show_in_website>
59
+ <show_in_store>0</show_in_store>
60
+ <comment>Set this value larger than your cron.php launch period.</comment>
61
+ </interval>
62
+ <minutes>
63
+ <label>Minute of the Hour</label>
64
+ <depends><frequency>H</frequency></depends>
65
+ <frontend_type>text</frontend_type>
66
+ <sort_order>40</sort_order>
67
+ <show_in_default>1</show_in_default>
68
+ <show_in_website>1</show_in_website>
69
+ <show_in_store>0</show_in_store>
70
+ <comment>Valid range: 0-59 (default 0).</comment>
71
+ </minutes>
72
+ <time>
73
+ <label>Start Time</label>
74
+ <depends><enabled>1</enabled></depends>
75
+ <frontend_type>time</frontend_type>
76
+ <sort_order>50</sort_order>
77
+ <show_in_default>1</show_in_default>
78
+ <show_in_website>1</show_in_website>
79
+ <show_in_store>0</show_in_store>
80
+ </time>
81
+ <limit>
82
+ <label>Limit</label>
83
+ <depends><enabled>1</enabled></depends>
84
+ <frontend_type>select</frontend_type>
85
+ <source_model>bronto_order/system_config_source_limit</source_model>
86
+ <sort_order>60</sort_order>
87
+ <show_in_default>1</show_in_default>
88
+ <show_in_website>1</show_in_website>
89
+ <show_in_store>0</show_in_store>
90
+ <comment>Total Customers to process every cron run.</comment>
91
+ </limit>
92
+ </fields>
93
+ </settings>
94
+ <cron_list>
95
+ <frontend_type>text</frontend_type>
96
+ <frontend_model>bronto_customer/adminhtml_system_config_cron</frontend_model>
97
+ <sort_order>6</sort_order>
98
+ <show_in_default>1</show_in_default>
99
+ <show_in_website>0</show_in_website>
100
+ <show_in_store>1</show_in_store>
101
+ </cron_list>
102
+ <attributes>
103
+ <label>Customer Attributes</label>
104
+ <frontend_type>text</frontend_type>
105
+ <frontend_model>bronto_customer/adminhtml_system_config_form_fieldset_attributes_customer</frontend_model>
106
+ <sort_order>10</sort_order>
107
+ <show_in_default>1</show_in_default>
108
+ <show_in_website>1</show_in_website>
109
+ <show_in_store>0</show_in_store>
110
+ <fields>
111
+ <!-- prefix -->
112
+ <prefix>
113
+ <sort_order>1</sort_order>
114
+ <label>Prefix</label>
115
+ <frontend_type>select</frontend_type>
116
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
117
+ <source_model>bronto_common/system_config_source_field</source_model>
118
+ <show_in_default>1</show_in_default>
119
+ <show_in_website>1</show_in_website>
120
+ <show_in_store>0</show_in_store>
121
+ </prefix>
122
+ <new_prefix>
123
+ <sort_order>2</sort_order>
124
+ <frontend_type>text</frontend_type>
125
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
126
+ <show_in_default>1</show_in_default>
127
+ <show_in_website>1</show_in_website>
128
+ <show_in_store>0</show_in_store>
129
+ <depends><prefix>_new_</prefix></depends>
130
+ <validate>validate-length minimum-length-5</validate>
131
+ </new_prefix>
132
+ <!-- firstname -->
133
+ <firstname>
134
+ <sort_order>5</sort_order>
135
+ <label>First Name</label>
136
+ <frontend_type>select</frontend_type>
137
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
138
+ <source_model>bronto_common/system_config_source_field</source_model>
139
+ <show_in_default>1</show_in_default>
140
+ <show_in_website>1</show_in_website>
141
+ <show_in_store>0</show_in_store>
142
+ </firstname>
143
+ <new_firstname>
144
+ <sort_order>6</sort_order>
145
+ <frontend_type>text</frontend_type>
146
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
147
+ <show_in_default>1</show_in_default>
148
+ <show_in_website>1</show_in_website>
149
+ <show_in_store>0</show_in_store>
150
+ <depends><firstname>_new_</firstname></depends>
151
+ <validate>validate-length minimum-length-5</validate>
152
+ </new_firstname>
153
+ <!-- middlename -->
154
+ <middlename>
155
+ <sort_order>10</sort_order>
156
+ <label>Middle Name/Initial</label>
157
+ <frontend_type>select</frontend_type>
158
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
159
+ <source_model>bronto_common/system_config_source_field</source_model>
160
+ <show_in_default>1</show_in_default>
161
+ <show_in_website>1</show_in_website>
162
+ <show_in_store>0</show_in_store>
163
+ </middlename>
164
+ <new_middlename>
165
+ <sort_order>11</sort_order>
166
+ <frontend_type>text</frontend_type>
167
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
168
+ <show_in_default>1</show_in_default>
169
+ <show_in_website>1</show_in_website>
170
+ <show_in_store>0</show_in_store>
171
+ <depends><middlename>_new_</middlename></depends>
172
+ <validate>validate-length minimum-length-5</validate>
173
+ </new_middlename>
174
+ <!-- lastname -->
175
+ <lastname>
176
+ <sort_order>15</sort_order>
177
+ <label>Last Name</label>
178
+ <frontend_type>select</frontend_type>
179
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
180
+ <source_model>bronto_common/system_config_source_field</source_model>
181
+ <show_in_default>1</show_in_default>
182
+ <show_in_website>1</show_in_website>
183
+ <show_in_store>0</show_in_store>
184
+ </lastname>
185
+ <new_lastname>
186
+ <sort_order>16</sort_order>
187
+ <frontend_type>text</frontend_type>
188
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
189
+ <show_in_default>1</show_in_default>
190
+ <show_in_website>1</show_in_website>
191
+ <show_in_store>0</show_in_store>
192
+ <depends><lastname>_new_</lastname></depends>
193
+ <validate>validate-length minimum-length-5</validate>
194
+ </new_lastname>
195
+ <!-- suffix -->
196
+ <suffix>
197
+ <sort_order>20</sort_order>
198
+ <label>Suffix</label>
199
+ <frontend_type>select</frontend_type>
200
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
201
+ <source_model>bronto_common/system_config_source_field</source_model>
202
+ <show_in_default>1</show_in_default>
203
+ <show_in_website>1</show_in_website>
204
+ <show_in_store>0</show_in_store>
205
+ </suffix>
206
+ <new_suffix>
207
+ <sort_order>21</sort_order>
208
+ <frontend_type>text</frontend_type>
209
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
210
+ <show_in_default>1</show_in_default>
211
+ <show_in_website>1</show_in_website>
212
+ <show_in_store>0</show_in_store>
213
+ <depends><suffix>_new_</suffix></depends>
214
+ <validate>validate-length minimum-length-5</validate>
215
+ </new_suffix>
216
+ <!-- gender -->
217
+ <gender>
218
+ <sort_order>25</sort_order>
219
+ <label>Gender</label>
220
+ <frontend_type>select</frontend_type>
221
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
222
+ <source_model>bronto_common/system_config_source_field</source_model>
223
+ <show_in_default>1</show_in_default>
224
+ <show_in_website>1</show_in_website>
225
+ <show_in_store>0</show_in_store>
226
+ </gender>
227
+ <new_gender>
228
+ <sort_order>26</sort_order>
229
+ <frontend_type>text</frontend_type>
230
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
231
+ <show_in_default>1</show_in_default>
232
+ <show_in_website>1</show_in_website>
233
+ <show_in_store>0</show_in_store>
234
+ <depends><gender>_new_</gender></depends>
235
+ <validate>validate-length minimum-length-5</validate>
236
+ </new_gender>
237
+ <!-- dob -->
238
+ <dob>
239
+ <sort_order>30</sort_order>
240
+ <label>Date of Birth</label>
241
+ <frontend_type>select</frontend_type>
242
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
243
+ <source_model>bronto_common/system_config_source_field</source_model>
244
+ <show_in_default>1</show_in_default>
245
+ <show_in_website>1</show_in_website>
246
+ <show_in_store>0</show_in_store>
247
+ </dob>
248
+ <new_dob>
249
+ <sort_order>31</sort_order>
250
+ <frontend_type>text</frontend_type>
251
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
252
+ <show_in_default>1</show_in_default>
253
+ <show_in_website>1</show_in_website>
254
+ <show_in_store>0</show_in_store>
255
+ <depends><dob>_new_</dob></depends>
256
+ <validate>validate-length minimum-length-5</validate>
257
+ </new_dob>
258
+ <!-- taxvat -->
259
+ <taxvat>
260
+ <sort_order>35</sort_order>
261
+ <label>Tax/VAT Number</label>
262
+ <frontend_type>select</frontend_type>
263
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
264
+ <source_model>bronto_common/system_config_source_field</source_model>
265
+ <show_in_default>1</show_in_default>
266
+ <show_in_website>1</show_in_website>
267
+ <show_in_store>0</show_in_store>
268
+ </taxvat>
269
+ <new_taxvat>
270
+ <sort_order>36</sort_order>
271
+ <frontend_type>text</frontend_type>
272
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
273
+ <show_in_default>1</show_in_default>
274
+ <show_in_website>1</show_in_website>
275
+ <show_in_store>0</show_in_store>
276
+ <depends><taxvat>_new_</taxvat></depends>
277
+ <validate>validate-length minimum-length-5</validate>
278
+ </new_taxvat>
279
+ <!-- website_id -->
280
+ <website_id>
281
+ <sort_order>40</sort_order>
282
+ <label>Website Association</label>
283
+ <frontend_type>select</frontend_type>
284
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
285
+ <source_model>bronto_common/system_config_source_field</source_model>
286
+ <show_in_default>1</show_in_default>
287
+ <show_in_website>1</show_in_website>
288
+ <show_in_store>0</show_in_store>
289
+ </website_id>
290
+ <new_website_id>
291
+ <sort_order>41</sort_order>
292
+ <frontend_type>text</frontend_type>
293
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
294
+ <show_in_default>1</show_in_default>
295
+ <show_in_website>1</show_in_website>
296
+ <show_in_store>0</show_in_store>
297
+ <depends><website_id>_new_</website_id></depends>
298
+ <validate>validate-length minimum-length-5</validate>
299
+ </new_website_id>
300
+ <!-- group_id -->
301
+ <group_id>
302
+ <sort_order>45</sort_order>
303
+ <label>Customer Group</label>
304
+ <frontend_type>select</frontend_type>
305
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
306
+ <source_model>bronto_common/system_config_source_field</source_model>
307
+ <show_in_default>1</show_in_default>
308
+ <show_in_website>1</show_in_website>
309
+ <show_in_store>0</show_in_store>
310
+ </group_id>
311
+ <new_group_id>
312
+ <sort_order>46</sort_order>
313
+ <frontend_type>text</frontend_type>
314
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
315
+ <show_in_default>1</show_in_default>
316
+ <show_in_website>1</show_in_website>
317
+ <show_in_store>0</show_in_store>
318
+ <depends><group_id>_new_</group_id></depends>
319
+ <validate>validate-length minimum-length-5</validate>
320
+ </new_group_id>
321
+ <!-- created_at -->
322
+ <created_at>
323
+ <sort_order>50</sort_order>
324
+ <label>Created At</label>
325
+ <frontend_type>select</frontend_type>
326
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
327
+ <source_model>bronto_common/system_config_source_field</source_model>
328
+ <show_in_default>1</show_in_default>
329
+ <show_in_website>1</show_in_website>
330
+ <show_in_store>0</show_in_store>
331
+ </created_at>
332
+ <new_created_at>
333
+ <sort_order>51</sort_order>
334
+ <frontend_type>text</frontend_type>
335
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
336
+ <show_in_default>1</show_in_default>
337
+ <show_in_website>1</show_in_website>
338
+ <show_in_store>0</show_in_store>
339
+ <depends><created_at>_new_</created_at></depends>
340
+ <validate>validate-length minimum-length-5</validate>
341
+ </new_created_at>
342
+ <!-- created_in -->
343
+ <created_in>
344
+ <sort_order>55</sort_order>
345
+ <label>Created From</label>
346
+ <frontend_type>select</frontend_type>
347
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
348
+ <source_model>bronto_common/system_config_source_field</source_model>
349
+ <show_in_default>1</show_in_default>
350
+ <show_in_website>1</show_in_website>
351
+ <show_in_store>0</show_in_store>
352
+ </created_in>
353
+ <new_created_in>
354
+ <sort_order>56</sort_order>
355
+ <frontend_type>text</frontend_type>
356
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
357
+ <show_in_default>1</show_in_default>
358
+ <show_in_website>1</show_in_website>
359
+ <show_in_store>0</show_in_store>
360
+ <depends><created_in>_new_</created_in></depends>
361
+ <validate>validate-length minimum-length-5</validate>
362
+ </new_created_in>
363
+ </fields>
364
+ </attributes>
365
+ <address_attributes>
366
+ <label>Address Attributes</label>
367
+ <frontend_type>text</frontend_type>
368
+ <frontend_model>bronto_customer/adminhtml_system_config_form_fieldset_attributes_address</frontend_model>
369
+ <sort_order>15</sort_order>
370
+ <show_in_default>1</show_in_default>
371
+ <show_in_website>1</show_in_website>
372
+ <show_in_store>0</show_in_store>
373
+ <fields>
374
+ <!-- street -->
375
+ <street>
376
+ <sort_order>1</sort_order>
377
+ <label>Street Address</label>
378
+ <frontend_type>select</frontend_type>
379
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
380
+ <source_model>bronto_common/system_config_source_field</source_model>
381
+ <show_in_default>1</show_in_default>
382
+ <show_in_website>1</show_in_website>
383
+ <show_in_store>0</show_in_store>
384
+ </street>
385
+ <new_street>
386
+ <sort_order>2</sort_order>
387
+ <frontend_type>text</frontend_type>
388
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
389
+ <show_in_default>1</show_in_default>
390
+ <show_in_website>1</show_in_website>
391
+ <show_in_store>0</show_in_store>
392
+ <depends><street>_new_</street></depends>
393
+ <validate>validate-length minimum-length-5</validate>
394
+ </new_street>
395
+ <!-- city -->
396
+ <city>
397
+ <sort_order>5</sort_order>
398
+ <label>City</label>
399
+ <frontend_type>select</frontend_type>
400
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
401
+ <source_model>bronto_common/system_config_source_field</source_model>
402
+ <show_in_default>1</show_in_default>
403
+ <show_in_website>1</show_in_website>
404
+ <show_in_store>0</show_in_store>
405
+ </city>
406
+ <new_city>
407
+ <sort_order>6</sort_order>
408
+ <frontend_type>text</frontend_type>
409
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
410
+ <show_in_default>1</show_in_default>
411
+ <show_in_website>1</show_in_website>
412
+ <show_in_store>0</show_in_store>
413
+ <depends><city>_new_</city></depends>
414
+ <validate>validate-length minimum-length-5</validate>
415
+ </new_city>
416
+ <!-- region -->
417
+ <region>
418
+ <sort_order>10</sort_order>
419
+ <label>State/Province</label>
420
+ <frontend_type>select</frontend_type>
421
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
422
+ <source_model>bronto_common/system_config_source_field</source_model>
423
+ <show_in_default>1</show_in_default>
424
+ <show_in_website>1</show_in_website>
425
+ <show_in_store>0</show_in_store>
426
+ </region>
427
+ <new_region>
428
+ <sort_order>11</sort_order>
429
+ <frontend_type>text</frontend_type>
430
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
431
+ <show_in_default>1</show_in_default>
432
+ <show_in_website>1</show_in_website>
433
+ <show_in_store>0</show_in_store>
434
+ <depends><region>_new_</region></depends>
435
+ <validate>validate-length minimum-length-5</validate>
436
+ </new_region>
437
+ <!-- postcode -->
438
+ <postcode>
439
+ <sort_order>15</sort_order>
440
+ <label>Zip/Postal Code</label>
441
+ <frontend_type>select</frontend_type>
442
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
443
+ <source_model>bronto_common/system_config_source_field</source_model>
444
+ <show_in_default>1</show_in_default>
445
+ <show_in_website>1</show_in_website>
446
+ <show_in_store>0</show_in_store>
447
+ </postcode>
448
+ <new_postcode>
449
+ <sort_order>16</sort_order>
450
+ <frontend_type>text</frontend_type>
451
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
452
+ <show_in_default>1</show_in_default>
453
+ <show_in_website>1</show_in_website>
454
+ <show_in_store>0</show_in_store>
455
+ <depends><postcode>_new_</postcode></depends>
456
+ <validate>validate-length minimum-length-5</validate>
457
+ </new_postcode>
458
+ <!-- country_id -->
459
+ <country_id>
460
+ <sort_order>20</sort_order>
461
+ <label>Country</label>
462
+ <frontend_type>select</frontend_type>
463
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
464
+ <source_model>bronto_common/system_config_source_field</source_model>
465
+ <show_in_default>1</show_in_default>
466
+ <show_in_website>1</show_in_website>
467
+ <show_in_store>0</show_in_store>
468
+ </country_id>
469
+ <new_country_id>
470
+ <sort_order>21</sort_order>
471
+ <frontend_type>text</frontend_type>
472
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
473
+ <show_in_default>1</show_in_default>
474
+ <show_in_website>1</show_in_website>
475
+ <show_in_store>0</show_in_store>
476
+ <depends><country_id>_new_</country_id></depends>
477
+ <validate>validate-length minimum-length-5</validate>
478
+ </new_country_id>
479
+ <!-- company -->
480
+ <company>
481
+ <sort_order>25</sort_order>
482
+ <label>Company</label>
483
+ <frontend_type>select</frontend_type>
484
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
485
+ <source_model>bronto_common/system_config_source_field</source_model>
486
+ <show_in_default>1</show_in_default>
487
+ <show_in_website>1</show_in_website>
488
+ <show_in_store>0</show_in_store>
489
+ </company>
490
+ <new_company>
491
+ <sort_order>26</sort_order>
492
+ <frontend_type>text</frontend_type>
493
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
494
+ <show_in_default>1</show_in_default>
495
+ <show_in_website>1</show_in_website>
496
+ <show_in_store>0</show_in_store>
497
+ <depends><company>_new_</company></depends>
498
+ <validate>validate-length minimum-length-5</validate>
499
+ </new_company>
500
+ <!-- telephone -->
501
+ <telephone>
502
+ <sort_order>30</sort_order>
503
+ <label>Telephone</label>
504
+ <frontend_type>select</frontend_type>
505
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
506
+ <source_model>bronto_common/system_config_source_field</source_model>
507
+ <show_in_default>1</show_in_default>
508
+ <show_in_website>1</show_in_website>
509
+ <show_in_store>0</show_in_store>
510
+ </telephone>
511
+ <new_telephone>
512
+ <sort_order>31</sort_order>
513
+ <frontend_type>text</frontend_type>
514
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
515
+ <show_in_default>1</show_in_default>
516
+ <show_in_website>1</show_in_website>
517
+ <show_in_store>0</show_in_store>
518
+ <depends><telephone>_new_</telephone></depends>
519
+ <validate>validate-length minimum-length-5</validate>
520
+ </new_telephone>
521
+ <!-- fax -->
522
+ <fax>
523
+ <sort_order>35</sort_order>
524
+ <label>Fax</label>
525
+ <frontend_type>select</frontend_type>
526
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
527
+ <source_model>bronto_common/system_config_source_field</source_model>
528
+ <show_in_default>1</show_in_default>
529
+ <show_in_website>1</show_in_website>
530
+ <show_in_store>0</show_in_store>
531
+ </fax>
532
+ <new_fax>
533
+ <sort_order>36</sort_order>
534
+ <frontend_type>text</frontend_type>
535
+ <backend_model>bronto_customer/system_config_backend_newfield</backend_model>
536
+ <show_in_default>1</show_in_default>
537
+ <show_in_website>1</show_in_website>
538
+ <show_in_store>0</show_in_store>
539
+ <depends><fax>_new_</fax></depends>
540
+ <validate>validate-length minimum-length-5</validate>
541
+ </new_fax>
542
+ </fields>
543
+ </address_attributes>
544
+ </groups>
545
+ </bronto_customer>
546
+ </sections>
547
+ </config>
app/code/community/Bronto/Customer/sql/bronto_customer_setup/mysql4-install-1.0.0.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Sales_Model_Mysql4_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ //
9
+ // Customer Attributes
10
+ $installer->addAttribute('customer', 'bronto_imported', array(
11
+ 'type' => 'datetime',
12
+ 'required' => false,
13
+ ));
14
+
15
+ // try {
16
+ // $installer->getConnection()->addKey(
17
+ // $installer->getTable('sales/order'), 'IDX_BRONTO_IMPORTED', 'bronto_imported'
18
+ // );
19
+ // } catch (Exception $e) {
20
+ // // Already exists...
21
+ // }
22
+
23
+ $installer->endSetup();
24
+
25
+ // Mark installation date
26
+ $config = Mage::getConfig();
27
+ $config->saveConfig(Bronto_Customer_Helper_Data::XML_PATH_INSTALL_DATE, time());
app/code/community/Bronto/Email/Block/Adminhtml/System/Config/About.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Block_Adminhtml_System_Config_About extends Bronto_Common_Block_Adminhtml_System_Config_About
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_module = 'bronto_email';
14
+
15
+ /**
16
+ * @var string
17
+ */
18
+ protected $_name = 'Bronto Transactional Email Module';
19
+ }
app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Log.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Block_Adminhtml_System_Email_Log extends Mage_Adminhtml_Block_Widget_Grid_Container
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_controller = 'adminhtml_system_email_log';
14
+
15
+ /**
16
+ * @var string
17
+ */
18
+ protected $_clearButtonLabel = 'Clear Log History';
19
+
20
+ /**
21
+ * @var string
22
+ */
23
+ protected $_blockGroup = 'bronto_email';
24
+
25
+ public function __construct()
26
+ {
27
+ $this->_headerText = Mage::helper('bronto_email')->__('Bronto Delivery Log');
28
+
29
+ parent::__construct();
30
+
31
+ $this->_addBackButton();
32
+ $this->_addButton('clear', array(
33
+ 'label' => $this->getClearButtonLabel(),
34
+ 'onclick' => 'setLocation(\'' . $this->getClearUrl() .'\')',
35
+ 'class' => 'delete'
36
+ ));
37
+
38
+ $this->_removeButton('add');
39
+ }
40
+
41
+ /**
42
+ * @return string
43
+ */
44
+ public function getClearUrl()
45
+ {
46
+ return $this->getUrl('*/*/clear');
47
+ }
48
+
49
+ /**
50
+ * @return string
51
+ */
52
+ protected function getClearButtonLabel()
53
+ {
54
+ return $this->_clearButtonLabel;
55
+ }
56
+ }
app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Log/Grid.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Block_Adminhtml_System_Email_Log_Grid extends Mage_Adminhtml_Block_Widget_Grid
9
+ {
10
+ /**
11
+ * @param array $attributes
12
+ * @return void
13
+ */
14
+ public function __construct($attributes = array())
15
+ {
16
+ parent::__construct($attributes);
17
+ $this->setId('logGrid');
18
+ $this->setIdFieldName('log_id');
19
+ $this->setDefaultSort('sent_at', 'desc');
20
+ $this->setSaveParametersInSession(true);
21
+ }
22
+
23
+ protected function _prepareCollection()
24
+ {
25
+ $collection = Mage::getModel('bronto_email/log')->getCollection();
26
+ $this->setCollection($collection);
27
+ return parent::_prepareCollection();
28
+ }
29
+
30
+ protected function _prepareColumns()
31
+ {
32
+ $this->addColumn('log_id', array(
33
+ 'header' => Mage::helper('bronto_email')->__('ID'),
34
+ 'align' => 'left',
35
+ 'index' => 'log_id',
36
+ 'type' => 'number',
37
+ 'filter' => false,
38
+ ));
39
+
40
+ $this->addColumn('message_name', array(
41
+ 'header' => Mage::helper('bronto_email')->__('Message Name'),
42
+ 'align' => 'left',
43
+ 'index' => 'message_name',
44
+ 'filter' => false,
45
+ ));
46
+
47
+ $this->addColumn('sent_at', array(
48
+ 'header' => Mage::helper('bronto_email')->__('Sent At'),
49
+ 'align' => 'left',
50
+ 'index' => 'sent_at',
51
+ 'type' => 'datetime'
52
+ ));
53
+
54
+ $this->addColumn('customer_email', array(
55
+ 'header' => Mage::helper('customer')->__('Email'),
56
+ 'index' => 'customer_email',
57
+ 'renderer' => 'bronto_email/adminhtml_system_email_log_grid_renderer_customer',
58
+ ));
59
+
60
+ $this->addColumn('success', array(
61
+ 'header' => Mage::helper('bronto_email')->__('Success'),
62
+ 'align' => 'left',
63
+ 'index' => 'success',
64
+ 'sortable' => false,
65
+ 'type' => 'options',
66
+ 'options' => array(
67
+ 0 => 'No',
68
+ 1 => 'Yes',
69
+ ),
70
+ ));
71
+
72
+ $this->addColumn('error', array(
73
+ 'header' => Mage::helper('bronto_email')->__('Error'),
74
+ 'align' => 'left',
75
+ 'index' => 'error',
76
+ 'sortable' => false,
77
+ 'filter' => false,
78
+ ));
79
+
80
+ $this->addColumn('data', array(
81
+ 'header' => Mage::helper('bronto_email')->__('Fields'),
82
+ 'align' => 'left',
83
+ 'index' => 'data',
84
+ 'renderer' => 'bronto_email/adminhtml_system_email_log_grid_renderer_fields',
85
+ 'sortable' => false,
86
+ 'filter' => false,
87
+ ));
88
+
89
+ return parent::_prepareColumns();
90
+ }
91
+
92
+ /**
93
+ * Return row url for js event handlers
94
+ *
95
+ * @param Bronto_Email_Model_Log|Varien_Object
96
+ * @return string
97
+ */
98
+ public function getRowUrl($log)
99
+ {
100
+ return null;
101
+ }
102
+ }
app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Log/Grid/Renderer/Customer.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Block_Adminhtml_System_Email_Log_Grid_Renderer_Customer extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
9
+ {
10
+ /**
11
+ * @param Varien_Object $row
12
+ * @return mixed
13
+ */
14
+ public function render(Varien_Object $row)
15
+ {
16
+ if ($row->getCustomerId() && Mage::getSingleton('admin/session')->isAllowed('customer/manage')) {
17
+ $customerEditUrl = $this->getUrl('*/customer/edit', array('id' => $row->getCustomerId()));
18
+ return sprintf(
19
+ '<a href="%s">%s</a>',
20
+ $customerEditUrl,
21
+ parent::render($row)
22
+ );
23
+ }
24
+
25
+ return parent::render($row);
26
+ }
27
+ }
app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Log/Grid/Renderer/Fields.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Block_Adminhtml_System_Email_Log_Grid_Renderer_Fields extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
9
+ {
10
+ public function render(Varien_Object $row)
11
+ {
12
+ $fields = array();
13
+ try {
14
+ $fields = unserialize($row->getFields());
15
+ } catch (Exception $e) {
16
+ //
17
+ }
18
+
19
+ if (empty($fields)) {
20
+ return '';
21
+ }
22
+
23
+ $fieldsHtml = '<dl style="margin-top: 10px">';
24
+ foreach ($fields as $field) {
25
+ $fieldsHtml .= '<dt><strong>' . $field['name'] . '</strong></dt>';
26
+ $fieldsHtml .= '
27
+ <dd style="padding-left: 15px; padding-bottom: 10px">
28
+ <pre>' . htmlspecialchars($field['content']) . '</pre>
29
+ </dd>
30
+ ';
31
+ }
32
+ $fieldsHtml .= '</dl>';
33
+
34
+ return '
35
+ <a href="#" onclick="javascript:document.getElementById(\'fields-' . $row->getId() . '\').style.display = \'block\';">Show</a>
36
+ <span style="color:#666">|</span>
37
+ <a href="#" onclick="javascript:document.getElementById(\'fields-' . $row->getId() . '\').style.display = \'none\';">Hide</a>
38
+ <div id="fields-' . $row->getId() . '" style="display: none">' . $fieldsHtml . '</div>
39
+ ';
40
+ }
41
+ }
app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Template.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Block_Adminhtml_System_Email_Template extends Mage_Adminhtml_Block_System_Email_Template
9
+ {
10
+ /**
11
+ * Set transactional emails grid template
12
+ */
13
+ protected function _construct()
14
+ {
15
+ Mage_Adminhtml_Block_Template::_construct();
16
+ $this->setTemplate('bronto/email/template/list.phtml');
17
+ }
18
+
19
+ /**
20
+ * @return Mage_Core_Block_Abstract
21
+ */
22
+ protected function _prepareLayout()
23
+ {
24
+ if (!Mage::helper('bronto_email')->isEnabled()) {
25
+ return parent::_prepareLayout();
26
+ }
27
+
28
+ $this->setChild('add_button',
29
+ $this->getLayout()->createBlock('adminhtml/widget_button')
30
+ ->setData(array(
31
+ 'label' => Mage::helper('adminhtml')->__('Add Bronto Message'),
32
+ 'onclick' => "window.location='" . $this->getCreateUrl() . "'",
33
+ 'class' => 'add'
34
+ ))
35
+ );
36
+
37
+ $this->setChild('import_button',
38
+ $this->getLayout()->createBlock('adminhtml/widget_button')
39
+ ->setData(array(
40
+ 'label' => Mage::helper('adminhtml')->__('Import Existing Templates'),
41
+ 'onclick' => "window.location='" . $this->getImportUrl() . "'",
42
+ 'class' => 'go'
43
+ ))
44
+ );
45
+
46
+ if (Mage::helper('bronto_email')->isLogEnabled()) {
47
+ $this->setChild('log_button',
48
+ $this->getLayout()->createBlock('adminhtml/widget_button')
49
+ ->setData(array(
50
+ 'label' => Mage::helper('adminhtml')->__('Delivery Log'),
51
+ 'onclick' => "window.location='" . $this->getLogUrl() . "'",
52
+ 'class' => 'go'
53
+ ))
54
+ );
55
+ }
56
+
57
+ $this->setChild('grid', $this->getLayout()->createBlock('adminhtml/system_email_template_grid', 'email.template.grid'));
58
+
59
+ return Mage_Adminhtml_Block_Template::_prepareLayout();
60
+ }
61
+
62
+ /**
63
+ * Get transactional emails page header text
64
+ *
65
+ * @return string
66
+ */
67
+ public function getHeaderText()
68
+ {
69
+ if (!Mage::helper('bronto_email')->isEnabled()) {
70
+ return parent::getHeaderText();
71
+ }
72
+
73
+ return Mage::helper('bronto_email')->__('Bronto Transactional Emails');
74
+ }
75
+
76
+ /**
77
+ * Get URL for create new email template
78
+ *
79
+ * @return string
80
+ */
81
+ public function getLogUrl()
82
+ {
83
+ return $this->getUrl('*/system_email_log/index');
84
+ }
85
+
86
+ /**
87
+ * Get URL to import existing email templates
88
+ *
89
+ * @return string
90
+ */
91
+ public function getImportUrl()
92
+ {
93
+ return $this->getUrl('*/system_email_template/import');
94
+ }
95
+ }
app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Template/Edit.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Block_Adminhtml_System_Email_Template_Edit extends Mage_Adminhtml_Block_System_Email_Template_Edit
9
+ {
10
+ public function __construct()
11
+ {
12
+ if (!Mage::helper('bronto_email')->isEnabled()) {
13
+ return parent::__construct();
14
+ }
15
+
16
+ Mage_Adminhtml_Block_Widget::__construct();
17
+ $this->setTemplate('bronto/email/template/edit.phtml');
18
+ }
19
+
20
+ protected function _prepareLayout()
21
+ {
22
+ if (!Mage::helper('bronto_email')->isEnabled()) {
23
+ return parent::_prepareLayout();
24
+ }
25
+
26
+ parent::_prepareLayout();
27
+
28
+ $this->unsetChild('to_plain_button');
29
+ $this->unsetChild('to_html_button');
30
+ $this->unsetChild('preview_button');
31
+
32
+ $this->setChild('save_button', $this->getLayout()->createBlock('adminhtml/widget_button')->setData(array(
33
+ 'label' => Mage::helper('adminhtml')->__('Save Message'),
34
+ 'onclick' => 'templateControl.save();',
35
+ 'class' => 'save'
36
+ )));
37
+ }
38
+
39
+ /**
40
+ * Return header text for form
41
+ *
42
+ * @return string
43
+ */
44
+ public function getHeaderText()
45
+ {
46
+ if (!Mage::helper('bronto_email')->isEnabled()) {
47
+ return parent::getHeaderText();
48
+ }
49
+
50
+ if ($this->getEditMode()) {
51
+ return Mage::helper('adminhtml')->__('Edit Bronto Email Message');
52
+ }
53
+
54
+ return Mage::helper('adminhtml')->__('New Bronto Email Message');
55
+ }
56
+
57
+ public function getUsedDefaultForPaths($asJSON = true)
58
+ {
59
+ $paths = $this->getEmailTemplate()->getSystemConfigPathsWhereUsedAsDefault();
60
+ if (Mage::helper('bronto_email')->isEnabled()) {
61
+ if ($this->getEmailTemplate()->hasData('store_id')) {
62
+ $paths[0]['scope_id'] = $this->getEmailTemplate()->getData('store_id');
63
+ $paths[0]['scope'] = 'stores';
64
+ }
65
+ }
66
+
67
+ $pathsParts = $this->_getSystemConfigPathsParts($paths);
68
+
69
+ if($asJSON){
70
+ return Mage::helper('core')->jsonEncode($pathsParts);
71
+ }
72
+
73
+ return $pathsParts;
74
+ }
75
+ }
app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Template/Edit/Form.php ADDED
@@ -0,0 +1,119 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Block_Adminhtml_System_Email_Template_Edit_Form extends Mage_Adminhtml_Block_System_Email_Template_Edit_Form
9
+ {
10
+ /**
11
+ * @return Mage_Adminhtml_Block_Widget_Form
12
+ */
13
+ protected function _prepareForm()
14
+ {
15
+ if (!Mage::helper('bronto_email')->isEnabled()) {
16
+ return parent::_prepareForm();
17
+ }
18
+
19
+ parent::_prepareForm();
20
+
21
+ /* @var $form Varien_Data_Form */
22
+ $form = $this->getForm();
23
+
24
+ /* @var $fieldset Varien_Data_Form_Element_Fieldset */
25
+ $fieldset = $form->getElement('base_fieldset');
26
+
27
+ $templateId = $this->getEmailTemplate()->getId();
28
+
29
+ if ($templateId) {
30
+ if (!$this->getEmailTemplate()->getSystemConfigPathsWhereUsedCurrently()) {
31
+ $fieldset->addField('used_default_for', 'label', array(
32
+ 'label' => Mage::helper('adminhtml')->__('Used as Default For'),
33
+ 'container_id' => 'used_default_for',
34
+ 'after_element_html' =>
35
+ '<script type="text/javascript">' .
36
+ (!(bool)$this->getEmailTemplate()->getOrigTemplateCode() ? '$(\'' . 'used_default_for' . '\').hide(); ' : '') .
37
+ '</script>',
38
+ ));
39
+
40
+ $fieldset->addField('note_used_currently', 'label', array(
41
+ 'label' => '',
42
+ 'container_id' => 'note_used_currently',
43
+ 'after_element_html' => '<div style="color:red;"><strong>Note:</strong> This Email Message is currently not used.</div>',
44
+ ));
45
+ }
46
+ }
47
+
48
+ $fieldset->removeField('template_text');
49
+ $fieldset->removeField('template_styles');
50
+ $fieldset->removeField('insert_variable');
51
+ $fieldset->removeField('template_subject');
52
+
53
+ $fieldset->removeField('template_code');
54
+ $fieldset->addField('template_code', 'text', array(
55
+ 'name' =>'template_code',
56
+ 'label' => Mage::helper('adminhtml')->__('Name'),
57
+ 'required' => true
58
+ ));
59
+
60
+ if (!Mage::app()->isSingleStoreMode()) {
61
+ $event = $fieldset->addField('store_id', 'select', array(
62
+ 'name' => 'store_id',
63
+ 'label' => Mage::helper('adminhtml')->__('Store View'),
64
+ 'title' => Mage::helper('adminhtml')->__('Store View'),
65
+ 'onchange' => "updateMessages(this);",
66
+ 'required' => true,
67
+ 'values' => Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm(false, false),
68
+ ));
69
+ $event->setAfterElementHtml("
70
+ <script type=\"text/javascript\">
71
+ function updateMessages(store){
72
+ var reloadurl = '". $this->getUrl('adminhtml/system_email_template/ajaxlist')."id/'+store.value;
73
+ new Ajax.Request(reloadurl, {
74
+ method: 'get',
75
+ onLoading: function (transport) {
76
+ $('bronto_message_id').update('Searching...');
77
+ },
78
+ onComplete: function(transport) {
79
+ $('bronto_message_id').update(transport.responseText);
80
+ }
81
+ });
82
+ }
83
+ </script>");
84
+ } else {
85
+ $fieldset->addField('store_id', 'hidden', array(
86
+ 'name' => 'store_id',
87
+ 'value' => Mage::app()->getStore(true)->getId()
88
+ ));
89
+ }
90
+
91
+
92
+ $fieldset->addField('bronto_message_id', 'select', array(
93
+ 'name' => 'bronto_message_id',
94
+ 'label' => Mage::helper('adminhtml')->__('Bronto Message'),
95
+ 'values' => Mage::helper('bronto_reminder/message')->getAllMessageOptions(),
96
+ 'required' => true,
97
+ ));
98
+
99
+ $fieldset->addField('template_variables_key', 'label', array(
100
+ 'container_id' => 'template_variables_key_row',
101
+ 'label' => Mage::helper('adminhtml')->__('Variables'),
102
+ 'after_element_html' => '<div id="template_variables_key_list"></div>' .
103
+ ($templateId ? '' : '<script>$("template_variables_key_row").hide();</script>')
104
+ ));
105
+
106
+ if ($templateId) {
107
+ $form->addValues($this->getEmailTemplate()->getData());
108
+ $form->addValues(array(
109
+ 'template_variables' => Zend_Json::encode($this->getEmailTemplate()->getVariablesOptionArray(true)),
110
+ ));
111
+ }
112
+
113
+ if ($values = Mage::getSingleton('adminhtml/session')->getData('email_template_form_data', true)) {
114
+ $form->setValues($values);
115
+ }
116
+
117
+ return $this;
118
+ }
119
+ }
app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Template/Grid.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Block_Adminhtml_System_Email_Template_Grid extends Mage_Adminhtml_Block_System_Email_Template_Grid
9
+ {
10
+ protected function _prepareCollection()
11
+ {
12
+ /* @var $collection Mage_Core_Model_Resource_Email_Template_Collection */
13
+ $collection = Mage::getResourceSingleton('core/email_template_collection');
14
+
15
+ if (!Mage::helper('bronto_email')->isEnabled()) {
16
+ $collection->addFieldToFilter('bronto_message_id', array('null' => true));
17
+ } else {
18
+ $collection->addFieldToFilter('bronto_message_id', array('notnull' => true));
19
+ }
20
+
21
+ // Change how table names and SQL aliases are mapped resource
22
+ // to account for version 1.9 differences
23
+ $resource = Mage::getSingleton('core/resource');
24
+ $tableName = $resource->getTableName('core/store');
25
+ $mainTable = $resource->getTableName('core/email_template');
26
+ $version = Mage::getVersionInfo();
27
+ if (1 == $version['major'] && 9 != $version['minor']) {
28
+ $mainTable = 'main_table';
29
+ }
30
+ $collection->getSelect()
31
+ ->join(
32
+ array('core_store' => $tableName),
33
+ "`$mainTable`.store_id=`core_store`.store_id",
34
+ array('storename' => 'core_store.name')
35
+ );
36
+
37
+ $this->setCollection($collection);
38
+
39
+ return Mage_Adminhtml_Block_Widget_Grid::_prepareCollection();
40
+ }
41
+
42
+ /**
43
+ * Add columns to the grid
44
+ *
45
+ * @return Bronto_Email_Block_Adminhtml_System_Email_Template_Grid
46
+ */
47
+ protected function _prepareColumns()
48
+ {
49
+ if (!Mage::helper('bronto_email')->isEnabled()) {
50
+ return parent::_prepareColumns();
51
+ }
52
+
53
+ $this->addColumn(
54
+ 'template_id',
55
+ array(
56
+ 'header' => Mage::helper('adminhtml')->__('ID'),
57
+ 'index' => 'template_id'
58
+ )
59
+ );
60
+
61
+ $this->addColumn(
62
+ 'added_at',
63
+ array(
64
+ 'header' => Mage::helper('adminhtml')->__('Date Added'),
65
+ 'index' => 'added_at',
66
+ 'gmtoffset' => true,
67
+ 'type' => 'datetime'
68
+ )
69
+ );
70
+
71
+ $this->addColumn(
72
+ 'modified_at',
73
+ array(
74
+ 'header' => Mage::helper('adminhtml')->__('Date Updated'),
75
+ 'index' => 'modified_at',
76
+ 'gmtoffset' => true,
77
+ 'type' => 'datetime'
78
+ )
79
+ );
80
+
81
+ $this->addColumn(
82
+ 'code',
83
+ array(
84
+ 'header' => Mage::helper('adminhtml')->__('Name'),
85
+ 'index' => 'template_code'
86
+ )
87
+ );
88
+
89
+ $this->addColumn(
90
+ 'message_name',
91
+ array(
92
+ 'header' => Mage::helper('adminhtml')->__('Bronto Message'),
93
+ 'index' => 'bronto_message_name'
94
+ )
95
+ );
96
+
97
+ $this->addColumn(
98
+ 'store',
99
+ array(
100
+ 'header' => Mage::helper('adminhtml')->__('Store'),
101
+ 'index' => 'storename'
102
+ )
103
+ );
104
+
105
+ return $this;
106
+ }
107
+ }
app/code/community/Bronto/Email/Block/Adminhtml/System/Email/Template/Grid/Renderer/Message.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Block_Adminhtml_System_Email_Template_Grid_Renderer_Message extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
9
+ {
10
+ /**
11
+ * @param Varien_Object $row
12
+ * @return string
13
+ */
14
+ public function render(Varien_Object $row)
15
+ {
16
+ $skinUrl = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_SKIN) . 'adminhtml/default/default/bronto/';
17
+
18
+ if ($row->getBrontoMessageApproved()) {
19
+ return '
20
+ <img src="' . $skinUrl . 'images/message_approved.gif" style="vertical-align:top;padding-right:1px" />
21
+ <strong>Approved!</strong>
22
+ ';
23
+ } else {
24
+ return '
25
+ <img src="' . $skinUrl . 'images/message_not_approved.gif" style="vertical-align:top;padding-right:1px" />
26
+ <strong>Not Approved!</strong>
27
+ ';
28
+ }
29
+ }
30
+ }
app/code/community/Bronto/Email/Helper/Contact.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Helper_Contact extends Bronto_Common_Helper_Contact
9
+ {
10
+ /**
11
+ * Retrieve helper module name
12
+ *
13
+ * @return string
14
+ */
15
+ protected function _getModuleName()
16
+ {
17
+ return 'Bronto_Email';
18
+ }
19
+
20
+ /**
21
+ * @param string $email
22
+ * @return Bronto_Api_Contact_Row
23
+ */
24
+ public function getContactByEmail($email, $customSource = 'bronto_email', $store = null)
25
+ {
26
+ return parent::getContactByEmail($email, $customSource, $store);
27
+ }
28
+ }
app/code/community/Bronto/Email/Helper/Data.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Helper_Data extends Bronto_Common_Helper_Data implements Bronto_Common_Helper_DataInterface
9
+ {
10
+ const XML_PATH_ENABLED = 'bronto_email/settings/enabled';
11
+ const XML_PATH_LOG_ENABLED = 'bronto_email/settings/log_enabled';
12
+ const XML_PATH_LOG_FIELDS_ENABLED = 'bronto_email/settings/log_fields_enabled';
13
+
14
+ /**
15
+ * Retrieve helper module name
16
+ *
17
+ * @return string
18
+ */
19
+ protected function _getModuleName()
20
+ {
21
+ return 'Bronto_Email';
22
+ }
23
+
24
+ /**
25
+ * Disable the module in the admin configuration
26
+ *
27
+ * @return bool
28
+ */
29
+ public function disableModule($scope = 'default', $scopeId = 0)
30
+ {
31
+ return $this->_disableModule(self::XML_PATH_ENABLED, $scope, $scopeId);
32
+ }
33
+
34
+ /**
35
+ * @return bool
36
+ */
37
+ public function isEnabled()
38
+ {
39
+ return (bool) Mage::getStoreConfig(self::XML_PATH_ENABLED);
40
+ }
41
+
42
+ /**
43
+ * @return bool
44
+ */
45
+ public function isLogEnabled()
46
+ {
47
+ return (bool) Mage::getStoreConfig(self::XML_PATH_LOG_ENABLED);
48
+ }
49
+
50
+ /**
51
+ * @return bool
52
+ */
53
+ public function isLogFieldsEnabled()
54
+ {
55
+ return (bool) Mage::getStoreConfig(self::XML_PATH_LOG_FIELDS_ENABLED);
56
+ }
57
+ }
app/code/community/Bronto/Email/Helper/Field.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Helper_Field extends Bronto_Common_Helper_Field
9
+ {
10
+ /**
11
+ * Retrieve helper module name
12
+ *
13
+ * @return string
14
+ */
15
+ protected function _getModuleName()
16
+ {
17
+ return 'Bronto_Email';
18
+ }
19
+ }
app/code/community/Bronto/Email/Helper/Message.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Helper_Message extends Bronto_Common_Helper_Message
9
+ {
10
+ /**
11
+ * Retrieve helper module name
12
+ *
13
+ * @return string
14
+ */
15
+ protected function _getModuleName()
16
+ {
17
+ return 'Bronto_Email';
18
+ }
19
+ }
app/code/community/Bronto/Email/Model/Email/Message.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Model_Email_Message extends Bronto_Common_Model_Email_Message
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_helper = 'bronto_email';
14
+
15
+ /**
16
+ * Log about the functionality of sending the email before it goes out
17
+ *
18
+ * @param Bronto_Api_Contact_Row $contact
19
+ * @param Bronto_Api_Message_Row $message
20
+ *
21
+ * @return void
22
+ */
23
+ protected function _beforeSend(Bronto_Api_Contact_Row $contact, Bronto_Api_Message_Row $message)
24
+ {
25
+ Mage::dispatchEvent('bronto_email_send_before');
26
+
27
+ if (Mage::helper('bronto_email')->isLogEnabled()) {
28
+ $this->_log = Mage::getModel('bronto_email/log');
29
+ $this->_log->setCustomerEmail($contact->email);
30
+ $this->_log->setContactId($contact->id);
31
+ $this->_log->setMessageId($message->id);
32
+ $this->_log->setMessageName($message->name);
33
+ $this->_log->setSuccess(0);
34
+ $this->_log->setSentAt(new Zend_Db_Expr('NOW()'));
35
+ $this->_log->save();
36
+ }
37
+ }
38
+
39
+ /**
40
+ * Log data on sending message
41
+ *
42
+ * @param bool $success
43
+ * @param string $error
44
+ * @param Bronto_Api_Delivery_Row $delivery
45
+ *
46
+ * @return void
47
+ */
48
+ protected function _afterSend($success, $error = null, Bronto_Api_Delivery_Row $delivery = null)
49
+ {
50
+ Mage::dispatchEvent('bronto_email_send_after');
51
+
52
+ if (Mage::helper('bronto_email')->isLogEnabled()) {
53
+ $this->_log->setSuccess((int) $success);
54
+ if (!empty($error)) {
55
+ $this->_log->setError($error);
56
+ }
57
+ if ($delivery) {
58
+ $this->_log->setDeliveryId($delivery->id);
59
+ if (Mage::helper('bronto_email')->isLogFieldsEnabled()) {
60
+ $this->_log->setFields(serialize($delivery->getFields()));
61
+ }
62
+ }
63
+ $this->_log->save();
64
+ $this->_log = null;
65
+ }
66
+ }
67
+ }
app/code/community/Bronto/Email/Model/Log.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Model_Log extends Mage_Core_Model_Abstract
9
+ {
10
+ protected function _construct()
11
+ {
12
+ parent::_construct();
13
+ $this->_init('bronto_email/log');
14
+ }
15
+ }
app/code/community/Bronto/Email/Model/Mysql4/Log.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Model_Mysql4_Log extends Mage_Core_Model_Mysql4_Abstract
9
+ {
10
+ public function _construct()
11
+ {
12
+ $this->_init('bronto_email/log', 'log_id');
13
+ }
14
+ }
app/code/community/Bronto/Email/Model/Mysql4/Log/Collection.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Model_Mysql4_Log_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
9
+ {
10
+ protected function _construct()
11
+ {
12
+ parent::_construct();
13
+ $this->_init('bronto_email/log');
14
+ }
15
+
16
+ /**
17
+ * Specify collection select order by attribute value
18
+ * Backward compatibility with EAV collection
19
+ *
20
+ * @param string $attribute
21
+ * @param string $dir
22
+ * @return Bronto_Email_Model_Mysql4_Log_Collection
23
+ */
24
+ public function addAttributeToSort($attribute, $dir = 'asc')
25
+ {
26
+ $this->addOrder($attribute, $dir);
27
+ return $this;
28
+ }
29
+
30
+ /**
31
+ * Delete all the entities in the collection
32
+ */
33
+ public function delete()
34
+ {
35
+ foreach ($this->getItems() as $item) {
36
+ $item->delete($item);
37
+ }
38
+ return $this;
39
+ }
40
+ }
app/code/community/Bronto/Email/Model/Observer.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Model_Observer
9
+ {
10
+ const NOTICE_IDENTIFER = 'bronto_email';
11
+
12
+ /**
13
+ * @param Varien_Event_Observer $observer
14
+ * @return mixed
15
+ */
16
+ public function checkBrontoRequirements(Varien_Event_Observer $observer)
17
+ {
18
+ if (!Mage::getSingleton('admin/session')->isLoggedIn()) {
19
+ return;
20
+ }
21
+
22
+ // Verify Requirements
23
+ if (!Mage::helper(self::NOTICE_IDENTIFER)->varifyRequirements(self::NOTICE_IDENTIFER, array('soap', 'openssl'))) {
24
+ return;
25
+ }
26
+ }
27
+ }
app/code/community/Bronto/Email/Model/System/Config/Source/Email/Template.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ class Bronto_Email_Model_System_Config_Source_Email_Template extends Mage_Adminhtml_Model_System_Config_Source_Email_Template
5
+ {
6
+
7
+ /**
8
+ * Generate list of email templates
9
+ *
10
+ * @return array
11
+ */
12
+ public function toOptionArray()
13
+ {
14
+ if(!$collection = Mage::registry('config_system_email_template')) {
15
+ if (Mage::helper('bronto_email')->isEnabled() && Mage::app()->getRequest()->getParam('store')) {
16
+ if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
17
+ $store = Mage::app()->getStore($storeCode);
18
+ $storeId = $store->getId();
19
+ }
20
+ $collection = Mage::getResourceModel('core/email_template_collection')
21
+ ->addFieldToFilter('store_id', $storeId)
22
+ ->load();
23
+
24
+ Mage::register('config_system_email_template', $collection);
25
+ } else {
26
+ $collection = Mage::getResourceModel('core/email_template_collection')
27
+ ->load();
28
+
29
+ Mage::register('config_system_email_template', $collection);
30
+ }
31
+ }
32
+ $options = $collection->toOptionArray();
33
+ $templateName = Mage::helper('adminhtml')->__('Default Template from Locale');
34
+ $nodeName = str_replace('/', '_', $this->getPath());
35
+ $templateLabelNode = Mage::app()->getConfig()->getNode(self::XML_PATH_TEMPLATE_EMAIL . $nodeName . '/label');
36
+ if ($templateLabelNode) {
37
+ $templateName = Mage::helper('adminhtml')->__((string)$templateLabelNode);
38
+ $templateName = Mage::helper('adminhtml')->__('%s (Default Template from Locale)', $templateName);
39
+ }
40
+ array_unshift(
41
+ $options,
42
+ array(
43
+ 'value'=> $nodeName,
44
+ 'label' => $templateName
45
+ )
46
+ );
47
+ return $options;
48
+ }
49
+
50
+ }
app/code/community/Bronto/Email/Model/Template/Import.php ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Model_Template_Import extends Mage_Core_Model_Email_Template
9
+ {
10
+ /**
11
+ * @var array
12
+ */
13
+ private $_templateCollection;
14
+
15
+ /**
16
+ * @var [type]
17
+ */
18
+ private $_apiToken;
19
+
20
+ /**
21
+ * @var [type]
22
+ */
23
+ private $_apiObject;
24
+
25
+ public function _construct()
26
+ {
27
+ // Verify requirements
28
+ if (!extension_loaded('soap') || !extension_loaded('openssl') ||
29
+ !$this->_apiToken = Mage::helper('bronto_common')->getApiToken()) {
30
+ if (Mage::helper('bronto_email')->isEnabled()) {
31
+ Mage::helper('bronto_email')->disableModule();
32
+ }
33
+ }
34
+
35
+ parent::_construct();
36
+ }
37
+
38
+ public function loadTemplateCollection()
39
+ {
40
+ if ($this->_apiToken) {
41
+ $this->_templateCollection = Mage::getResourceSingleton('core/email_template_collection');
42
+ }
43
+ return $this;
44
+ }
45
+
46
+ public function importTemplates()
47
+ {
48
+ $allStores = Mage::app()->getStores();
49
+ //process existing
50
+ $token = Mage::helper('bronto_common')->getApiToken();
51
+ if($token) {
52
+ $this->_apiObject = new Bronto_Api_Message(array(
53
+ 'api' => new Bronto_Api($token)
54
+ ));
55
+
56
+ //process existing
57
+ $this->loadTemplateCollection();
58
+ foreach ($this->_templateCollection as $template) {
59
+ $template->setStoreId(1);
60
+ $this->processMessage($template);
61
+ }
62
+ }
63
+ //process defaults
64
+ foreach ($allStores as $_eachStoreId => $val)
65
+ {
66
+ $_storeCode = Mage::app()->getStore($_eachStoreId)->getCode();
67
+ $_storeId = Mage::app()->getStore($_eachStoreId)->getId();
68
+
69
+ $token = Mage::helper('bronto_common')->getApiToken($_storeId);
70
+ if($token) {
71
+ $this->_apiObject = new Bronto_Api_Message(array(
72
+ 'api' => new Bronto_Api($token)
73
+ ));
74
+
75
+ //process default
76
+ $templates = Mage::getModel('bronto_common/email_message')->getDefaultTemplates();
77
+ $i = 0;
78
+ foreach($templates as $templateToLoad => $temp) {
79
+ $template = Mage::getModel('bronto_common/email_message');
80
+ $template->loadDefault($templateToLoad);
81
+ $template->setOrigTemplateCode($templateToLoad);
82
+ $template->setTemplateCode($_storeCode . '_' . $templateToLoad);
83
+ $template->setAddedAt(Varien_Date::formatDate(true, true));
84
+ $template->unsTemplateId();
85
+ $template->setStoreId($_storeId);
86
+ $this->processMessage($template);
87
+ }
88
+ }
89
+ }
90
+
91
+ return $this;
92
+ }
93
+
94
+ protected function processMessage($template)
95
+ {
96
+ $data = $template->getData();
97
+ $emt = Mage::getModel('bronto_common/email_message_templatefilter');
98
+
99
+ if(!isset($data['bronto_message_id']) || $data['bronto_message_id'] == '') {
100
+ try{
101
+ // Send message template to Bronto
102
+ $message = new Bronto_Api_Message_Row(array(
103
+ 'apiObject' => $this->_apiObject
104
+ ));
105
+
106
+ $message->name = $data['template_code'];
107
+ $message->status = 'active';
108
+ $message->content = array(
109
+ array(
110
+ 'type' => 'html',
111
+ 'subject' => $emt->filter($data['template_subject']),
112
+ 'content' => $emt->filter($data['template_text']),
113
+ ),
114
+ array(
115
+ 'type' => 'text',
116
+ 'subject' => $emt->filter($data['template_subject']),
117
+ 'content' => $emt->filter($this->ripTags($data['template_text'])),
118
+ )
119
+ );
120
+ $message->subject = $emt->filter($data['template_subject']);
121
+ $message->save();
122
+ $template->setBrontoMessageId($message->id);
123
+ $template->setBrontoMessageName($message->name);
124
+ $template->setBrontoMessageApproved(0);
125
+ $template->save();
126
+ }
127
+ catch(Exception $e) {
128
+ Mage::log('Bronto Import:' . $e->getMessage());
129
+ }
130
+ }
131
+ }
132
+
133
+ protected function ripTags($string)
134
+ {
135
+ $string = preg_replace ('/<[^>]*>/', ' ', $string);
136
+ // ----- remove multiple spaces -----
137
+ $string = trim(preg_replace('/ {2,}/', ' ', $string));
138
+ return $string;
139
+ }
140
+ }
app/code/community/Bronto/Email/Test/Config/Config.php ADDED
@@ -0,0 +1,216 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_Email_Test_Config_Config
3
+ extends EcomDev_PHPUnit_Test_Case_Config
4
+ {
5
+ public function blocksProvider()
6
+ {
7
+ return array(
8
+ array('bronto_email/adminhtml_system_config_about', 'Bronto_Email_Block_Adminhtml_System_Config_About'),
9
+ array('bronto_email/adminhtml_system_email_log', 'Bronto_Email_Block_Adminhtml_System_Email_Log'),
10
+ array('bronto_email/adminhtml_system_email_log_grid', 'Bronto_Email_Block_Adminhtml_System_Email_Log_Grid'),
11
+ array('bronto_email/adminhtml_system_email_log_grid_renderer_customer', 'Bronto_Email_Block_Adminhtml_System_Email_Log_Grid_Renderer_Customer'),
12
+ array('bronto_email/adminhtml_system_email_log_grid_renderer_fields', 'Bronto_Email_Block_Adminhtml_System_Email_Log_Grid_Renderer_Fields'),
13
+ array('bronto_email/adminhtml_system_email_template', 'Bronto_Email_Block_Adminhtml_System_Email_Template'),
14
+ array('bronto_email/adminhtml_system_email_template_edit', 'Bronto_Email_Block_Adminhtml_System_Email_Template_Edit'),
15
+ array('bronto_email/adminhtml_system_email_template_edit_form', 'Bronto_Email_Block_Adminhtml_System_Email_Template_Edit_Form'),
16
+ array('bronto_email/adminhtml_system_email_template_grid', 'Bronto_Email_Block_Adminhtml_System_Email_Template_Grid'),
17
+ array('bronto_email/adminhtml_system_email_template_grid_renderer_message', 'Bronto_Email_Block_Adminhtml_System_Email_Template_Grid_Renderer_Message'),
18
+ );
19
+ }
20
+
21
+ public function resourceModelProvider()
22
+ {
23
+ return array(
24
+ array('bronto_email_mysql4/log', 'Bronto_Email_Model_Mysql4_Log'),
25
+ array('bronto_email_mysql4/log_collection', 'Bronto_Email_Model_Mysql4_Log_Collection'),
26
+ );
27
+ }
28
+
29
+ public function modelsProvider()
30
+ {
31
+ return array(
32
+ array('bronto_email/log', 'Bronto_Email_Model_Log'),
33
+ array('bronto_email/email_message', 'Bronto_Email_Model_Email_Message'),
34
+ array('bronto_email/template_import', 'Bronto_Email_Model_Template_Import'),
35
+ array('bronto_email/observer', 'Bronto_Email_Model_Observer'),
36
+ );
37
+ }
38
+
39
+ public function helpersProvider()
40
+ {
41
+ return array(
42
+ array('bronto_email/data', 'Bronto_Email_Helper_Data'),
43
+ array('bronto_email/email', 'Bronto_Email_Helper_Email'),
44
+ array('bronto_email/field', 'Bronto_Email_Helper_Field'),
45
+ array('bronto_email/message', 'Bronto_Email_Helper_Message'),
46
+ array('bronto_email/contact', 'Bronto_Email_Helper_Contact'),
47
+ );
48
+ }
49
+
50
+ public function observersProvider()
51
+ {
52
+ return array(
53
+ array('adminhtml', 'controller_action_predispatch', 'bronto_email/observer', 'checkBrontoRequirements')
54
+ );
55
+ }
56
+
57
+ public function definedLayoutFilesProvider()
58
+ {
59
+ return array(
60
+ array('adminhtml', 'bronto/email.xml'),
61
+ );
62
+ }
63
+
64
+ public function themeLayoutFilesExistProvider()
65
+ {
66
+ return array(
67
+ array('adminhtml', 'bronto/email.xml', 'default', 'default'),
68
+ );
69
+ }
70
+
71
+ public function dependsProvider()
72
+ {
73
+ return array(
74
+ array('Bronto_Common'),
75
+ );
76
+ }
77
+
78
+ /**
79
+ * @test
80
+ * @group amd
81
+ * @group config
82
+ */
83
+ public function assertEmailModuleVersionGreaterThanOrEquals()
84
+ {
85
+ $this->assertModuleVersionGreaterThanOrEquals('1.1.1');
86
+ }
87
+
88
+ /**
89
+ * @test
90
+ * @group amd
91
+ * @group config
92
+ */
93
+ public function assertEmailModuleInCommunityCodePool()
94
+ {
95
+ $this->assertModuleCodePool('community');
96
+ }
97
+
98
+ /**
99
+ * @test
100
+ * @group amd
101
+ * @group config
102
+ * @dataProvider dependsProvider
103
+ */
104
+ public function assertEmailModuleDepends(
105
+ $requiredModuleName
106
+ ) {
107
+ $this->assertModuleDepends($requiredModuleName);
108
+ }
109
+
110
+ /**
111
+ * @test
112
+ * @group amd
113
+ * @group config
114
+ * @dataProvider modelsProvider
115
+ */
116
+ public function assertEmailModelAliases(
117
+ $classAlias,
118
+ $expectedClassName
119
+ ) {
120
+ $this->assertModelAlias($classAlias, $expectedClassName);
121
+ }
122
+
123
+ /**
124
+ * @test
125
+ * @group amd
126
+ * @group config
127
+ * @dataProvider resourceModelProvider
128
+ */
129
+ public function assertEmailResourceModelAliases(
130
+ $classAlias,
131
+ $expectedClassName
132
+ ) {
133
+ $this->assertResourceModelAlias($classAlias, $expectedClassName);
134
+ }
135
+
136
+
137
+ /**
138
+ * @test
139
+ * @group amd
140
+ * @group config
141
+ * @dataProvider blocksProvider
142
+ */
143
+ public function assertEmailBlockAliases(
144
+ $classAlias,
145
+ $expectedClassName
146
+ ) {
147
+ $this->assertBlockAlias($classAlias, $expectedClassName);
148
+ }
149
+
150
+ /**
151
+ * @test
152
+ * @group amd
153
+ * @group config
154
+ * @dataProvider helpersProvider
155
+ */
156
+ public function assertEmailHelperAliases(
157
+ $classAlias,
158
+ $expectedClassName
159
+ ) {
160
+ $this->assertHelperAlias($classAlias, $expectedClassName);
161
+ }
162
+
163
+ /**
164
+ * @test
165
+ * @group amd
166
+ * @group config
167
+ * @dataProvider observersProvider
168
+ */
169
+ function assertEmailEventObserverDefined (
170
+ $area,
171
+ $eventName,
172
+ $observerClassAlias,
173
+ $observerMethod
174
+ ) {
175
+ $this->assertEventObserverDefined(
176
+ $area,
177
+ $eventName,
178
+ $observerClassAlias,
179
+ $observerMethod
180
+ );
181
+ }
182
+
183
+ /**
184
+ * @test
185
+ * @group amd
186
+ * @group config
187
+ * @dataProvider definedLayoutFilesProvider
188
+ */
189
+ public function assertEmailLayoutFileDefined (
190
+ $area,
191
+ $expectedFileName
192
+ ) {
193
+ $this->assertLayoutFileDefined($area, $expectedFileName);
194
+ }
195
+
196
+ /**
197
+ * @test
198
+ * @group amd
199
+ * @group config
200
+ * @dataProvider themeLayoutFilesExistProvider
201
+ */
202
+ public function assertEmailLayoutFileExistsInTheme (
203
+ $area,
204
+ $filename,
205
+ $theme,
206
+ $designPackage
207
+ ) {
208
+ $this->assertLayoutFileExistsInTheme(
209
+ $area,
210
+ $filename,
211
+ $theme,
212
+ $designPackage
213
+ );
214
+ }
215
+
216
+ }
app/code/community/Bronto/Email/Test/Model/Email/Message.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Bronto_Email_Test_Model_Email_Message extends Bronto_Common_Test_Model_Checkout
4
+ {
5
+ /**
6
+ * @test
7
+ */
8
+ public function testOrderEmailSent()
9
+ {
10
+ $mockOrder = $this->getModelMock('sales/order', array('sendNewOrderEmail'));
11
+ $mockOrder->expects($this->any())
12
+ ->method('sendNewOrderEmail')
13
+ ->will($this->returnCallback(
14
+ array($this, '')
15
+ ));
16
+ $this->replaceByMock('model', 'sales/order', $mockOrder);
17
+
18
+ $order = $this->createRandomGuestOrder();
19
+
20
+ $this->assertEventDispatchedExactly('bronto_email_send_before', 1);
21
+ $this->assertEventDispatchedExactly('bronto_email_send_after', 1);
22
+
23
+ return $order;
24
+ }
25
+
26
+ /**
27
+ * @test
28
+ * @depends testOrderEmailSent
29
+ */
30
+ public function testShipmentEmailSent(Mage_Sales_Model_Order $order)
31
+ {
32
+ $this->createShipmentForOrder($order);
33
+
34
+ $this->assertEventDispatchedExactly('bronto_email_send_before', 1);
35
+ $this->assertEventDispatchedExactly('bronto_email_send_after', 1);
36
+ }
37
+ }
app/code/community/Bronto/Email/controllers/Adminhtml/System/Email/LogController.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Email
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.1
7
+ */
8
+ class Bronto_Email_Adminhtml_System_Email_LogController extends Mage_Adminhtml_Controller_Action
9
+ {
10
+ protected function _initAction()
11
+ {
12
+ $this->_title($this->__('Bronto Deliveries'))->_title($this->__('Logs'));
13
+ $this->loadLayout()
14
+ ->_setActiveMenu('system/email/log')
15
+ ->_addBreadcrumb(
16
+ Mage::helper('bronto_email')->__('Bronto Delivery Log'),
17
+ Mage::helper('bronto_email')->__('Bronto Delivery Log')
18
+ );
19
+ return $this;
20
+ }
21
+
22
+ public function indexAction()
23
+ {
24
+ $this->_initAction()->renderLayout();
25
+ }
26
+
27
+ /**
28
+ * Deletes all log history
29
+ */
30
+ public function clearAction()
31
+ {
32
+ /* @var $collection Bronto_Email_Model_Mysql4_Log_Collection */
33
+ $collection = Mage::getModel('bronto_email/log')->getCollection();
34
+ $collection->delete();
35
+ Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('bronto_email')->__('All log entries have been deleted'));
36
+ $this->_redirect('*/*/index');
37
+ }
38
+ }
app/code/community/Bronto/Email/controllers/Adminhtml/System/Email/TemplateController.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @var Mage_Adminhtml_System_Email_TemplateController
5
+ */
6
+ require_once 'Mage/Adminhtml/controllers/System/Email/TemplateController.php';
7
+
8
+ /**
9
+ * @package Bronto\Email
10
+ * @copyright 2011-2013 Bronto Software, Inc.
11
+ * @version 1.1.1
12
+ */
13
+ class Bronto_Email_Adminhtml_System_Email_TemplateController extends Mage_Adminhtml_System_Email_TemplateController
14
+ {
15
+ public function saveAction()
16
+ {
17
+ if (!Mage::helper('bronto_email')->isEnabled()) {
18
+ return parent::saveAction();
19
+ }
20
+
21
+ $request = $this->getRequest();
22
+ $id = $this->getRequest()->getParam('id');
23
+
24
+ $template = $this->_initTemplate('id');
25
+ if (!$template->getId() && $id) {
26
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('adminhtml')->__('This Email template no longer exists.'));
27
+ $this->_redirect('*/*/');
28
+ return;
29
+ }
30
+
31
+ try {
32
+
33
+
34
+ $messages = Mage::helper('bronto_common/message')->getAllMessageOptions();
35
+ foreach ($messages as $message) {
36
+ if ($message['value'] == $request->getParam('bronto_message_id')) {
37
+ $messageName = $message['label'];
38
+ break;
39
+ }
40
+ }
41
+
42
+ $template->setTemplateCode($request->getParam('template_code'))
43
+ ->setBrontoMessageId($request->getParam('bronto_message_id'))
44
+ ->setBrontoMessageName(isset($messageName) ? $messageName : 'Unknown')
45
+ ->setModifiedAt(Mage::getSingleton('core/date')->gmtDate())
46
+ ->setOrigTemplateCode($request->getParam('orig_template_code'))
47
+ ->setOrigTemplateVariables($request->getParam('orig_template_variables'))
48
+ ->setStoreId($request->getParam('store_id'));
49
+
50
+ if (!$template->getId() || !$template->getAddedAt()) {
51
+ $template->setAddedAt(Mage::getSingleton('core/date')->gmtDate());
52
+ }
53
+
54
+ $template->save();
55
+ Mage::getSingleton('adminhtml/session')->setFormData(false);
56
+ Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('The email template has been saved.'));
57
+ $this->_redirect('*/*');
58
+
59
+ } catch (Exception $e) {
60
+ Mage::getSingleton('adminhtml/session')->setData('email_template_form_data', $this->getRequest()->getParams());
61
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
62
+ $this->_forward('new');
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Set template data to retrieve it in template info form
68
+ */
69
+ public function defaultTemplateAction()
70
+ {
71
+ if (!Mage::helper('bronto_email')->isEnabled()) {
72
+ return parent::defaultTemplateAction();
73
+ }
74
+
75
+ $template = $this->_initTemplate('id');
76
+ $templateCode = $this->getRequest()->getParam('code');
77
+
78
+ $template->loadDefault($templateCode, $this->getRequest()->getParam('locale'));
79
+ $template->setData('orig_template_code', $templateCode);
80
+ $template->setData('template_variables', Zend_Json::encode($template->getVariablesOptionArray(true)));
81
+
82
+ $templateBlock = $this->getLayout()->createBlock('adminhtml/system_email_template_edit');
83
+ $template->setData('orig_template_used_default_for', $templateBlock->getUsedDefaultForPaths(false));
84
+
85
+ // Edit: Remove unneeded variables
86
+ $template->unsetData('template_styles');
87
+ $template->unsetData('template_text');
88
+ $template->unsetData('template_type');
89
+ $template->unsetData('template_subject');
90
+ // End
91
+
92
+ $this->getResponse()->setBody(Mage::helper('core')->jsonEncode($template->getData()));
93
+ }
94
+
95
+ public function importAction()
96
+ {
97
+ try {
98
+ $importModel = Mage::getModel('bronto_email/template_import');
99
+ $importModel->importTemplates();
100
+ Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('adminhtml')->__('The email templates have been successfully imported.'));
101
+ $this->_redirect('*/*');
102
+
103
+ } catch (Exception $e) {
104
+ Mage::getSingleton('adminhtml/session')->addError('There was an error importing the templates.');
105
+ $this->_redirect('*/*');
106
+ }
107
+ }
108
+
109
+ public function ajaxlistAction()
110
+ {
111
+ $request = $this->getRequest();
112
+ $messages = Mage::helper('bronto_common/message')->getMessagesOptionsArray($request->getParam('id'));
113
+ foreach ($messages as $message) {
114
+ echo sprintf('<option value="%s">%s</option>', $message['value'], $message['label']);
115
+ }
116
+ }
117
+ }
app/code/community/Bronto/Email/etc/adminhtml.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <admin>
6
+ <children>
7
+ <system>
8
+ <children>
9
+ <config>
10
+ <children>
11
+ <bronto_email translate="title" module="bronto_email">
12
+ <title>Bronto Email</title>
13
+ <sort_order>200</sort_order>
14
+ </bronto_email>
15
+ </children>
16
+ </config>
17
+ </children>
18
+ </system>
19
+ </children>
20
+ </admin>
21
+ </resources>
22
+ </acl>
23
+ </config>
app/code/community/Bronto/Email/etc/config.xml ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Bronto_Email>
5
+ <version>1.1.2</version>
6
+ </Bronto_Email>
7
+ </modules>
8
+ <global>
9
+ <helpers>
10
+ <bronto_email>
11
+ <class>Bronto_Email_Helper</class>
12
+ </bronto_email>
13
+ </helpers>
14
+ <blocks>
15
+ <bronto_email>
16
+ <class>Bronto_Email_Block</class>
17
+ </bronto_email>
18
+ <adminhtml>
19
+ <rewrite>
20
+ <system_email_template>Bronto_Email_Block_Adminhtml_System_Email_Template</system_email_template>
21
+ <system_email_template_grid>Bronto_Email_Block_Adminhtml_System_Email_Template_Grid</system_email_template_grid>
22
+ <system_email_template_edit>Bronto_Email_Block_Adminhtml_System_Email_Template_Edit</system_email_template_edit>
23
+ <system_email_template_edit_form>Bronto_Email_Block_Adminhtml_System_Email_Template_Edit_Form</system_email_template_edit_form>
24
+ </rewrite>
25
+ </adminhtml>
26
+ </blocks>
27
+ <models>
28
+ <bronto_email>
29
+ <class>Bronto_Email_Model</class>
30
+ <resourceModel>bronto_email_mysql4</resourceModel>
31
+ </bronto_email>
32
+ <bronto_email_mysql4>
33
+ <class>Bronto_Email_Model_Mysql4</class>
34
+ <entities>
35
+ <log><table>bronto_email_log</table></log>
36
+ </entities>
37
+ </bronto_email_mysql4>
38
+ <core>
39
+ <rewrite>
40
+ <email_template>Bronto_Email_Model_Email_Message</email_template>
41
+ </rewrite>
42
+ </core>
43
+ <adminhtml>
44
+ <rewrite>
45
+ <system_config_source_email_template>Bronto_Email_Model_System_Config_Source_Email_Template</system_config_source_email_template>
46
+ </rewrite>
47
+ </adminhtml>
48
+ </models>
49
+ <resources>
50
+ <bronto_email_setup>
51
+ <setup>
52
+ <module>Bronto_Email</module>
53
+ </setup>
54
+ <connection>
55
+ <use>core_setup</use>
56
+ </connection>
57
+ </bronto_email_setup>
58
+ <bronto_email_write>
59
+ <connection>
60
+ <use>core_write</use>
61
+ </connection>
62
+ </bronto_email_write>
63
+ <bronto_email_read>
64
+ <connection>
65
+ <use>core_read</use>
66
+ </connection>
67
+ </bronto_email_read>
68
+ </resources>
69
+ </global>
70
+ <admin>
71
+ <routers>
72
+ <adminhtml>
73
+ <args>
74
+ <modules>
75
+ <bronto_email before="Mage_Adminhtml">Bronto_Email_Adminhtml</bronto_email>
76
+ </modules>
77
+ </args>
78
+ </adminhtml>
79
+ </routers>
80
+ </admin>
81
+ <default>
82
+ <bronto_email>
83
+ <settings>
84
+ <enabled>0</enabled>
85
+ <log_enabled>1</log_enabled>
86
+ <log_fields_enabled>1</log_fields_enabled>
87
+ </settings>
88
+ </bronto_email>
89
+ </default>
90
+ <adminhtml>
91
+ <events>
92
+ <controller_action_predispatch>
93
+ <observers>
94
+ <bronto_email_controller_action_predispatch>
95
+ <class>bronto_email/observer</class>
96
+ <method>checkBrontoRequirements</method>
97
+ </bronto_email_controller_action_predispatch>
98
+ </observers>
99
+ </controller_action_predispatch>
100
+ </events>
101
+ <layout>
102
+ <updates>
103
+ <bronto_email>
104
+ <file>bronto/email.xml</file>
105
+ </bronto_email>
106
+ </updates>
107
+ </layout>
108
+ <acl>
109
+ <resources>
110
+ <admin>
111
+ <children>
112
+ <system>
113
+ <children>
114
+ <config>
115
+ <children>
116
+ <bronto_email translate="title" module="bronto_email">
117
+ <title>Bronto Email</title>
118
+ <sort_order>200</sort_order>
119
+ </bronto_email>
120
+ </children>
121
+ </config>
122
+ </children>
123
+ </system>
124
+ </children>
125
+ </admin>
126
+ </resources>
127
+ </acl>
128
+ </adminhtml>
129
+ <phpunit>
130
+ <suite>
131
+ <modules>
132
+ <Bronto_Email />
133
+ </modules>
134
+ </suite>
135
+ </phpunit>
136
+ </config>
app/code/community/Bronto/Email/etc/system.xml ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <bronto_email translate="label" module="bronto_email">
5
+ <label>Transactional Emails</label>
6
+ <tab>bronto</tab>
7
+ <frontend_type>text</frontend_type>
8
+ <sort_order>600</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
+ <about>
14
+ <frontend_type>text</frontend_type>
15
+ <frontend_model>bronto_email/adminhtml_system_config_about</frontend_model>
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
+ </about>
21
+ <settings translate="label">
22
+ <label>Settings</label>
23
+ <frontend_type>text</frontend_type>
24
+ <sort_order>1</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ <fields>
29
+ <enabled translate="label">
30
+ <label>Enable Module</label>
31
+ <frontend_type>select</frontend_type>
32
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
33
+ <source_model>adminhtml/system_config_source_yesno</source_model>
34
+ <sort_order>0</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
+ </enabled>
39
+ <log_enabled translate="label">
40
+ <label>Log Deliveries</label>
41
+ <depends><enabled>1</enabled></depends>
42
+ <frontend_type>select</frontend_type>
43
+ <source_model>adminhtml/system_config_source_yesno</source_model>
44
+ <sort_order>10</sort_order>
45
+ <show_in_default>1</show_in_default>
46
+ <show_in_website>0</show_in_website>
47
+ <show_in_store>0</show_in_store>
48
+ </log_enabled>
49
+ <log_fields_enabled translate="label">
50
+ <label>Log Delivery Fields</label>
51
+ <depends><enabled>1</enabled></depends>
52
+ <frontend_type>select</frontend_type>
53
+ <source_model>adminhtml/system_config_source_yesno</source_model>
54
+ <sort_order>11</sort_order>
55
+ <show_in_default>1</show_in_default>
56
+ <show_in_website>0</show_in_website>
57
+ <show_in_store>0</show_in_store>
58
+ </log_fields_enabled>
59
+ </fields>
60
+ </settings>
61
+ </groups>
62
+ </bronto_email>
63
+ </sections>
64
+ </config>
app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-install-1.0.0.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ try {
9
+ $installer->run("
10
+
11
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
12
+ ADD COLUMN `bronto_message_id` char(36) NOT NULL default '';
13
+
14
+ ");
15
+ } catch (Exception $e) {
16
+ //
17
+ }
18
+
19
+ try {
20
+ $installer->run("
21
+
22
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
23
+ ADD COLUMN `bronto_message_name` varchar(255) NOT NULL default '';
24
+
25
+ ");
26
+ } catch (Exception $e) {
27
+ //
28
+ }
29
+
30
+ $installer->endSetup();
app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-install-1.0.2.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ $installer->run("
9
+
10
+ CREATE TABLE `{$this->getTable('bronto_email_log')}` (
11
+ `log_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
12
+ `customer_id` int(10) UNSIGNED NULL DEFAULT NULL ,
13
+ `customer_email` varchar(255) NULL DEFAULT NULL ,
14
+ `contact_id` char(36) NULL DEFAULT NULL ,
15
+ `message_id` char(36) NOT NULL ,
16
+ `delivery_id` char(36) NULL DEFAULT NULL ,
17
+ `sent_at` datetime NULL DEFAULT NULL ,
18
+ `success` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 ,
19
+ `error` varchar(255) NULL DEFAULT NULL ,
20
+ PRIMARY KEY (`log_id`),
21
+ INDEX `IDX_BRONTO_EMAIL_LOG_CUSTOMER_EMAIL` (`customer_email`)
22
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
23
+
24
+ ");
25
+
26
+ try {
27
+ $installer->run("
28
+
29
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
30
+ ADD COLUMN `bronto_message_id` char(36) NULL DEFAULT NULL;
31
+
32
+ ");
33
+ } catch (Exception $e) {
34
+ //
35
+ }
36
+
37
+ try {
38
+ $installer->run("
39
+
40
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
41
+ ADD COLUMN `bronto_message_name` varchar(255) NULL DEFAULT NULL;
42
+
43
+ ");
44
+ } catch (Exception $e) {
45
+ //
46
+ }
47
+
48
+ try {
49
+ $installer->run("
50
+
51
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
52
+ ADD COLUMN `bronto_message_approved` tinyint(1) UNSIGNED NOT NULL DEFAULT 1;
53
+
54
+ ");
55
+ } catch (Exception $e) {
56
+ //
57
+ }
58
+
59
+ $installer->endSetup();
app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-install-1.0.5.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ $installer->run("
9
+
10
+ CREATE TABLE `{$this->getTable('bronto_email_log')}` (
11
+ `log_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
12
+ `customer_id` int(10) UNSIGNED NULL DEFAULT NULL ,
13
+ `customer_email` varchar(255) NULL DEFAULT NULL ,
14
+ `contact_id` char(36) NULL DEFAULT NULL ,
15
+ `message_id` char(36) NOT NULL ,
16
+ `delivery_id` char(36) NULL DEFAULT NULL ,
17
+ `sent_at` datetime NULL DEFAULT NULL ,
18
+ `success` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 ,
19
+ `error` varchar(255) NULL DEFAULT NULL ,
20
+ PRIMARY KEY (`log_id`),
21
+ INDEX `IDX_BRONTO_EMAIL_LOG_CUSTOMER_EMAIL` (`customer_email`)
22
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
23
+
24
+ ");
25
+
26
+ try {
27
+ $installer->run("
28
+
29
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
30
+ ADD COLUMN `bronto_message_id` char(36) NULL DEFAULT NULL;
31
+
32
+ ");
33
+ } catch (Exception $e) {
34
+ //
35
+ }
36
+
37
+ try {
38
+ $installer->run("
39
+
40
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
41
+ ADD COLUMN `bronto_message_name` varchar(255) NULL DEFAULT NULL;
42
+
43
+ ");
44
+ } catch (Exception $e) {
45
+ //
46
+ }
47
+
48
+ try {
49
+ $installer->run("
50
+
51
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
52
+ ADD COLUMN `bronto_message_approved` tinyint(1) UNSIGNED NOT NULL DEFAULT 1;
53
+
54
+ ");
55
+ } catch (Exception $e) {
56
+ //
57
+ }
58
+
59
+ $installer->endSetup();
app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-install-1.0.8.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ $installer->run("
9
+
10
+ CREATE TABLE `{$this->getTable('bronto_email_log')}` (
11
+ `log_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
12
+ `customer_id` int(10) unsigned DEFAULT NULL,
13
+ `customer_email` varchar(255) DEFAULT NULL,
14
+ `contact_id` char(36) DEFAULT NULL,
15
+ `message_id` char(36) NOT NULL,
16
+ `message_name` varchar(64) DEFAULT NULL,
17
+ `delivery_id` char(36) DEFAULT NULL,
18
+ `sent_at` datetime DEFAULT NULL,
19
+ `success` tinyint(1) unsigned NOT NULL DEFAULT '0',
20
+ `error` varchar(255) DEFAULT NULL,
21
+ `fields` text,
22
+ PRIMARY KEY (`log_id`),
23
+ KEY `IDX_BRONTO_EMAIL_LOG_CUSTOMER_EMAIL` (`customer_email`),
24
+ KEY `IDX_BRONTO_EMAIL_LOG_SENT_AT` (`sent_at`)
25
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
26
+
27
+ ");
28
+
29
+ try {
30
+ $installer->run("
31
+
32
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
33
+ ADD COLUMN `bronto_message_id` char(36) NULL DEFAULT NULL;
34
+
35
+ ");
36
+ } catch (Exception $e) {
37
+ //
38
+ }
39
+
40
+ try {
41
+ $installer->run("
42
+
43
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
44
+ ADD COLUMN `bronto_message_name` varchar(255) NULL DEFAULT NULL;
45
+
46
+ ");
47
+ } catch (Exception $e) {
48
+ //
49
+ }
50
+
51
+ try {
52
+ $installer->run("
53
+
54
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
55
+ ADD COLUMN `bronto_message_approved` tinyint(1) UNSIGNED NOT NULL DEFAULT 1;
56
+
57
+ ");
58
+ } catch (Exception $e) {
59
+ //
60
+ }
61
+
62
+ $installer->endSetup();
63
+
64
+
app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-install-1.1.2.php ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ $installer->run("
9
+
10
+ CREATE TABLE `{$this->getTable('bronto_email_log')}` (
11
+ `log_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
12
+ `customer_id` int(10) unsigned DEFAULT NULL,
13
+ `customer_email` varchar(255) DEFAULT NULL,
14
+ `contact_id` char(36) DEFAULT NULL,
15
+ `message_id` char(36) NOT NULL,
16
+ `message_name` varchar(64) DEFAULT NULL,
17
+ `delivery_id` char(36) DEFAULT NULL,
18
+ `sent_at` datetime DEFAULT NULL,
19
+ `success` tinyint(1) unsigned NOT NULL DEFAULT '0',
20
+ `error` varchar(255) DEFAULT NULL,
21
+ `fields` text,
22
+ PRIMARY KEY (`log_id`),
23
+ KEY `IDX_BRONTO_EMAIL_LOG_CUSTOMER_EMAIL` (`customer_email`),
24
+ KEY `IDX_BRONTO_EMAIL_LOG_SENT_AT` (`sent_at`)
25
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
26
+
27
+ ");
28
+
29
+ try {
30
+ $installer->run("
31
+
32
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
33
+ ADD COLUMN `bronto_message_id` char(36) NULL DEFAULT NULL;
34
+
35
+ ");
36
+ } catch (Exception $e) {
37
+ //
38
+ }
39
+
40
+ try {
41
+ $installer->run("
42
+
43
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
44
+ ADD COLUMN `bronto_message_name` varchar(255) NULL DEFAULT NULL;
45
+
46
+ ");
47
+ } catch (Exception $e) {
48
+ //
49
+ }
50
+
51
+ try {
52
+ $installer->run("
53
+
54
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
55
+ ADD COLUMN `bronto_message_approved` tinyint(1) UNSIGNED NOT NULL DEFAULT 1;
56
+
57
+ ");
58
+ } catch (Exception $e) {
59
+ //
60
+ }
61
+
62
+ try {
63
+ $installer->run("
64
+
65
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
66
+ ADD COLUMN `store_id` int(10) NOT NULL default '1';
67
+
68
+ ");
69
+
70
+ } catch (Exception $e) {
71
+ Mage::log($e->getMessage());
72
+ }
73
+
74
+ $installer->endSetup();
75
+
app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-upgrade-1.0.0-1.0.2.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ $installer->run("
9
+
10
+ CREATE TABLE `{$this->getTable('bronto_email_log')}` (
11
+ `log_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT ,
12
+ `customer_id` int(10) UNSIGNED NULL DEFAULT NULL ,
13
+ `customer_email` varchar(255) NULL DEFAULT NULL ,
14
+ `contact_id` char(36) NULL DEFAULT NULL ,
15
+ `message_id` char(36) NOT NULL ,
16
+ `delivery_id` char(36) NULL DEFAULT NULL ,
17
+ `sent_at` datetime NULL DEFAULT NULL ,
18
+ `success` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 ,
19
+ `error` varchar(255) NULL DEFAULT NULL ,
20
+ PRIMARY KEY (`log_id`),
21
+ INDEX `IDX_BRONTO_EMAIL_LOG_CUSTOMER_EMAIL` (`customer_email`)
22
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
23
+
24
+ ");
25
+
26
+ try {
27
+ $installer->run("
28
+
29
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
30
+ MODIFY COLUMN `bronto_message_id` char(36) NULL DEFAULT NULL;
31
+
32
+ ");
33
+ } catch (Exception $e) {
34
+ //
35
+ }
36
+
37
+ try {
38
+ $installer->run("
39
+
40
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
41
+ ADD COLUMN `bronto_message_approved` tinyint(1) UNSIGNED NOT NULL DEFAULT 1;
42
+
43
+ ");
44
+ } catch (Exception $e) {
45
+ //
46
+ }
47
+
48
+ $installer->endSetup();
app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-upgrade-1.0.2-1.0.5.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ $installer->endSetup();
app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-upgrade-1.0.5-1.0.8.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ try {
9
+ $installer->run("
10
+
11
+ ALTER TABLE `{$this->getTable('bronto_email_log')}`
12
+ ADD COLUMN `message_name` varchar(64) NULL DEFAULT NULL AFTER `message_id`,
13
+ ADD COLUMN `fields` text NULL AFTER `error`,
14
+ ADD INDEX `IDX_BRONTO_EMAIL_LOG_SENT_AT` (`sent_at`) ;
15
+
16
+ ");
17
+ } catch (Exception $e) {
18
+ //
19
+ }
20
+
21
+ $installer->endSetup();
app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-upgrade-1.0.8-1.1.1.php ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ $installer->endSetup();
app/code/community/Bronto/Email/sql/bronto_email_setup/mysql4-upgrade-1.1.1-1.1.2.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ try {
9
+ $installer->run("
10
+
11
+ ALTER TABLE `{$installer->getTable('core/email_template')}`
12
+ ADD COLUMN `store_id` int(10) NOT NULL default '1';
13
+
14
+ ");
15
+
16
+ } catch (Exception $e) {
17
+ Mage::log($e->getMessage());
18
+ }
19
+
20
+ $installer->endSetup();
app/code/community/Bronto/Newsletter/Block/Adminhtml/System/Config/About.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Newsletter
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.3.5
7
+ */
8
+ class Bronto_Newsletter_Block_Adminhtml_System_Config_About extends Bronto_Common_Block_Adminhtml_System_Config_About
9
+ {
10
+
11
+ /**
12
+ * Description for protected
13
+ * @var string
14
+ * @access protected
15
+ */
16
+ protected $_module = 'bronto_newsletter';
17
+
18
+ /**
19
+ * Description for protected
20
+ * @var string
21
+ * @access protected
22
+ */
23
+ protected $_name = 'Bronto Contact Newsletter Sign-Up for Magento';
24
+ }
app/code/community/Bronto/Newsletter/Block/Adminhtml/System/Config/Cron.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Newsletter
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.3.5
7
+ */
8
+ class Bronto_Newsletter_Block_Adminhtml_System_Config_Cron extends Bronto_Common_Block_Adminhtml_System_Config_Cron
9
+ {
10
+ protected $_jobCode = 'bronto_newsletter_import';
11
+ protected $_hasProgressBar = false;
12
+
13
+ /**
14
+ * @return Bronto_Order_Block_Adminhtml_System_Config_Cron
15
+ */
16
+ protected function _prepareLayout()
17
+ {
18
+ // $this->addButton($this->getLayout()->createBlock('bronto_newsletter/adminhtml_widget_button_reset'));
19
+ $this->addButton($this->getLayout()->createBlock('bronto_newsletter/adminhtml_widget_button_run'));
20
+
21
+ return parent::_prepareLayout();
22
+ }
23
+
24
+ /**
25
+ * @return int
26
+ */
27
+ protected function getProgressBarTotal()
28
+ {
29
+ return $this->getOrderResourceCollection()
30
+ ->addStoreFilter($storeId)
31
+ ->getSize()
32
+ ;
33
+ }
34
+
35
+ /**
36
+ * @return int
37
+ */
38
+ protected function getProgressBarPending()
39
+ {
40
+ return $this->getOrderResourceCollection()
41
+ ->addBrontoNotImportedFilter()
42
+ ->getSize()
43
+ ;
44
+ }
45
+
46
+ /**
47
+ * @return Bronto_Order_Model_Resource_Order_Collection
48
+ */
49
+ protected function getOrderResourceCollection()
50
+ {
51
+ $collection = Mage::getModel('bronto_order/resource_order_collection');
52
+
53
+ if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
54
+ $store = Mage::app()->getStore($storeCode);
55
+ $collection->addStoreFilter($store->getId());
56
+ } else if ($websiteCode = Mage::app()->getRequest()->getParam('website')){
57
+ $website = Mage::app()->getWebsite($websiteCode);
58
+ $collection->addStoreFilter($website->getStoreids());
59
+ } else if ($groupCode = Mage::app()->getRequest()->getParam('group')){
60
+ $website = Mage::app()->getGroup($groupCode)->getWebsite();
61
+ $collection->addStoreFilter($website->getStoreids());
62
+ }
63
+
64
+ return $collection;
65
+ }
66
+ }
app/code/community/Bronto/Newsletter/Block/Adminhtml/Widget/Button/Run.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Newsletter
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Newsletter_Block_Adminhtml_Widget_Button_Run extends Mage_Adminhtml_Block_Widget_Button
9
+ {
10
+ /**
11
+ * Internal constructor not depended on params. Can be used for object initialization
12
+ */
13
+ protected function _construct()
14
+ {
15
+ $this->setLabel('Run Now');
16
+ $this->setOnClick("setLocation('" . Mage::helper('adminhtml')->getUrl('*/newsletter/run') . "'); return false;");
17
+
18
+ if (!extension_loaded('soap') || !extension_loaded('openssl') || !Mage::helper('bronto_common')->getApiToken() || !Mage::helper('bronto_newsletter')->isEnabled()) {
19
+ $this->setDisabled(true)->setClass('disabled');
20
+ }
21
+ }
22
+ }
app/code/community/Bronto/Newsletter/Block/Checkout/Onepage/Newsletter.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Newsletter
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.3.5
7
+ */
8
+ class Bronto_Newsletter_Block_Checkout_Onepage_Newsletter extends Mage_Checkout_Block_Onepage_Abstract
9
+ {
10
+ /**
11
+ * @return bool
12
+ */
13
+ public function isSubscribed()
14
+ {
15
+ return Mage::helper('bronto_newsletter')->isCustomerSubscribed($this->getCustomer());
16
+ }
17
+
18
+ /**
19
+ * @return bool
20
+ */
21
+ public function isEnabled()
22
+ {
23
+ return Mage::helper('bronto_newsletter')->isEnabled();
24
+ }
25
+
26
+ /**
27
+ * @return bool
28
+ */
29
+ public function isEnabledCheckedByDefault()
30
+ {
31
+ return Mage::helper('bronto_newsletter')->isEnabledCheckedByDefault();
32
+ }
33
+
34
+ /**
35
+ * @return bool
36
+ */
37
+ public function isEnabledForGuestCheckout()
38
+ {
39
+ return Mage::helper('bronto_newsletter')->isEnabledForGuestCheckout();
40
+ }
41
+
42
+ /**
43
+ * @return bool
44
+ */
45
+ public function isEnabledForRegisterCheckout()
46
+ {
47
+ return Mage::helper('bronto_newsletter')->isEnabledForRegisterCheckout();
48
+ }
49
+
50
+ /**
51
+ * @return bool
52
+ */
53
+ public function isEnabledIfAlreadySubscribed()
54
+ {
55
+ return Mage::helper('bronto_newsletter')->isEnabledIfAlreadySubscribed();
56
+ }
57
+
58
+ /**
59
+ * @return bool
60
+ */
61
+ public function getCheckboxLabelText()
62
+ {
63
+ return Mage::helper('bronto_newsletter')->getCheckboxLabelText();
64
+ }
65
+ }
app/code/community/Bronto/Newsletter/Helper/Contact.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Newsletter
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.3.5
7
+ */
8
+ class Bronto_Newsletter_Helper_Contact extends Bronto_Common_Helper_Contact
9
+ {
10
+
11
+ /**
12
+ * Description for const
13
+ */
14
+ const XML_PATH_UPDATE_STATUS = 'bronto_newsletter/contacts/update_status';
15
+
16
+ /**
17
+ * Description for const
18
+ */
19
+ const XML_PATH_LISTS = 'bronto_newsletter/contacts/lists';
20
+
21
+ /**
22
+ * @param string $email
23
+ * @param string $customSource
24
+ * @return Bronto_Api_Contact_Row
25
+ */
26
+ public function getContactByEmail($email, $customSource = 'bronto_newsletter', $store = null)
27
+ {
28
+ if ($contact = parent::getContactByEmail($email, $customSource, $store)) {
29
+ if ($this->getUpdateStatus()) {
30
+ // We want to use the Newsletter status
31
+ $contact = $this->setStatusFromNewsletter($contact);
32
+ }
33
+
34
+ $contact = $this->_addContactToLists($contact, $this->getListIds($store));
35
+ }
36
+
37
+ return $contact;
38
+ }
39
+
40
+ /**
41
+ * @param Bronto_Api_Contact_Row $contact
42
+ * @param Mage_Newsletter_Model_Subscriber $subscriber
43
+ * @return Bronto_Api_Contact_Row
44
+ */
45
+ public function setStatusFromNewsletter(Bronto_Api_Contact_Row $contact, Mage_Newsletter_Model_Subscriber $subscriber = null)
46
+ {
47
+ if (!is_object($subscriber) || !($subscriber instanceOf Mage_Newsletter_Model_Subscriber)) {
48
+ /* @var $subscriber Mage_Newsletter_Model_Subscriber */
49
+ $subscriber = Mage::getModel('newsletter/subscriber')->loadByEmail($contact->email);
50
+ }
51
+
52
+ switch ($subscriber->getStatus()) {
53
+ case Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED:
54
+ $contact->status = Bronto_Api_Contact::STATUS_ONBOARDING;
55
+ break;
56
+ case Mage_Newsletter_Model_Subscriber::STATUS_UNSUBSCRIBED:
57
+ $contact->status = Bronto_Api_Contact::STATUS_UNSUBSCRIBED;
58
+ break;
59
+ case Mage_Newsletter_Model_Subscriber::STATUS_NOT_ACTIVE:
60
+ default:
61
+ $contact->status = Bronto_Api_Contact::STATUS_TRANSACTIONAL;
62
+ break;
63
+ }
64
+
65
+ // Special check for old Magento versions
66
+ if (defined('Mage_Newsletter_Model_Subscriber::STATUS_UNCONFIRMED')) {
67
+ if (Mage_Newsletter_Model_Subscriber::STATUS_UNCONFIRMED == $subscriber->getStatus()) {
68
+ $contact->status = Bronto_Api_Contact::STATUS_UNCONFIRMED;
69
+ }
70
+ }
71
+
72
+ $this->writeInfo(" Setting Contact ({$contact->email}) status to: {$contact->status}");
73
+ return $contact;
74
+ }
75
+
76
+ /**
77
+ * @return bool
78
+ */
79
+ public function getUpdateStatus()
80
+ {
81
+ return (bool) Mage::getStoreConfig(self::XML_PATH_UPDATE_STATUS);
82
+ }
83
+
84
+ /**
85
+ * @return array
86
+ */
87
+ public function getListIds($store = null)
88
+ {
89
+ $listIds = Mage::getStoreConfig(self::XML_PATH_LISTS, $store);
90
+ if (empty($listIds)) {
91
+ return array();
92
+ }
93
+
94
+ if (!is_array($listIds)) {
95
+ $listIds = explode(',', $listIds);
96
+ }
97
+
98
+ return $listIds;
99
+ }
100
+
101
+ /**
102
+ * @param Bronto_Api_Contact_Row $contact
103
+ * @param array $listIds
104
+ * @return Bronto_Api_Contact_Row
105
+ */
106
+ protected function _addContactToLists(Bronto_Api_Contact_Row $contact, array $listIds = array())
107
+ {
108
+ if (empty($listIds)) {
109
+ return $contact;
110
+ }
111
+
112
+ foreach ($listIds as $listId) {
113
+ $this->writeInfo(" Adding Contact to list: {$listId}");
114
+ $contact->addToList($listId);
115
+ }
116
+
117
+ return $contact;
118
+ }
119
+
120
+ /**
121
+ * Retrieve helper module name
122
+ *
123
+ * @return string
124
+ */
125
+ protected function _getModuleName()
126
+ {
127
+ return 'Bronto_Newsletter';
128
+ }
129
+ }
app/code/community/Bronto/Newsletter/Helper/Data.php ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Newsletter
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.3.5
7
+ */
8
+ class Bronto_Newsletter_Helper_Data extends Bronto_Common_Helper_Data
9
+ {
10
+ const XML_PATH_ENABLED = 'bronto_newsletter/settings/enabled';
11
+ const XML_PATH_LIMIT = 'bronto_newsletter/settings/limit';
12
+ const XML_PATH_DEFAULT = 'bronto_newsletter/checkout/default_checked';
13
+ const XML_PATH_SHOW_GUEST = 'bronto_newsletter/checkout/show_to_guests';
14
+ const XML_PATH_SHOW_REGISTRAR = 'bronto_newsletter/checkout/show_to_registrars';
15
+ const XML_PATH_SHOW_SUBSCRIBED = 'bronto_newsletter/checkout/show_if_subscribed';
16
+ const XML_PATH_LABEL_TEXT = 'bronto_newsletter/checkout/label_text';
17
+ const XML_PATH_USE_CUSTOM_TEMPLATE = 'bronto_newsletter/checkout/use_custom_template';
18
+ const XML_PATH_BILLING_TEMPLATE = 'bronto_newsletter/checkout/billing_template';
19
+ const XML_PATH_INSTALL_DATE = 'bronto_newsletter/settings/install_date';
20
+ const XML_PATH_UPGRADE_DATE = 'bronto_newsletter/settings/upgrade_date';
21
+
22
+ /**
23
+ * @param string $store
24
+ * @return bool
25
+ */
26
+ public function isEnabled($store = null)
27
+ {
28
+ if (!$this->getApiToken($store)) {
29
+ return false;
30
+ }
31
+
32
+ return (bool) $this->getAdminScopedConfig(self::XML_PATH_ENABLED, $store);
33
+ }
34
+
35
+ /**
36
+ * @param string $path
37
+ * @return bool
38
+ */
39
+ public function disableModule()
40
+ {
41
+ return $this->_disableModule(self::XML_PATH_ENABLED);
42
+ }
43
+
44
+ /**
45
+ * @return int
46
+ */
47
+ public function getLimit()
48
+ {
49
+ if (!$this->isEnabled()) {
50
+ return false;
51
+ }
52
+
53
+ return (int) Mage::getStoreConfig(self::XML_PATH_LIMIT);
54
+ }
55
+
56
+ /**
57
+ * @return bool
58
+ */
59
+ public function isEnabledCheckedByDefault()
60
+ {
61
+ return (bool) Mage::getStoreConfig(self::XML_PATH_DEFAULT);
62
+ }
63
+
64
+ /**
65
+ * @return bool
66
+ */
67
+ public function isEnabledForGuestCheckout()
68
+ {
69
+ return (bool) Mage::getStoreConfig(self::XML_PATH_SHOW_GUEST);
70
+ }
71
+
72
+ /**
73
+ * @return bool
74
+ */
75
+ public function isEnabledForRegisterCheckout()
76
+ {
77
+ return (bool) Mage::getStoreConfig(self::XML_PATH_SHOW_REGISTRAR);
78
+ }
79
+
80
+ /**
81
+ * @return bool
82
+ */
83
+ public function isEnabledIfAlreadySubscribed()
84
+ {
85
+ return (bool) Mage::getStoreConfig(self::XML_PATH_SHOW_SUBSCRIBED);
86
+ }
87
+
88
+ /**
89
+ * @return string
90
+ */
91
+ public function getCheckboxLabelText()
92
+ {
93
+ return Mage::getStoreConfig(self::XML_PATH_LABEL_TEXT);
94
+ }
95
+
96
+ /**
97
+ * @param Mage_Customer_Model_Customer $customer
98
+ * @return boolean
99
+ */
100
+ public function isCustomerSubscribed(Mage_Customer_Model_Customer $customer = null)
101
+ {
102
+ if (!$customer) {
103
+ return false;
104
+ }
105
+
106
+ /* @var $subscriber Mage_Newsletter_Model_Subscriber */
107
+ $subscriber = Mage::getModel('newsletter/subscriber')->loadByCustomer($customer);
108
+ return (bool) $subscriber->isSubscribed();
109
+ }
110
+
111
+ /**
112
+ * @return bool
113
+ */
114
+ public function useCustomBillingTemplate()
115
+ {
116
+ return (bool) Mage::getStoreConfig(self::XML_PATH_USE_CUSTOM_TEMPLATE);
117
+ }
118
+
119
+ /**
120
+ * @return string
121
+ */
122
+ public function getCustomBillingTemplate()
123
+ {
124
+ $template = Mage::getStoreConfig(self::XML_PATH_BILLING_TEMPLATE);
125
+
126
+ if (!$this->useCustomBillingTemplate() || empty($template)) {
127
+ return false;
128
+ }
129
+
130
+ return $template;
131
+ }
132
+
133
+ /**
134
+ * @return string
135
+ */
136
+ public function getCheckoutOnepageBillingTemplate()
137
+ {
138
+ $customTemplate = $this->getCustomBillingTemplate();
139
+
140
+ if (empty($customTemplate)) {
141
+ if ($this->isEnabled()) {
142
+ return 'bronto/newsletter/billing.phtml';
143
+ } else {
144
+ return 'checkout/onepage/billing.phtml';
145
+ }
146
+ }
147
+
148
+ return $customTemplate;
149
+ }
150
+
151
+ /**
152
+ * Retrieve helper module name
153
+ *
154
+ * @return string
155
+ */
156
+ protected function _getModuleName()
157
+ {
158
+ return 'Bronto_Newsletter';
159
+ }
160
+ }
app/code/community/Bronto/Newsletter/Model/Mysql4/Queue.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Short description for file
5
+ *
6
+ * Long description (if any) ...
7
+ *
8
+ * PHP version 5
9
+ *
10
+ * The license text...
11
+ *
12
+ * @category Bronto
13
+ * @package Newsletter
14
+ * @author Jeff Lambert <jeff.lambert@atlanticbt.com>
15
+ * @copyright 2012 Atlantic BT
16
+ * @license http://www.atlanticbt.com/ Atlantic BT
17
+ * @version CVS: $Id:$
18
+ * @link <>
19
+ * @see References to other sections (if any)...
20
+ */
21
+ /**
22
+ * @author Jeff Lambert <jeff.lambert@atlanticbt.com>
23
+ * */
24
+ class Bronto_Newsletter_Model_Mysql4_Queue extends Mage_Core_Model_Mysql4_Abstract
25
+ {
26
+
27
+ /**
28
+ * Short description for function
29
+ *
30
+ * Long description (if any) ...
31
+ *
32
+ * @return void
33
+ * @access public
34
+ */
35
+ public function _construct()
36
+ {
37
+ $this->_init('bronto_newsletter/queue', 'subscriber_id');
38
+ }
39
+ }
app/code/community/Bronto/Newsletter/Model/Mysql4/Queue/Collection.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Short description for file
5
+ *
6
+ * Long description (if any) ...
7
+ *
8
+ * PHP version 5
9
+ *
10
+ * The license text...
11
+ *
12
+ * @category Bronto
13
+ * @package Newsletter
14
+ * @author Jeff Lambert <jeff.lambert@atlanticbt.com>
15
+ * @copyright 2012 Atlantic BT
16
+ * @license http://www.atlanticbt.com/ Atlantic BT
17
+ * @version CVS: $Id:$
18
+ * @link <>
19
+ * @see References to other sections (if any)...
20
+ */
21
+ /**
22
+ * @author Jeff Lambert <jeff.lambert@atlanticbt.com>
23
+ * */
24
+ class Bronto_Newsletter_Model_Mysql4_Queue_Collection
25
+ extends Mage_Core_Model_Mysql4_Collection_Abstract
26
+ {
27
+
28
+ /**
29
+ * Short description for function
30
+ *
31
+ * Long description (if any) ...
32
+ *
33
+ * @return void
34
+ * @access public
35
+ */
36
+ public function _construct() {
37
+ parent::_construct();
38
+ $this->_init('bronto_newsletter/queue');
39
+ }
40
+ }
app/code/community/Bronto/Newsletter/Model/Observer.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Newsletter
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.3.5
7
+ */
8
+ class Bronto_Newsletter_Model_Observer extends Mage_Core_Model_Abstract
9
+ {
10
+ const NOTICE_IDENTIFER = 'bronto_newsletter';
11
+ const BOX_UNCHECKED = 0;
12
+ const BOX_CHECKED = 1;
13
+ const BOX_NOT_SHOWN = 2;
14
+
15
+ /**
16
+ * @param Varien_Event_Observer $observer
17
+ * @return mixed
18
+ */
19
+ public function checkBrontoRequirements(Varien_Event_Observer $observer)
20
+ {
21
+ if (!Mage::getSingleton('admin/session')->isLoggedIn()) {
22
+ return;
23
+ }
24
+
25
+ // Verify Requirements
26
+ if (!Mage::helper(self::NOTICE_IDENTIFER)->varifyRequirements(self::NOTICE_IDENTIFER, array('soap', 'openssl'))) {
27
+ return;
28
+ }
29
+ }
30
+
31
+ /**
32
+ * This event fires when customer continues past the Billing Info step
33
+ * on the onepage checkout. We set a flag here in the session to avoid
34
+ * actually doing anything until checkout is complete.
35
+ *
36
+ * @param Varien_Event_Observer $observer
37
+ */
38
+ public function setSubscriptionAtBillingStep(Varien_Event_Observer $observer)
39
+ {
40
+ if (!Mage::helper('bronto_newsletter')->isEnabled()) {
41
+ return;
42
+ }
43
+
44
+ $params = Mage::app()->getRequest()->getParams();
45
+ if (isset($params['billing']['is_subscribed'])) {
46
+ $isSubscribed = (int) $params['billing']['is_subscribed'];
47
+ Mage::getSingleton('checkout/session')->setIsSubscribed($isSubscribed);
48
+ } else {
49
+ Mage::getSingleton('checkout/session')->setIsSubscribed(self::BOX_UNCHECKED);
50
+ }
51
+ }
52
+
53
+ /**
54
+ * @param Varien_Event_Observer $observer
55
+ */
56
+ public function handleSubscriptionAtCheckout(Varien_Event_Observer $observer)
57
+ {
58
+ if (!Mage::helper('bronto_newsletter')->isEnabled()) {
59
+ return;
60
+ }
61
+
62
+ try {
63
+ // Get e-mail address we are working with
64
+ $email = $observer->getEvent()->getOrder()->getData('customer_email');
65
+ if (empty($email)) {
66
+ Mage::helper('bronto_newsletter')->writeError('No customer_email was provided.');
67
+ return false;
68
+ }
69
+
70
+ /* @var $subscriber Mage_Newsletter_Model_Subscriber */
71
+ $subscriber = Mage::getModel('newsletter/subscriber')->loadByEmail($email);
72
+ $isSubscribed = Mage::getSingleton('checkout/session')->getIsSubscribed();
73
+
74
+ switch ($isSubscribed) {
75
+ case self::BOX_UNCHECKED:
76
+ // Unsubscribe the Customer
77
+ if ($subscriber && $subscriber->isSubscribed()) {
78
+ return $subscriber->unsubscribe();
79
+ }
80
+ break;
81
+ case self::BOX_CHECKED:
82
+ // Subscribe the Customer
83
+ if (!$subscriber || !$subscriber->isSubscribed()) {
84
+ return $subscriber->subscribe($email);
85
+ }
86
+ break;
87
+ case self::BOX_NOT_SHOWN:
88
+ // Just save the Customer
89
+ $subscriber->setStatus(Mage_Newsletter_Model_Subscriber::STATUS_NOT_ACTIVE);
90
+ $subscriber->save();
91
+ break;
92
+ }
93
+
94
+ } catch (Exception $e) {
95
+ Mage::helper('bronto_newsletter')->writeError($e);
96
+ }
97
+ }
98
+
99
+ /**
100
+ * @param Varien_Event_Observer $observer
101
+ */
102
+ public function updateBrontoFromNewsletterStatus(Varien_Event_Observer $observer)
103
+ {
104
+ if (!Mage::helper('bronto_newsletter')->isEnabled()) {
105
+ return;
106
+ }
107
+
108
+ try {
109
+ // Insert contact email into queuing table. Cron will
110
+ // then issue an update to Bronto on its next run.
111
+ if ($subscriber = $observer->getEvent()->getSubscriber()) {
112
+ $email = $subscriber->getEmail();
113
+ if (!empty($email)) {
114
+ /* @var $contactHelper Bronto_Newsletter_Helper_Contact */
115
+ $contactHelper = Mage::helper('bronto_newsletter/contact');
116
+
117
+ if (!$contactHelper->getUpdateStatus()) {
118
+ $status = Bronto_Api_Contact::STATUS_TRANSACTIONAL;
119
+ } else {
120
+ $status = $contactHelper->getContactByEmail($email)->status;
121
+ }
122
+ $this->_saveToQueue($email, $contactHelper, Mage::app()->getStore()->getId());
123
+ }
124
+ }
125
+ } catch (Exception $e) {
126
+ Mage::helper('bronto_newsletter')->writeError($e);
127
+ }
128
+ }
129
+
130
+ private function _saveToQueue($email, $helper, $storeId) {
131
+ /* var $contactQueue Bronto_Newsletter_Model_Queue */
132
+ $contactQueue = Mage::getModel('bronto_newsletter/queue');
133
+
134
+ if(!$helper->getUpdateStatus()) {
135
+ $status = Bronto_Api_Contact::STATUS_TRANSACTIONAL;
136
+ } else {
137
+ $status = Bronto_Api_Contact::STATUS_ONBOARDING;
138
+ }
139
+
140
+ $contactQueue->setSubscriberEmail( $email )
141
+ ->setStatus( $status )
142
+ ->setMessagePreference( 'html' )
143
+ ->setSource( 'api' )
144
+ ->setStore( $storeId )
145
+ ->save();
146
+ }
147
+
148
+ static public function cronImport() {
149
+ /* var $contactHelper Bronto_Newsletter_Helper_Contact */
150
+ $contactHelper = Mage::helper('bronto_newsletter/contact');
151
+ /* var $subscribers Bronto_Newsletter_Model_Mysql4_Queue_Collection */
152
+ $subscribers = Mage::getModel('bronto_newsletter/queue')
153
+ ->getCollection()
154
+ ->addFilter('imported', 0);
155
+
156
+ foreach($subscribers as $subscriber) {
157
+ $email = $subscriber->getSubscriberEmail();
158
+ $contact = $contactHelper->getContactByEmail($email, null, $subscriber->getStore());
159
+ $contact->status = $subscriber->getStatus();
160
+
161
+ try {
162
+ $contactHelper->saveContact($contact);
163
+ $subscriber->setImported(1)->save();
164
+ } catch(Exception $e) {
165
+ Mage::helper('bronto_newsletter')->writeError($e);
166
+ }
167
+ }
168
+ }
169
+ }
app/code/community/Bronto/Newsletter/Model/Queue.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Short description for file
5
+ *
6
+ * Long description (if any) ...
7
+ *
8
+ * PHP version 5
9
+ *
10
+ * The license text...
11
+ *
12
+ * @category Bronto
13
+ * @package Newsletter
14
+ * @author Jeff Lambert <jeff.lambert@atlanticbt.com>
15
+ * @copyright 2012 Atlantic BT
16
+ * @license http://www.atlanticbt.com/ Atlantic BT
17
+ * @version CVS: $Id:$
18
+ * @link <>
19
+ * @see References to other sections (if any)...
20
+ */
21
+ /**
22
+ * @author Jeff Lambert <jeff.lambert@atlanticbt.com>
23
+ * */
24
+ class Bronto_Newsletter_Model_Queue extends Mage_Core_Model_Abstract
25
+ {
26
+
27
+ /**
28
+ * Short description for function
29
+ *
30
+ * Long description (if any) ...
31
+ *
32
+ * @return void
33
+ * @access public
34
+ */
35
+ public function _construct()
36
+ {
37
+ parent::_construct();
38
+ $this->_init('bronto_newsletter/queue');
39
+ }
40
+
41
+ }
app/code/community/Bronto/Newsletter/Test/Config/Config.php ADDED
@@ -0,0 +1,226 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_Newsletter_Test_Config_Config
3
+ extends EcomDev_PHPUnit_Test_Case_Config
4
+ {
5
+ // {{{ blocksProvider()
6
+
7
+ public function blocksProvider()
8
+ {
9
+ return array(
10
+ array('bronto_newsletter/adminhtml_system_config_about', 'Bronto_Newsletter_Block_Adminhtml_System_Config_About'),
11
+ array('bronto_newsletter/checkout_onepage_newsletter', 'Bronto_Newsletter_Block_Checkout_Onepage_Newsletter'),
12
+ );
13
+ }
14
+
15
+ // }}}
16
+ // {{{ resourceModelProvider()
17
+
18
+ public function resourceModelProvider()
19
+ {
20
+ return array(
21
+ array('bronto_newsletter_mysql4/queue', 'Bronto_Newsletter_Model_Mysql4_Queue'),
22
+ array('bronto_newsletter_mysql4/queue_collection', 'Bronto_Newsletter_Model_Mysql4_Queue_Collection'),
23
+ );
24
+ }
25
+
26
+ // }}}
27
+ // {{{ modelsProvider()
28
+
29
+ public function modelsProvider()
30
+ {
31
+ return array(
32
+ array('bronto_newsletter/queue', 'Bronto_Newsletter_Model_Queue'),
33
+ );
34
+ }
35
+
36
+ // }}}
37
+ // {{{ helpersProvider()
38
+
39
+ public function helpersProvider()
40
+ {
41
+ return array(
42
+ array('bronto_newsletter/data', 'Bronto_Newsletter_Helper_Data'),
43
+ array('bronto_newsletter/contact', 'Bronto_Newsletter_Helper_Contact'),
44
+ );
45
+ }
46
+
47
+ // }}}
48
+ // {{{ observersProvider()
49
+
50
+ public function observersProvider()
51
+ {
52
+ return array(
53
+ array('adminhtml', 'controller_action_predispatch', 'bronto_newsletter/observer', 'checkBrontoRequirements'),
54
+ );
55
+ }
56
+
57
+ // }}}
58
+ // {{{ definedLayoutFilesProvider()
59
+
60
+ public function definedLayoutFilesProvider()
61
+ {
62
+ return array(
63
+ array('frontend', 'bronto/newsletter.xml'),
64
+ );
65
+ }
66
+
67
+ // }}}
68
+ // {{{ themeLayoutFilesExistProvider()
69
+
70
+ public function themeLayoutFilesExistProvider()
71
+ {
72
+ return array(
73
+ array('frontend', 'bronto/newsletter.xml', 'default', 'default'),
74
+ );
75
+ }
76
+
77
+ // }}}
78
+
79
+ /**
80
+ * @test
81
+ * @group amd
82
+ * @group config
83
+ */
84
+ public function assertNewsletterModuleVersionGreaterThanOrEquals()
85
+ {
86
+ $this->assertModuleVersionGreaterThanOrEquals('1.4.0');
87
+ }
88
+
89
+ // {{{ assertNewsletterModuleInLocalCodePool()
90
+
91
+ /**
92
+ * @test
93
+ * @group amd
94
+ * @group config
95
+ */
96
+ public function assertNewsletterModuleInCommunityCodePool()
97
+ {
98
+ $this->assertModuleCodePool('community');
99
+ }
100
+
101
+ // }}}
102
+ // {{{ assertNewsletterModelAliases()
103
+
104
+ /**
105
+ * @test
106
+ * @group amd
107
+ * @group config
108
+ * @dataProvider modelsProvider
109
+ */
110
+ public function assertNewsletterModelAliases(
111
+ $classAlias,
112
+ $expectedClassName
113
+ ) {
114
+ $this->assertModelAlias($classAlias, $expectedClassName);
115
+ }
116
+
117
+ // }}}
118
+ // {{{ assertNewsletterResourceModelAliases()
119
+
120
+ /**
121
+ * @test
122
+ * @group amd
123
+ * @group config
124
+ * @dataProvider resourceModelProvider
125
+ */
126
+ public function assertNewsletterResourceModelAliases(
127
+ $classAlias,
128
+ $expectedClassName
129
+ ) {
130
+ $this->assertResourceModelAlias($classAlias, $expectedClassName);
131
+ }
132
+
133
+ // }}}
134
+ // {{{ assertNewsletterBlockAliases()
135
+
136
+ /**
137
+ * @test
138
+ * @group amd
139
+ * @group config
140
+ * @dataProvider blocksProvider
141
+ */
142
+ public function assertNewsletterBlockAliases(
143
+ $classAlias,
144
+ $expectedClassName
145
+ ) {
146
+ $this->assertBlockAlias($classAlias, $expectedClassName);
147
+ }
148
+
149
+ // }}}
150
+ // {{{ assertNewsletterHelperAliases()
151
+
152
+ /**
153
+ * @test
154
+ * @group amd
155
+ * @group config
156
+ * @dataProvider helpersProvider
157
+ */
158
+ public function assertNewsletterHelperAliases(
159
+ $classAlias,
160
+ $expectedClassName
161
+ ) {
162
+ $this->assertHelperAlias($classAlias, $expectedClassName);
163
+ }
164
+
165
+ // }}}
166
+ // {{{ assertNewsletterEventObserversDefined()
167
+
168
+ /**
169
+ * test
170
+ * @group config
171
+ * @group amd
172
+ * @dataProvider observersProvider
173
+ */
174
+ public function assertNewsletterEventObserversDefined(
175
+ $area,
176
+ $eventName,
177
+ $observerClassAlias,
178
+ $observerMethod
179
+ ) {
180
+ $this->assertEventObserverDefined(
181
+ $area,
182
+ $eventName,
183
+ $observerClassAlias,
184
+ $observerMethod
185
+ );
186
+ }
187
+
188
+ // }}}
189
+ // {{{ assertNewsletterLayoutFileDefined()
190
+
191
+ /**
192
+ * test
193
+ * @group config
194
+ * @group amd
195
+ * @dataProvider definedLayoutFilesProvider
196
+ */
197
+ public function assertNewsletterLayoutFileDefined($area, $expectedFileName)
198
+ {
199
+ $this->assertLayoutFileDefined($area, $expectedFileName);
200
+ }
201
+
202
+ // }}}
203
+ // {{{ assertNewsletterLayoutFileExistsForDefaultTheme()
204
+
205
+ /**
206
+ * test
207
+ * @group config
208
+ * @group amd
209
+ * @dataProvider themeLayoutFilesExistProvider
210
+ */
211
+ public function assertNewsletterLayoutFileExistsForDefaultTheme(
212
+ $area,
213
+ $filename,
214
+ $theme,
215
+ $designPackage
216
+ ) {
217
+ $this->assertLayoutFileExistsInTheme(
218
+ $area,
219
+ $filename,
220
+ $theme,
221
+ $designPackage
222
+ );
223
+ }
224
+
225
+ // }}}
226
+ }
app/code/community/Bronto/Newsletter/controllers/Adminhtml/NewsletterController.php ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Bronto
5
+ * @package Bronto_Customer
6
+ */
7
+ class Bronto_Newsletter_Adminhtml_NewsletterController extends Mage_Adminhtml_Controller_Action
8
+ {
9
+ /**
10
+ * Run immediately
11
+ */
12
+ public function runAction()
13
+ {
14
+ try {
15
+ $result = array('total' => 0, 'success' => 0, 'error' => 0);
16
+ $model = Mage::getModel('bronto_newsletter/observer');
17
+
18
+ if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
19
+ $store = Mage::app()->getStore($storeCode);
20
+ $storeIds[] = $store->getId();
21
+ } else if ($websiteCode = Mage::app()->getRequest()->getParam('website')){
22
+ $website = Mage::app()->getWebsite($websiteCode);
23
+ $storeIds = $website->getStoreIds();
24
+ } else if ($groupCode = Mage::app()->getRequest()->getParam('group')){
25
+ $website = Mage::app()->getGroup($groupCode)->getWebsite();
26
+ $storeIds = $website->getStoreIds();
27
+ } else {
28
+ $storeIds = false;
29
+ }
30
+
31
+ if ($storeIds) {
32
+ foreach ($storeIds as $storeId) {
33
+ // $storeResult = $model->processCustomersForStore($storeId);
34
+ $result['total'] += $storeResult['total'];
35
+ $result['success'] += $storeResult['success'];
36
+ $result['error'] += $storeResult['error'];
37
+ }
38
+ } else {
39
+ // $result = $model->processCustomers();
40
+ }
41
+
42
+ if (is_array($result)) {
43
+ $this->_getSession()->addSuccess(sprintf("Processed %d Subscribers (%d Error / %d Success)", $result['total'], $result['error'], $result['success']));
44
+ } else {
45
+ $this->_getSession()->addError('Scheduled Import failed: ' . $result);
46
+ }
47
+
48
+ } catch (Exception $e) {
49
+ $this->_getSession()->addError($e->getMessage());
50
+ Mage::helper('bronto_newsletter')->writeError($e);
51
+ }
52
+
53
+ $this->_redirect('*/system_config/edit', array('section' => 'bronto_newsletter'));
54
+ }
55
+
56
+ /**
57
+ * Reset all Customers
58
+ */
59
+ public function resetAction()
60
+ {
61
+ $storeIds = array();
62
+ $writeConnection = Mage::getSingleton('core/resource')->getConnection('core_write');
63
+ $tablePrefix = Mage::getConfig()->getTablePrefix();
64
+
65
+ if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
66
+ $store = Mage::app()->getStore($storeCode);
67
+ $storeIds[] = $store->getId();
68
+ } else if ($websiteCode = Mage::app()->getRequest()->getParam('website')){
69
+ $website = Mage::app()->getWebsite($websiteCode);
70
+ $storeIds = $website->getStoreIds();
71
+ } else if ($groupCode = Mage::app()->getRequest()->getParam('group')){
72
+ $website = Mage::app()->getGroup($groupCode)->getWebsite();
73
+ $storeIds = $website->getStoreIds();
74
+ } else {
75
+ $storeIds[] = null;
76
+ }
77
+
78
+ foreach ($storeIds as $storeId) {
79
+ //
80
+ }
81
+
82
+ $this->_redirect('*/system_config/edit', array('section' => 'bronto_newsletter'));
83
+ }
84
+
85
+ /**
86
+ * @return bool
87
+ */
88
+ protected function _isAllowed()
89
+ {
90
+ return $this->_isSectionAllowed('bronto_newsletter');
91
+ }
92
+
93
+ /**
94
+ * Check if specified section allowed in ACL
95
+ *
96
+ * Will forward to deniedAction(), if not allowed.
97
+ *
98
+ * @param string $section
99
+ * @return bool
100
+ */
101
+ protected function _isSectionAllowed($section)
102
+ {
103
+ try {
104
+ $session = Mage::getSingleton('admin/session');
105
+ $resourceLookup = "admin/system/config/{$section}";
106
+ if ($session->getData('acl') instanceof Mage_Admin_Model_Acl) {
107
+ $resourceId = $session->getData('acl')->get($resourceLookup)->getResourceId();
108
+ if (!$session->isAllowed($resourceId)) {
109
+ throw new Exception('');
110
+ }
111
+ return true;
112
+ }
113
+ } catch (Zend_Acl_Exception $e) {
114
+ $this->norouteAction();
115
+ $this->setFlag('', self::FLAG_NO_DISPATCH, true);
116
+ return false;
117
+ } catch (Exception $e) {
118
+ $this->deniedAction();
119
+ $this->setFlag('', self::FLAG_NO_DISPATCH, true);
120
+ return false;
121
+ }
122
+ }
123
+ }
app/code/community/Bronto/Newsletter/etc/adminhtml.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <admin>
6
+ <children>
7
+ <system>
8
+ <children>
9
+ <config>
10
+ <children>
11
+ <bronto_newsletter module="bronto_newsletter">
12
+ <title>Bronto Newsletter Section</title>
13
+ </bronto_newsletter>
14
+ </children>
15
+ </config>
16
+ </children>
17
+ </system>
18
+ </children>
19
+ </admin>
20
+ </resources>
21
+ </acl>
22
+ </config>
app/code/community/Bronto/Newsletter/etc/config.xml ADDED
@@ -0,0 +1,178 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Bronto_Newsletter>
5
+ <version>1.4.1</version>
6
+ </Bronto_Newsletter>
7
+ </modules>
8
+ <global>
9
+ <helpers>
10
+ <bronto_newsletter>
11
+ <class>Bronto_Newsletter_Helper</class>
12
+ </bronto_newsletter>
13
+ </helpers>
14
+ <blocks>
15
+ <bronto_newsletter>
16
+ <class>Bronto_Newsletter_Block</class>
17
+ </bronto_newsletter>
18
+ </blocks>
19
+ <models>
20
+ <bronto_newsletter>
21
+ <class>Bronto_Newsletter_Model</class>
22
+ <resourceModel>bronto_newsletter_mysql4</resourceModel>
23
+ </bronto_newsletter>
24
+ <bronto_newsletter_mysql4>
25
+ <class>Bronto_Newsletter_Model_Mysql4</class>
26
+ <entities>
27
+ <queue><table>bronto_newsletter_queue</table></queue>
28
+ </entities>
29
+ </bronto_newsletter_mysql4>
30
+ </models>
31
+ <resources>
32
+ <bronto_newsletter_setup>
33
+ <setup>
34
+ <module>Bronto_Newsletter</module>
35
+ </setup>
36
+ <connection>
37
+ <use>core_setup</use>
38
+ </connection>
39
+ </bronto_newsletter_setup>
40
+ <bronto_newsletter_write>
41
+ <connection>
42
+ <use>core_write</use>
43
+ </connection>
44
+ </bronto_newsletter_write>
45
+ <bronto_newsletter_read>
46
+ <connection>
47
+ <use>core_read</use>
48
+ </connection>
49
+ </bronto_newsletter_read>
50
+ </resources>
51
+ <events>
52
+ <newsletter_subscriber_save_after>
53
+ <observers>
54
+ <bronto_newsletter_newsletter_subscriber_save_after>
55
+ <class>bronto_newsletter/observer</class>
56
+ <method>updateBrontoFromNewsletterStatus</method>
57
+ </bronto_newsletter_newsletter_subscriber_save_after>
58
+ </observers>
59
+ </newsletter_subscriber_save_after>
60
+ </events>
61
+ </global>
62
+ <frontend>
63
+ <layout>
64
+ <updates>
65
+ <bronto_newsletter>
66
+ <file>bronto/newsletter.xml</file>
67
+ </bronto_newsletter>
68
+ </updates>
69
+ </layout>
70
+ <events>
71
+ <checkout_type_onepage_save_order_after>
72
+ <observers>
73
+ <bronto_newsletter_checkout_type_onepage_save_order_after>
74
+ <class>bronto_newsletter/observer</class>
75
+ <method>handleSubscriptionAtCheckout</method>
76
+ </bronto_newsletter_checkout_type_onepage_save_order_after>
77
+ </observers>
78
+ </checkout_type_onepage_save_order_after>
79
+ <controller_action_postdispatch_checkout_onepage_saveBilling>
80
+ <observers>
81
+ <bronto_newsletter_controller_action_postdispatch_checkout_onepage_saveBilling>
82
+ <class>bronto_newsletter/observer</class>
83
+ <method>setSubscriptionAtBillingStep</method>
84
+ </bronto_newsletter_controller_action_postdispatch_checkout_onepage_saveBilling>
85
+ </observers>
86
+ </controller_action_postdispatch_checkout_onepage_saveBilling>
87
+ </events>
88
+ </frontend>
89
+ <default>
90
+ <bronto_newsletter>
91
+ <settings>
92
+ <enabled>1</enabled>
93
+ <frequency>D</frequency>
94
+ <interval>15</interval>
95
+ <minutes>0</minutes>
96
+ <limit>250</limit>
97
+ </settings>
98
+ <checkout>
99
+ <show_to_guests>1</show_to_guests>
100
+ <show_to_registrars>1</show_to_registrars>
101
+ <default_checked>0</default_checked>
102
+ <show_if_subscribed>0</show_if_subscribed>
103
+ <label_text>Sign up for our newsletter</label_text>
104
+ <use_custom_template>0</use_custom_template>
105
+ <billing_template>checkout/onepage/billing.phtml</billing_template>
106
+ </checkout>
107
+ <contacts>
108
+ <update_status>1</update_status>
109
+ </contacts>
110
+ </bronto_newsletter>
111
+ </default>
112
+ <crontab>
113
+ <jobs>
114
+ <bronto_newsletter_import>
115
+ <schedule><cron_expr>*/15 * * * *</cron_expr></schedule>
116
+ <run><model>bronto_newsletter/observer::processSubscribers</model></run>
117
+ </bronto_newsletter_import>
118
+ </jobs>
119
+ </crontab>
120
+ <adminhtml>
121
+ <events>
122
+ <controller_action_predispatch>
123
+ <observers>
124
+ <bronto_newsletter_controller_action_predispatch>
125
+ <class>bronto_newsletter/observer</class>
126
+ <method>checkBrontoRequirements</method>
127
+ </bronto_newsletter_controller_action_predispatch>
128
+ </observers>
129
+ </controller_action_predispatch>
130
+ </events>
131
+ <acl>
132
+ <resources>
133
+ <admin>
134
+ <children>
135
+ <system>
136
+ <children>
137
+ <config>
138
+ <children>
139
+ <bronto_newsletter module="bronto_newsletter">
140
+ <title>Bronto Newsletter Section</title>
141
+ </bronto_newsletter>
142
+ </children>
143
+ </config>
144
+ </children>
145
+ </system>
146
+ </children>
147
+ </admin>
148
+ </resources>
149
+ </acl>
150
+ </adminhtml>
151
+ <admin>
152
+ <fieldsets>
153
+ <customer_account>
154
+ <bronto_contact_id><create>1</create></bronto_contact_id>
155
+ </customer_account>
156
+ </fieldsets>
157
+ </admin>
158
+ <crontab>
159
+ <jobs>
160
+ <bronto_newsletter_import>
161
+ <schedule>
162
+ <cron_expr>*/5 * * * *</cron_expr>
163
+ </schedule>
164
+ <run>
165
+ <model>bronto_newsletter/observer::cronImport</model>
166
+ </run>
167
+ </bronto_newsletter_import>
168
+ </jobs>
169
+ </crontab>
170
+
171
+ <phpunit>
172
+ <suite>
173
+ <modules>
174
+ <Bronto_Newsletter />
175
+ </modules>
176
+ </suite>
177
+ </phpunit>
178
+ </config>
app/code/community/Bronto/Newsletter/etc/system.xml ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <bronto_newsletter module="bronto_newsletter">
5
+ <label>Newsletter Opt-In</label>
6
+ <tab>bronto</tab>
7
+ <frontend_type>text</frontend_type>
8
+ <sort_order>400</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
+ <about>
14
+ <frontend_type>text</frontend_type>
15
+ <frontend_model>bronto_newsletter/adminhtml_system_config_about</frontend_model>
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
+ </about>
21
+ <settings>
22
+ <label>Settings</label>
23
+ <frontend_type>text</frontend_type>
24
+ <sort_order>1</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ <fields>
29
+ <enabled>
30
+ <label>Enable Module</label>
31
+ <frontend_type>select</frontend_type>
32
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
33
+ <source_model>adminhtml/system_config_source_yesno</source_model>
34
+ <sort_order>0</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
+ </enabled>
39
+ <frequency>
40
+ <label>Frequency</label>
41
+ <depends><enabled>1</enabled></depends>
42
+ <frontend_type>select</frontend_type>
43
+ <source_model>bronto_common/system_config_source_cron_frequency</source_model>
44
+ <backend_model>bronto_order/system_config_backend_cron</backend_model>
45
+ <sort_order>20</sort_order>
46
+ <show_in_default>1</show_in_default>
47
+ <show_in_website>0</show_in_website>
48
+ <show_in_store>0</show_in_store>
49
+ </frequency>
50
+ <interval>
51
+ <label>Interval</label>
52
+ <depends><frequency>I</frequency></depends>
53
+ <frontend_type>select</frontend_type>
54
+ <source_model>bronto_common/system_config_source_cron_minutes</source_model>
55
+ <sort_order>30</sort_order>
56
+ <show_in_default>1</show_in_default>
57
+ <show_in_website>0</show_in_website>
58
+ <show_in_store>0</show_in_store>
59
+ <comment>Set this value larger than your cron.php launch period.</comment>
60
+ </interval>
61
+ <minutes>
62
+ <label>Minute of the Hour</label>
63
+ <depends><frequency>H</frequency></depends>
64
+ <frontend_type>text</frontend_type>
65
+ <sort_order>40</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
+ <comment>Valid range: 0-59 (default 0).</comment>
70
+ </minutes>
71
+ <time>
72
+ <label>Start Time</label>
73
+ <depends><enabled>1</enabled></depends>
74
+ <frontend_type>time</frontend_type>
75
+ <sort_order>50</sort_order>
76
+ <show_in_default>1</show_in_default>
77
+ <show_in_website>0</show_in_website>
78
+ <show_in_store>0</show_in_store>
79
+ </time>
80
+ <limit>
81
+ <label>Limit</label>
82
+ <depends><enabled>1</enabled></depends>
83
+ <frontend_type>select</frontend_type>
84
+ <source_model>bronto_order/system_config_source_limit</source_model>
85
+ <sort_order>60</sort_order>
86
+ <show_in_default>1</show_in_default>
87
+ <show_in_website>0</show_in_website>
88
+ <show_in_store>0</show_in_store>
89
+ <comment>Total Orders to process every cron run.</comment>
90
+ </limit>
91
+ </fields>
92
+ </settings>
93
+ <checkout>
94
+ <label>Checkout</label>
95
+ <frontend_type>text</frontend_type>
96
+ <sort_order>2</sort_order>
97
+ <show_in_default>1</show_in_default>
98
+ <show_in_website>1</show_in_website>
99
+ <show_in_store>1</show_in_store>
100
+ <fields>
101
+ <show_to_guests>
102
+ <label>Show on Guest Checkout</label>
103
+ <frontend_type>select</frontend_type>
104
+ <source_model>adminhtml/system_config_source_yesno</source_model>
105
+ <sort_order>5</sort_order>
106
+ <show_in_default>1</show_in_default>
107
+ <show_in_website>1</show_in_website>
108
+ <show_in_store>1</show_in_store>
109
+ </show_to_guests>
110
+ <show_to_registrars>
111
+ <label>Show on Register Checkout</label>
112
+ <frontend_type>select</frontend_type>
113
+ <source_model>adminhtml/system_config_source_yesno</source_model>
114
+ <sort_order>6</sort_order>
115
+ <show_in_default>1</show_in_default>
116
+ <show_in_website>1</show_in_website>
117
+ <show_in_store>1</show_in_store>
118
+ </show_to_registrars>
119
+ <show_if_subscribed>
120
+ <label>Show if Already Subscribed</label>
121
+ <frontend_type>select</frontend_type>
122
+ <source_model>adminhtml/system_config_source_yesno</source_model>
123
+ <sort_order>7</sort_order>
124
+ <show_in_default>1</show_in_default>
125
+ <show_in_website>1</show_in_website>
126
+ <show_in_store>1</show_in_store>
127
+ </show_if_subscribed>
128
+ <default_checked>
129
+ <label>Checked by Default</label>
130
+ <frontend_type>select</frontend_type>
131
+ <source_model>adminhtml/system_config_source_yesno</source_model>
132
+ <sort_order>10</sort_order>
133
+ <show_in_default>1</show_in_default>
134
+ <show_in_website>1</show_in_website>
135
+ <show_in_store>1</show_in_store>
136
+ </default_checked>
137
+ <label_text>
138
+ <label>Checkbox Label Text</label>
139
+ <frontend_type>text</frontend_type>
140
+ <validate>required-entry validate-length minimum-length-1</validate>
141
+ <sort_order>15</sort_order>
142
+ <show_in_default>1</show_in_default>
143
+ <show_in_website>1</show_in_website>
144
+ <show_in_store>1</show_in_store>
145
+ </label_text>
146
+ <use_custom_template>
147
+ <label>Use Custom Billing Template?</label>
148
+ <frontend_type>select</frontend_type>
149
+ <source_model>adminhtml/system_config_source_yesno</source_model>
150
+ <sort_order>20</sort_order>
151
+ <show_in_default>1</show_in_default>
152
+ <show_in_website>1</show_in_website>
153
+ <show_in_store>1</show_in_store>
154
+ <comment><![CDATA[If 'No', uses: <code>bronto/newsletter/billing.phtml</code>]]></comment>
155
+ </use_custom_template>
156
+ <billing_template>
157
+ <label>Billing Template Path</label>
158
+ <depends><use_custom_template>1</use_custom_template></depends>
159
+ <frontend_type>text</frontend_type>
160
+ <sort_order>21</sort_order>
161
+ <show_in_default>1</show_in_default>
162
+ <show_in_website>1</show_in_website>
163
+ <show_in_store>1</show_in_store>
164
+ <comment><![CDATA[<strong>Magento Default:</strong> <code>checkout/onepage/billing.phtml</code>]]></comment>
165
+ </billing_template>
166
+ </fields>
167
+ </checkout>
168
+ <contacts>
169
+ <label>Contacts</label>
170
+ <frontend_type>text</frontend_type>
171
+ <sort_order>3</sort_order>
172
+ <show_in_default>1</show_in_default>
173
+ <show_in_website>1</show_in_website>
174
+ <show_in_store>1</show_in_store>
175
+ <comment><![CDATA[<strong style="color: red">Warning!</strong> If <strong>Yes</strong>, the Magento subscriber status will overwrite the contact status in Bronto. See <a href="http://a.bron.to/magento" target="_blank">documentation</a> for more details.]]></comment>
176
+ <fields>
177
+ <update_status>
178
+ <label>Update Status</label>
179
+ <frontend_type>select</frontend_type>
180
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
181
+ <source_model>adminhtml/system_config_source_yesno</source_model>
182
+ <sort_order>10</sort_order>
183
+ <show_in_default>1</show_in_default>
184
+ <show_in_website>1</show_in_website>
185
+ <show_in_store>1</show_in_store>
186
+ <comment>If Yes, contacts receive Magento's Subscriber status.</comment>
187
+ </update_status>
188
+ <lists>
189
+ <label>Add to List(s)</label>
190
+ <frontend_type>multiselect</frontend_type>
191
+ <frontend_model>bronto_common/adminhtml_system_config_form_field_list</frontend_model>
192
+ <source_model>bronto_common/system_config_source_list</source_model>
193
+ <sort_order>20</sort_order>
194
+ <show_in_default>0</show_in_default>
195
+ <show_in_website>1</show_in_website>
196
+ <show_in_store>1</show_in_store>
197
+ <can_be_empty>1</can_be_empty>
198
+ </lists>
199
+ </fields>
200
+ </contacts>
201
+ <cron_list>
202
+ <frontend_type>text</frontend_type>
203
+ <frontend_model>bronto_newsletter/adminhtml_system_config_cron</frontend_model>
204
+ <sort_order>4</sort_order>
205
+ <show_in_default>1</show_in_default>
206
+ <show_in_website>0</show_in_website>
207
+ <show_in_store>1</show_in_store>
208
+ </cron_list>
209
+ </groups>
210
+ </bronto_newsletter>
211
+ </sections>
212
+ </config>
app/code/community/Bronto/Newsletter/sql/bronto_newsletter_setup/mysql4-install-1.0.0.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Sales_Model_Mysql4_Setup */
5
+
6
+ $installer->startSetup();
7
+ $connection = $installer->getConnection();
8
+
9
+ //
10
+ // Subscriber Attributes
11
+ $connection->addColumn(
12
+ $installer->getTable('newsletter/subscriber'), 'bronto_imported', 'datetime NULL default NULL'
13
+ );
14
+
15
+ try {
16
+ $installer->getConnection()->addKey(
17
+ $installer->getTable('newsletter/subscriber'), 'IDX_BRONTO_IMPORTED', 'bronto_imported'
18
+ );
19
+ } catch (Exception $e) {
20
+ // Already exists...
21
+ }
22
+
23
+ $installer->endSetup();
24
+
25
+ // Mark installation date
26
+ $config = Mage::getConfig();
27
+ $config->saveConfig(Bronto_Newsletter_Helper_Data::XML_PATH_INSTALL_DATE, time());
app/code/community/Bronto/Newsletter/sql/bronto_newsletter_setup/mysql4-install-1.4.0.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ try {
9
+ $installer->run("
10
+
11
+ CREATE TABLE `{$this->getTable('bronto_newsletter_queue')}` (
12
+ `status` varchar(32) CHARACTER SET utf8 NOT NULL,
13
+ `messagePreference` varchar(16) CHARACTER SET utf8 NOT NULL,
14
+ `source` varchar(16) CHARACTER SET utf8 NOT NULL,
15
+ `imported` tinyint(4) NOT NULL DEFAULT '0',
16
+ `subscriber_id` int(11) NOT NULL AUTO_INCREMENT,
17
+ `subscriber_email` varchar(255) CHARACTER SET utf8 NOT NULL,
18
+ `store` tinyint(4) NOT NULL,
19
+ PRIMARY KEY (`subscriber_id`)
20
+ ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
21
+ ");
22
+
23
+ } catch (Exception $e) {
24
+ //
25
+ }
26
+
27
+ $installer->endSetup();
app/code/community/Bronto/Newsletter/sql/bronto_newsletter_setup/mysql4-upgrade-1.4.0-1.4.1.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * fall back to create table if existing modules already exists to support upgrade
4
+ */
5
+
6
+ $installer = $this;
7
+ /* @var $installer Mage_Core_Model_Resource_Setup */
8
+
9
+ $installer->startSetup();
10
+
11
+ try {
12
+ $installer->run("
13
+ CREATE TABLE IF NOT EXISTS `{$this->getTable('bronto_newsletter_queue')}` (
14
+ `status` varchar(32) CHARACTER SET utf8 NOT NULL,
15
+ `messagePreference` varchar(16) CHARACTER SET utf8 NOT NULL,
16
+ `source` varchar(16) CHARACTER SET utf8 NOT NULL,
17
+ `imported` tinyint(4) NOT NULL DEFAULT '0',
18
+ `subscriber_id` int(11) NOT NULL AUTO_INCREMENT,
19
+ `subscriber_email` varchar(255) CHARACTER SET utf8 NOT NULL,
20
+ `store` tinyint(4) NOT NULL,
21
+ PRIMARY KEY (`subscriber_id`)
22
+ ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
23
+ ");
24
+
25
+ } catch (Exception $e) {
26
+ //
27
+ }
28
+
29
+ $installer->endSetup();
app/code/community/Bronto/Order/Block/Adminhtml/Sales/Order/View/Tab/Info.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Order
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Order_Block_Adminhtml_Sales_Order_View_Tab_Info extends Mage_Adminhtml_Block_Sales_Order_View_Tab_Info
9
+ {
10
+ /**
11
+ * Prepare html output
12
+ *
13
+ * @return string
14
+ */
15
+ protected function _toHtml()
16
+ {
17
+ $order = $this->getOrder();
18
+ $tid = $order->getBrontoTid();
19
+ $imported = $order->getBrontoImported();
20
+
21
+ $deliveryHtml = empty($tid) ? $this->_getNoHtml() : $this->_getYesHtml();
22
+ $importedHtml = empty($imported) ? $this->_getNoHtml() : $this->_getYesHtml();
23
+
24
+ $html = parent::_toHtml();
25
+ $html .= <<<SCRIPT
26
+ <script>
27
+ var orderTable, orderTableRow, orderTableCell;
28
+
29
+ // Add Delivery Row
30
+ // orderTableRow = orderTable.insertRow(orderTable.rows.length);
31
+ // orderTableCell = orderTableRow.insertCell(0);
32
+ // orderTableCell.innerHTML = "<label>Associated with Bronto Delivery?</label>";
33
+ // orderTableCell = orderTableRow.insertCell(1);
34
+ // orderTableCell.innerHTML = "$deliveryHtml";
35
+
36
+ // Add Imported Row
37
+ // orderTableRow = orderTable.insertRow(orderTable.rows.length);
38
+ // orderTableCell = orderTableRow.insertCell(0);
39
+ // orderTableCell.innerHTML = "<label>Imported into Bronto?</label>";
40
+ // orderTableCell = orderTableRow.insertCell(1);
41
+ // orderTableCell.innerHTML = "$importedHtml";
42
+ </script>
43
+ SCRIPT;
44
+
45
+ return $html;
46
+ }
47
+
48
+ /**
49
+ * @return string
50
+ */
51
+ private function _getYesHtml()
52
+ {
53
+ return 'YES';
54
+ }
55
+
56
+ /**
57
+ * @return string
58
+ */
59
+ private function _getNoHtml()
60
+ {
61
+ return 'NO';
62
+ }
63
+ }
app/code/community/Bronto/Order/Block/Adminhtml/System/Config/About.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Order
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Order_Block_Adminhtml_System_Config_About extends Bronto_Common_Block_Adminhtml_System_Config_About
9
+ {
10
+
11
+ /**
12
+ * Description for protected
13
+ * @var string
14
+ * @access protected
15
+ */
16
+ protected $_module = 'bronto_order';
17
+
18
+ /**
19
+ * Description for protected
20
+ * @var string
21
+ * @access protected
22
+ */
23
+ protected $_name = 'Bronto Order Import for Magento';
24
+ }
app/code/community/Bronto/Order/Block/Adminhtml/System/Config/Cron.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Order
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 2.0.0
7
+ */
8
+ class Bronto_Order_Block_Adminhtml_System_Config_Cron extends Bronto_Common_Block_Adminhtml_System_Config_Cron
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_jobCode = 'bronto_order_import';
14
+
15
+ /**
16
+ * @var boolean
17
+ */
18
+ protected $_hasProgressBar = true;
19
+
20
+ /**
21
+ * @return Bronto_Order_Block_Adminhtml_System_Config_Cron
22
+ */
23
+ protected function _prepareLayout()
24
+ {
25
+ $this->addButton($this->getLayout()->createBlock('bronto_order/adminhtml_widget_button_reset'));
26
+ $this->addButton($this->getLayout()->createBlock('bronto_order/adminhtml_widget_button_run'));
27
+
28
+ return parent::_prepareLayout();
29
+ }
30
+
31
+ /**
32
+ * @return int
33
+ */
34
+ protected function getProgressBarTotal()
35
+ {
36
+ return $this->getOrderResourceCollection()
37
+ ->getSize()
38
+ ;
39
+ }
40
+
41
+ /**
42
+ * @return int
43
+ */
44
+ protected function getProgressBarPending()
45
+ {
46
+ return $this->getOrderResourceCollection()
47
+ ->addBrontoNotImportedFilter()
48
+ ->getSize()
49
+ ;
50
+ }
51
+
52
+ /**
53
+ * @return Bronto_Order_Model_Resource_Order_Collection
54
+ */
55
+ protected function getOrderResourceCollection()
56
+ {
57
+ $collection = Mage::getModel('bronto_order/resource_order_collection');
58
+
59
+ if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
60
+ $store = Mage::app()->getStore($storeCode);
61
+ $collection->addStoreFilter($store->getId());
62
+ } else if ($websiteCode = Mage::app()->getRequest()->getParam('website')){
63
+ $website = Mage::app()->getWebsite($websiteCode);
64
+ $collection->addStoreFilter($website->getStoreids());
65
+ } else if ($groupCode = Mage::app()->getRequest()->getParam('group')){
66
+ $website = Mage::app()->getGroup($groupCode)->getWebsite();
67
+ $collection->addStoreFilter($website->getStoreids());
68
+ }
69
+
70
+ return $collection;
71
+ }
72
+ }
app/code/community/Bronto/Order/Block/Adminhtml/Widget/Button/Reset.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Order
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Order_Block_Adminhtml_Widget_Button_Reset extends Mage_Adminhtml_Block_Widget_Button
9
+ {
10
+ /**
11
+ * Internal constructor not depended on params. Can be used for object initialization
12
+ */
13
+ protected function _construct()
14
+ {
15
+ $params = array(
16
+ 'section' => Mage::app()->getRequest()->getParam('section'),
17
+ 'website' => Mage::app()->getRequest()->getParam('website'),
18
+ 'store' => Mage::app()->getRequest()->getParam('store'),
19
+ );
20
+ $this->setLabel('Reset All Orders');
21
+ $this->setOnClick("deleteConfirm('This will mark all orders as not-imported and will cause the importer to re-process each order again.\\n\\nAre you sure you want to do this?', '" . Mage::helper('adminhtml')->getUrl('*/order/reset', $params) . "'); return false;");
22
+ $this->setClass('delete');
23
+
24
+ if (!extension_loaded('soap') || !extension_loaded('openssl') || !Mage::helper('bronto_common')->getApiToken() || !Mage::helper('bronto_order')->isEnabled() || (!Mage::helper('bronto_order')->isDebugEnabled() && !Mage::helper('bronto_order')->isTestModeEnabled())) {
25
+ $this->setDisabled(true)->setClass('disabled');
26
+ }
27
+ }
28
+ }
app/code/community/Bronto/Order/Block/Adminhtml/Widget/Button/Run.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Order
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 2.0.0
7
+ */
8
+ class Bronto_Order_Block_Adminhtml_Widget_Button_Run extends Mage_Adminhtml_Block_Widget_Button
9
+ {
10
+ /**
11
+ * Internal constructor not depended on params. Can be used for object initialization
12
+ */
13
+ protected function _construct()
14
+ {
15
+ $params = array(
16
+ 'section' => Mage::app()->getRequest()->getParam('section'),
17
+ 'website' => Mage::app()->getRequest()->getParam('website'),
18
+ 'store' => Mage::app()->getRequest()->getParam('store'),
19
+ );
20
+ $this->setLabel('Run Now');
21
+ $this->setOnClick("setLocation('" . Mage::helper('adminhtml')->getUrl('*/order/run', $params) . "'); return false;");
22
+
23
+ if (!extension_loaded('soap') || !extension_loaded('openssl') || !Mage::helper('bronto_common')->getApiToken() || !Mage::helper('bronto_order')->isEnabled()) {
24
+ $this->setDisabled(true)->setClass('disabled');
25
+ }
26
+ }
27
+ }
app/code/community/Bronto/Order/Block/Bta.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Order
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ * @deprecated
8
+ */
9
+ class Bronto_Order_Block_Bta extends Mage_Core_Block_Text
10
+ {
11
+ /**
12
+ * Render Bronto tracking script
13
+ *
14
+ * @return string
15
+ */
16
+ protected function _toHtml()
17
+ {
18
+ $siteId = '';
19
+ $host = '';
20
+
21
+ return "
22
+ <script>
23
+ (function(d,t){
24
+ var b=d.createElement(t), s=d.getElementsByTagName(t)[0];
25
+ b.src='//p.bm23.com/bta.js';
26
+ b.onload = function(){ var bta = new __bta('{$siteId}'); bta.setHost('{$host}'); };
27
+ s.parentNode.insertBefore(b,s)
28
+ }(document,'script'));
29
+ </script>";
30
+ }
31
+ }
app/code/community/Bronto/Order/Helper/Data.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Order
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Order_Helper_Data extends Bronto_Common_Helper_Data implements Bronto_Common_Helper_DataInterface
9
+ {
10
+ const XML_PATH_ENABLED = 'bronto_order/settings/enabled';
11
+ const XML_PATH_LIMIT = 'bronto_order/settings/limit';
12
+ const XML_PATH_DESCRIPTION = 'bronto_order/settings/description_attribute';
13
+ const XML_PATH_INSTALL_DATE = 'bronto_order/settings/install_date';
14
+ const XML_PATH_UPGRADE_DATE = 'bronto_order/settings/upgrade_date';
15
+
16
+ /**
17
+ * @return bool
18
+ */
19
+ public function isEnabled()
20
+ {
21
+ return (bool) Mage::getStoreConfig(self::XML_PATH_ENABLED);
22
+ }
23
+
24
+ /**
25
+ * @param string $path
26
+ * @return bool
27
+ */
28
+ public function disableModule($scope = 'default', $scopeId = 0)
29
+ {
30
+ return $this->_disableModule(self::XML_PATH_ENABLED, $scope, $scopeId);
31
+ }
32
+
33
+ /**
34
+ * @return int
35
+ */
36
+ public function getLimit()
37
+ {
38
+ if (!$this->isEnabled()) {
39
+ return false;
40
+ }
41
+
42
+ return (int) Mage::getStoreConfig(self::XML_PATH_LIMIT);
43
+ }
44
+
45
+ /**
46
+ * @return string
47
+ */
48
+ public function getDescriptionAttribute()
49
+ {
50
+ return Mage::getStoreConfig(self::XML_PATH_DESCRIPTION);
51
+ }
52
+
53
+ /**
54
+ * Retrieve helper module name
55
+ *
56
+ * @return string
57
+ */
58
+ protected function _getModuleName()
59
+ {
60
+ return 'Bronto_Order';
61
+ }
62
+ }
app/code/community/Bronto/Order/Model/Observer.php ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Order
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Order_Model_Observer
9
+ {
10
+ const NOTICE_IDENTIFER = 'bronto_order';
11
+
12
+ /**
13
+ * @param Varien_Event_Observer $observer
14
+ */
15
+ public function checkBrontoRequirements(Varien_Event_Observer $observer)
16
+ {
17
+ if (!Mage::getSingleton('admin/session')->isLoggedIn()) {
18
+ return;
19
+ }
20
+
21
+ // Verify Requirements
22
+ if (!Mage::helper(self::NOTICE_IDENTIFER)->varifyRequirements(self::NOTICE_IDENTIFER, array('soap', 'openssl'))) {
23
+ return;
24
+ }
25
+ }
26
+
27
+ /**
28
+ * @param mixed $storeId
29
+ * @return array
30
+ */
31
+ public function processOrdersForStore($storeId = null)
32
+ {
33
+ if (is_object($storeId)) {
34
+ $store = $storeId;
35
+ $storeId = $store->getId();
36
+ } else {
37
+ $store = Mage::app()->getStore($storeId);
38
+ $storeId = $store->getId();
39
+ }
40
+
41
+ $result = array('total' => 0, 'success' => 0, 'error' => 0);
42
+ Mage::helper('bronto_order')->writeDebug("Starting Order Import process for store: {$store->getName()} ({$storeId})");
43
+
44
+ if (!$store->getConfig(Bronto_Order_Helper_Data::XML_PATH_ENABLED)) {
45
+ Mage::helper('bronto_order')->writeDebug(' Module disabled for this store. Skipping...');
46
+ return $result;
47
+ }
48
+
49
+ // Retrieve Store's configured API Token
50
+ $token = $store->getConfig(Bronto_Common_Helper_Data::XML_PATH_API_TOKEN);
51
+
52
+ /* @var $api Bronto_Common_Model_Api */
53
+ $api = Mage::helper('bronto_order')->getApi($token);
54
+
55
+ /* @var $orderObject Bronto_Api_Order */
56
+ $orderObject = $api->getOrderObject();
57
+
58
+ $limit = $store->getConfig(Bronto_Order_Helper_Data::XML_PATH_LIMIT);
59
+ if (!$limit) {
60
+ Mage::helper('bronto_order')->writeDebug(' Limit empty. Skipping...');
61
+ return $result;
62
+ }
63
+
64
+ $orderIds = Mage::getModel('bronto_order/resource_order_collection')
65
+ ->addStoreFilter($storeId)
66
+ ->addBrontoNotImportedFilter()
67
+ ->orderByUpdatedAt()
68
+ ->getAllIds($limit);
69
+
70
+ if (empty($orderIds)) {
71
+ Mage::helper('bronto_order')->writeVerboseDebug(' No Orders to process. Skipping...');
72
+ return $result;
73
+ }
74
+
75
+ /* @var $productHelper Bronto_Common_Helper_Product */
76
+ $productHelper = Mage::helper('bronto_common/product');
77
+ $descriptionAttr = $store->getConfig(Bronto_Order_Helper_Data::XML_PATH_DESCRIPTION);
78
+ $orderCache = array();
79
+
80
+ foreach ($orderIds as $orderId) {
81
+ if ($order = Mage::getModel('sales/order')->load($orderId) /* @var $order Mage_Sales_Model_Order */) {
82
+ Mage::helper('bronto_order')->writeDebug(" Processing Order ID: {$orderId}");
83
+ $orderCache[] = $orderId;
84
+
85
+ /* @var $brontoOrder Bronto_Api_Order_Row */
86
+ $brontoOrder = $orderObject->createRow();
87
+ $brontoOrder->email = $order->getCustomerEmail();
88
+ $brontoOrder->id = $order->getIncrementId();
89
+ $brontoOrder->orderDate = date('c', strtotime($order->getCreatedAt()));
90
+ if ($tid = $order->getBrontoTid()) {
91
+ $brontoOrder->tid = $tid;
92
+ }
93
+ $brontoOrderItems = array();
94
+
95
+ switch ($order->getState()) {
96
+ case Mage_Sales_Model_Order::STATE_CANCELED:
97
+ case Mage_Sales_Model_Order::STATE_HOLDED:
98
+ case Mage_Sales_Model_Order::STATE_CLOSED:
99
+ $brontoOrder->delete();
100
+ break;
101
+
102
+ default:
103
+ // loop through the items. if it's a bundled item, replace the parent item with the child items.
104
+ $items = $order->getAllVisibleItems();
105
+ $i = 0;
106
+ foreach ($items as $item) {
107
+ if (count($item->getChildrenItems()) > 0) {
108
+ unset($items[0]);
109
+ foreach ($item->getChildrenItems() as $child_item) {
110
+ $items[] = $child_item;
111
+ }
112
+ }
113
+ $i++;
114
+ }
115
+
116
+ foreach ($items as $item /* @var $item Mage_Sales_Model_Order_Item */) {
117
+ /* @var $product Mage_Catalog_Model_Product */
118
+ $product = Mage::getModel('catalog/product')->load($item->getProductId());
119
+ $categoryIds = $product->getCategoryIds();
120
+ $categories = array();
121
+ foreach ($categoryIds as $categoryId) {
122
+ /* @var $category Mage_Catalog_Model_Category */
123
+ $category = Mage::getModel('catalog/category')->load($categoryId);
124
+ $parent = $category->getParentCategory();
125
+ $categories[] = $parent->getUrlKey() ? $parent->getUrlKey() : $parent->formatUrlKey($parent->getName());
126
+ $categories[] = $category->getUrlKey() ? $category->getUrlKey() : $category->formatUrlKey($category->getName());
127
+ }
128
+ $categories = array_unique($categories);
129
+
130
+ // Write orderItem
131
+ $brontoOrderItems[] = array(
132
+ 'id' => $item->getId(),
133
+ 'sku' => $item->getSku(),
134
+ 'name' => $item->getName(),
135
+ 'description' => $productHelper->getProductAttribute($item->getProductId(), $descriptionAttr),
136
+ 'category' => implode(' ', $categories),
137
+ 'image' => $productHelper->getProductAttribute($item->getProductId(), 'image'),
138
+ 'url' => $productHelper->getProductAttribute($item->getProductId(), 'url'),
139
+ 'quantity' => (int) $item->getQtyOrdered(),
140
+ 'price' => (float) $item->getPrice(),
141
+ );
142
+ }
143
+ $brontoOrder->products = $brontoOrderItems;
144
+ $brontoOrder->persist();
145
+ break;
146
+ }
147
+
148
+ try {
149
+ // Mark order as imported
150
+ $order->setBrontoImported(Mage::getSingleton('core/date')->gmtDate());
151
+ $order->save();
152
+
153
+ // Flush every 10 orders
154
+ if ($result['total'] % 100 === 0) {
155
+ $result = $this->flushOrders($orderObject, $orderCache, $result);
156
+ $orderCache = array();
157
+ }
158
+ } catch (Exception $e) {
159
+ Mage::helper('bronto_order')->writeError($e);
160
+
161
+ // Mark import as *not* imported
162
+ $order->setBrontoImported(null);
163
+ $order->save();
164
+
165
+ $result['error']++;
166
+ }
167
+
168
+ $result['total']++;
169
+ }
170
+ }
171
+
172
+ // Final flush (for any we miss)
173
+ $result = $this->flushOrders($orderObject, $orderCache, $result);
174
+
175
+ Mage::helper('bronto_order')->writeDebug(' Success: ' . $result['success']);
176
+ Mage::helper('bronto_order')->writeDebug(' Error: ' . $result['error']);
177
+ Mage::helper('bronto_order')->writeDebug(' Total: ' . $result['total']);
178
+
179
+ return $result;
180
+ }
181
+
182
+ /**
183
+ * @param Bronto_Api_Order $orderObject
184
+ * @param array $orderCache
185
+ * @param array $result
186
+ * @return array
187
+ */
188
+ public function flushOrders($orderObject, $orderCache, $result)
189
+ {
190
+ $flushResult = $orderObject->flush();
191
+
192
+ Mage::helper('bronto_order')->writeVerboseDebug('===== FLUSH =====', 'bronto_order_api.log');
193
+ Mage::helper('bronto_order')->writeVerboseDebug(var_export($orderObject->getApi()->getLastRequest(), true), 'bronto_order_api.log');
194
+ Mage::helper('bronto_order')->writeVerboseDebug(var_export($orderObject->getApi()->getLastResponse(), true), 'bronto_order_api.log');
195
+
196
+ foreach ($flushResult as $i => $flushResultRow) {
197
+ if ($flushResultRow->hasError()) {
198
+ $errorCode = $flushResultRow->getErrorCode();
199
+ $errorMessage = $flushResultRow->getErrorMessage();
200
+ if (isset($orderCache[$i])) {
201
+ // Reset Bronto Import status
202
+ $order = Mage::getModel('sales/order')->load($orderCache[$i]);
203
+ $order->setBrontoImported(null);
204
+ $order->save();
205
+ Mage::helper('bronto_order')->writeError("[{$errorCode}] {$errorMessage} ({$order->getIncrementId})");
206
+ } else {
207
+ Mage::helper('bronto_order')->writeError("[{$errorCode}] {$errorMessage}");
208
+ }
209
+ $result['error']++;
210
+ } else {
211
+ $result['success']++;
212
+ }
213
+ }
214
+
215
+ return $result;
216
+ }
217
+
218
+ /**
219
+ * @return array
220
+ */
221
+ public function processOrders()
222
+ {
223
+ $result = array(
224
+ 'total' => 0,
225
+ 'success' => 0,
226
+ 'error' => 0,
227
+ );
228
+
229
+ $stores = Mage::app()->getStores();
230
+ foreach ($stores as $_storeId => $_store) {
231
+ $storeResult = $this->processOrdersForStore($_store);
232
+ $result['total'] += $storeResult['total'];
233
+ $result['success'] += $storeResult['success'];
234
+ $result['error'] += $storeResult['error'];
235
+ }
236
+
237
+ return $result;
238
+ }
239
+ }
app/code/community/Bronto/Order/Model/Order/Observer.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Order
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Order_Model_Order_Observer
9
+ {
10
+ /**
11
+ * Called when refunding an order.
12
+ *
13
+ * @param Varien_Event_Observer $observer
14
+ */
15
+ public function resetCreditMemoOrder(Varien_Event_Observer $observer)
16
+ {
17
+ /* @var $order Mage_Sales_Model_Order */
18
+ $order = $observer->getCreditmemo()->getOrder();
19
+ $order->setBrontoImported(null);
20
+ }
21
+
22
+ /**
23
+ * Called when cancelling an order.
24
+ *
25
+ * @param Varien_Event_Observer $observer
26
+ */
27
+ public function resetPaymentCancelOrder(Varien_Event_Observer $observer)
28
+ {
29
+ /* @var $order Mage_Sales_Model_Order */
30
+ $order = $observer->getPayment()->getOrder();
31
+ $order->setBrontoImported(null);
32
+ }
33
+
34
+ /**
35
+ * If an Order's status is changing,
36
+ * just reset the flag anyways...
37
+ *
38
+ * @param Varien_Event_Observer $observer
39
+ */
40
+ public function markOrderForReimport(Varien_Event_Observer $observer)
41
+ {
42
+ /* @var $order Mage_Sales_Model_Order */
43
+ $order = $observer->getOrder();
44
+ $order->setBrontoImported(null);
45
+ }
46
+ }
app/code/community/Bronto/Order/Model/Quote/Observer.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Order
5
+ * @copyright 2011-2013 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Order_Model_Quote_Observer
9
+ {
10
+ /**
11
+ * This event should only fire on the "frontend". It reads Bronto's
12
+ * "tid" cookie value and assigns to the shopping cart.
13
+ *
14
+ * @param Varien_Event_Observer $observer
15
+ */
16
+ public function addTidToQuote(Varien_Event_Observer $observer)
17
+ {
18
+ /* @var $quote Mage_Sales_Model_Quote */
19
+ $quote = $observer->getQuote();
20
+
21
+ foreach (Mage::getModel('core/cookie')->get() as $key => $value) {
22
+ if (stripos($key, "tid_") !== false) {
23
+ $quote->setBrontoTid($value);
24
+ break;
25
+ }
26
+ }
27
+ }
28
+ }
app/code/community/Bronto/Order/Model/Resource/Order/Collection.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Order
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Order_Model_Resource_Order_Collection extends Mage_Sales_Model_Mysql4_Order_Collection
9
+ {
10
+ /**
11
+ * @return Bronto_Order_Model_Resource_Order_Collection
12
+ */
13
+ public function addBrontoImportedFilter()
14
+ {
15
+ $this->addAttributeToFilter('bronto_imported', array('notnull' => true));
16
+ return $this;
17
+ }
18
+
19
+ /**
20
+ * @return Bronto_Order_Model_Resource_Order_Collection
21
+ */
22
+ public function addBrontoNotImportedFilter()
23
+ {
24
+ $this->addAttributeToFilter('bronto_imported', array('null' => true));
25
+ return $this;
26
+ }
27
+
28
+ /**
29
+ * @param mixed $storeIds (null, int|string, array, array may contain null)
30
+ * @return Bronto_Order_Model_Resource_Order_Collection
31
+ */
32
+ public function addStoreFilter($storeIds)
33
+ {
34
+ $nullCheck = false;
35
+
36
+ if (!is_array($storeIds)) {
37
+ $storeIds = array($storeIds);
38
+ }
39
+
40
+ $storeIds = array_unique($storeIds);
41
+
42
+ if ($index = array_search(null, $storeIds)) {
43
+ unset($storeIds[$index]);
44
+ $nullCheck = true;
45
+ }
46
+
47
+ $storeIds[0] = ($storeIds[0] == '') ? 0 : $storeIds[0];
48
+
49
+ if ($nullCheck) {
50
+ $this->getSelect()->where('store_id IN(?) OR store_id IS NULL', $storeIds);
51
+ } else {
52
+ $this->getSelect()->where('store_id IN(?)', $storeIds);
53
+ }
54
+
55
+ return $this;
56
+ }
57
+
58
+ /**
59
+ * Sort order by order created_at date
60
+ *
61
+ * @param string $dir
62
+ * @return Bronto_Order_Model_Resource_Order_Collection
63
+ */
64
+ public function orderByCreatedAt($dir = self::SORT_ORDER_DESC)
65
+ {
66
+ $this->setOrder('created_at', $dir);
67
+ return $this;
68
+ }
69
+
70
+ /**
71
+ * Sort order by order updated_at date
72
+ *
73
+ * @param string $dir
74
+ * @return Bronto_Order_Model_Resource_Order_Collection
75
+ */
76
+ public function orderByUpdatedAt($dir = self::SORT_ORDER_DESC)
77
+ {
78
+ $this->setOrder('updated_at', $dir);
79
+ return $this;
80
+ }
81
+ }
app/code/community/Bronto/Order/Model/Resource/Setup.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Order
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Order_Model_Resource_Setup extends Mage_Sales_Model_Mysql4_Setup
9
+ {
10
+
11
+ /**
12
+ * Short description for function
13
+ *
14
+ * Long description (if any) ...
15
+ *
16
+ * @param string $code Parameter description (if any) ...
17
+ * @param unknown $data Parameter description (if any) ...
18
+ * @return string Return description (if any) ...
19
+ * @access protected
20
+ */
21
+ protected function _getAttributeColumnDefinition($code, $data)
22
+ {
23
+ $definition = parent::_getAttributeColumnDefinition($code, $data);
24
+
25
+ if ($code === 'bronto_imported' && is_string($definition)) {
26
+ return 'datetime NULL DEFAULT NULL';
27
+ }
28
+
29
+ return $definition;
30
+ }
31
+ }
app/code/community/Bronto/Order/Model/System/Config/Backend/Cron.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Order
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Order_Model_System_Config_Backend_Cron extends Bronto_Common_Model_System_Config_Backend_Cron
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_cron_string_path = 'crontab/jobs/bronto_order_import/schedule/cron_expr';
14
+
15
+ /**
16
+ * @var string
17
+ */
18
+ protected $_cron_model_path = 'crontab/jobs/bronto_order_import/run/model';
19
+ }
app/code/community/Bronto/Order/Model/System/Config/Source/Description.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Order
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Order_Model_System_Config_Source_Description
9
+ {
10
+ /**
11
+ * @return array
12
+ */
13
+ public function toOptionArray()
14
+ {
15
+ return array(
16
+ 'short_description' => 'short_description',
17
+ 'description' => 'description',
18
+ );
19
+ }
20
+ }
app/code/community/Bronto/Order/Model/System/Config/Source/Limit.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Order
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Order_Model_System_Config_Source_Limit
9
+ {
10
+ /**
11
+ * @return array
12
+ */
13
+ public function toOptionArray()
14
+ {
15
+ return array(
16
+ 50 => 50,
17
+ 100 => 100,
18
+ 250 => 250,
19
+ 500 => 500,
20
+ 1000 => 1000,
21
+ );
22
+ }
23
+ }
app/code/community/Bronto/Order/Test/Config/Config.php ADDED
@@ -0,0 +1,233 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_Order_Test_Config_Config
3
+ extends EcomDev_PHPUnit_Test_Case_Config
4
+ {
5
+ // {{{ blocksProvider()
6
+
7
+ public function blocksProvider()
8
+ {
9
+ return array(
10
+ array('bronto_order/bta', 'Bronto_Order_Block_Bta'),
11
+ array('bronto_order/adminhtml_sales_order_view_tab_info', 'Bronto_Order_Block_Adminhtml_Sales_Order_View_Tab_Info'),
12
+ array('bronto_order/adminhtml_system_config_about', 'Bronto_Order_Block_Adminhtml_System_Config_About'),
13
+ array('bronto_order/adminhtml_system_config_cron', 'Bronto_Order_Block_Adminhtml_System_Config_Cron'),
14
+ array('bronto_order/adminhtml_widget_button_reset', 'Bronto_Order_Block_Adminhtml_Widget_Button_Reset'),
15
+ array('bronto_order/adminhtml_widget_button_run', 'Bronto_Order_Block_Adminhtml_Widget_Button_Run'),
16
+ );
17
+ }
18
+
19
+ // }}}
20
+ // {{{ resourceModelProvider()
21
+
22
+ public function resourceModelProvider()
23
+ {
24
+ return array(
25
+ array('bronto_order_resource/setup', 'Bronto_Order_Model_Resource_Setup'),
26
+ array('bronto_order_resource/order_collection', 'Bronto_Order_Model_Resource_Order_Collection'),
27
+ );
28
+ }
29
+
30
+ // }}}
31
+ // {{{ modelsProvider()
32
+
33
+ public function modelsProvider()
34
+ {
35
+ return array(
36
+ array('bronto_order/system_config_backend_cron', 'Bronto_Order_Model_System_Config_Backend_Cron'),
37
+ array('bronto_order/system_config_source_description', 'Bronto_Order_Model_System_Config_Source_Description'),
38
+ array('bronto_order/system_config_source_limit', 'Bronto_Order_Model_System_Config_Source_Limit'),
39
+ );
40
+ }
41
+
42
+ // }}}
43
+ // {{{ helpersProvider()
44
+
45
+ public function helpersProvider()
46
+ {
47
+ return array(
48
+ array('bronto_order/data', 'Bronto_Order_Helper_Data'),
49
+ );
50
+ }
51
+
52
+ // }}}
53
+ // {{{ observersProvider()
54
+
55
+ public function observersProvider()
56
+ {
57
+ return array(
58
+ array('global', 'sales_order_save_before', 'bronto_order/order_observer', 'markOrderForReimport'),
59
+ array('frontend', 'sales_quote_save_before', 'bronto_order/quote_observer', 'addTidToQuote'),
60
+ array('adminhtml', 'controller_action_predispatch', 'bronto_order/observer', 'checkBrontoRequirements'),
61
+ );
62
+ }
63
+
64
+ // }}}
65
+ // {{{ definedLayoutFilesProvider()
66
+
67
+ public function definedLayoutFilesProvider()
68
+ {
69
+ return array(
70
+ /*array('frontend', 'bronto/user.xml'),*/
71
+ );
72
+ }
73
+
74
+ // }}}
75
+ // {{{ themeLayoutFilesExistProvider()
76
+
77
+ public function themeLayoutFilesExistProvider()
78
+ {
79
+ return array(
80
+ /*array('frontend', 'bronto/user.xml', 'adsinc', 'adsinc'),*/
81
+ );
82
+ }
83
+
84
+ // }}}
85
+
86
+ /**
87
+ * @test
88
+ * @group amd
89
+ * @group config
90
+ */
91
+ public function assertOrderModuleVersionGreaterThanOrEquals()
92
+ {
93
+ $this->assertModuleVersionGreaterThanOrEquals('1.1.5');
94
+ }
95
+
96
+ // {{{ assertOrderModuleInLocalCodePool()
97
+
98
+ /**
99
+ * @test
100
+ * @group amd
101
+ * @group config
102
+ */
103
+ public function assertOrderModuleInCommunityCodePool()
104
+ {
105
+ $this->assertModuleCodePool('community');
106
+ }
107
+
108
+ // }}}
109
+ // {{{ assertOrderModelAliases()
110
+
111
+ /**
112
+ * @test
113
+ * @group amd
114
+ * @group config
115
+ * @dataProvider modelsProvider
116
+ */
117
+ public function assertOrderModelAliases(
118
+ $classAlias,
119
+ $expectedClassName
120
+ ) {
121
+ $this->assertModelAlias($classAlias, $expectedClassName);
122
+ }
123
+
124
+ // }}}
125
+ // {{{ assertOrderResourceModelAliases()
126
+
127
+ /**
128
+ * @test
129
+ * @group amd
130
+ * @group config
131
+ * @dataProvider resourceModelProvider
132
+ */
133
+ public function assertOrderResourceModelAliases(
134
+ $classAlias,
135
+ $expectedClassName
136
+ ) {
137
+ $this->assertResourceModelAlias($classAlias, $expectedClassName);
138
+ }
139
+
140
+ // }}}
141
+ // {{{ assertOrderBlockAliases()
142
+
143
+ /**
144
+ * @test
145
+ * @group amd
146
+ * @group config
147
+ * @dataProvider blocksProvider
148
+ */
149
+ public function assertOrderBlockAliases(
150
+ $classAlias,
151
+ $expectedClassName
152
+ ) {
153
+ $this->assertBlockAlias($classAlias, $expectedClassName);
154
+ }
155
+
156
+ // }}}
157
+ // {{{ assertOrderHelperAliases()
158
+
159
+ /**
160
+ * @test
161
+ * @group amd
162
+ * @group config
163
+ * @dataProvider helpersProvider
164
+ */
165
+ public function assertOrderHelperAliases(
166
+ $classAlias,
167
+ $expectedClassName
168
+ ) {
169
+ $this->assertHelperAlias($classAlias, $expectedClassName);
170
+ }
171
+
172
+ // }}}
173
+ // {{{ assertOrderEventObserversDefined()
174
+
175
+ /**
176
+ * @test
177
+ * @group config
178
+ * @group amd
179
+ * @dataProvider observersProvider
180
+ */
181
+ public function assertOrderEventObserversDefined(
182
+ $area,
183
+ $eventName,
184
+ $observerClassAlias,
185
+ $observerMethod
186
+ ) {
187
+ $this->assertEventObserverDefined(
188
+ $area,
189
+ $eventName,
190
+ $observerClassAlias,
191
+ $observerMethod
192
+ );
193
+ }
194
+
195
+ // }}}
196
+ // {{{ assertOrderLayoutFileDefined()
197
+
198
+ /**
199
+ * test
200
+ * @group config
201
+ * @group amd
202
+ * @dataProvider definedLayoutFilesProvider
203
+ */
204
+ public function assertOrderLayoutFileDefined($area, $expectedFileName)
205
+ {
206
+ $this->assertLayoutFileDefined($area, $expectedFileName);
207
+ }
208
+
209
+ // }}}
210
+ // {{{ assertOrderLayoutFileExistsForDefaultTheme()
211
+
212
+ /**
213
+ * test
214
+ * @group config
215
+ * @group amd
216
+ * @dataProvider themeLayoutFilesExistProvider
217
+ */
218
+ public function assertOrderLayoutFileExistsForDefaultTheme(
219
+ $area,
220
+ $filename,
221
+ $theme,
222
+ $designPackage
223
+ ) {
224
+ $this->assertLayoutFileExistsInTheme(
225
+ $area,
226
+ $filename,
227
+ $theme,
228
+ $designPackage
229
+ );
230
+ }
231
+
232
+ // }}}
233
+ }
app/code/community/Bronto/Order/controllers/Adminhtml/OrderController.php ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Bronto
5
+ * @package Order
6
+ */
7
+ class Bronto_Order_Adminhtml_OrderController extends Mage_Adminhtml_Controller_Action
8
+ {
9
+ /**
10
+ * Run immediately
11
+ */
12
+ public function runAction()
13
+ {
14
+ try {
15
+ $result = array('total' => 0, 'success' => 0, 'error' => 0);
16
+ $model = Mage::getModel('bronto_order/observer');
17
+
18
+ if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
19
+ $store = Mage::app()->getStore($storeCode);
20
+ $storeIds[] = $store->getId();
21
+ } elseif ($websiteCode = Mage::app()->getRequest()->getParam('website')){
22
+ $website = Mage::app()->getWebsite($websiteCode);
23
+ $storeIds = $website->getStoreIds();
24
+ } elseif ($groupCode = Mage::app()->getRequest()->getParam('group')){
25
+ $website = Mage::app()->getGroup($groupCode)->getWebsite();
26
+ $storeIds = $website->getStoreIds();
27
+ } else {
28
+ $storeIds = false;
29
+ }
30
+
31
+ if ($storeIds) {
32
+ foreach ($storeIds as $storeId) {
33
+ $storeResult = $model->processOrdersForStore($storeId);
34
+ $result['total'] += $storeResult['total'];
35
+ $result['success'] += $storeResult['success'];
36
+ $result['error'] += $storeResult['error'];
37
+ }
38
+ } else {
39
+ $result = $model->processOrders();
40
+ }
41
+
42
+ if (is_array($result)) {
43
+ $this->_getSession()->addSuccess(sprintf("Processed %d Orders (%d Error / %d Success)", $result['total'], $result['error'], $result['success']));
44
+ } else {
45
+ $this->_getSession()->addError('Scheduled Import failed: ' . $result);
46
+ }
47
+
48
+ } catch (Exception $e) {
49
+ $this->_getSession()->addError($e->getMessage());
50
+ Mage::helper('bronto_order')->writeError($e);
51
+ }
52
+
53
+ $this->_redirect('*/system_config/edit', array('section' => 'bronto_order'));
54
+ }
55
+
56
+ /**
57
+ * Reset all Orders
58
+ */
59
+ public function resetAction()
60
+ {
61
+ $storeIds = array();
62
+ $writeConnection = Mage::getSingleton('core/resource')->getConnection('core_write');
63
+ $tablePrefix = Mage::getConfig()->getTablePrefix();
64
+
65
+ if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
66
+ $store = Mage::app()->getStore($storeCode);
67
+ $storeIds[] = $store->getId();
68
+ } elseif ($websiteCode = Mage::app()->getRequest()->getParam('website')){
69
+ $website = Mage::app()->getWebsite($websiteCode);
70
+ $storeIds = $website->getStoreIds();
71
+ } elseif ($groupCode = Mage::app()->getRequest()->getParam('group')){
72
+ $website = Mage::app()->getGroup($groupCode)->getWebsite();
73
+ $storeIds = $website->getStoreIds();
74
+ } else {
75
+ $storeIds[] = null;
76
+ }
77
+
78
+ foreach ($storeIds as $storeId) {
79
+ $sql = "
80
+ UPDATE {$tablePrefix}sales_flat_order
81
+ SET bronto_imported = null
82
+ ";
83
+ if (!empty($storeId)) {
84
+ $storeId = (int) $storeId;
85
+ $sql .= " WHERE store_id = {$storeId}";
86
+ }
87
+
88
+ try {
89
+ $writeConnection->query($sql);
90
+ } catch (Exception $e) {
91
+ Mage::helper('bronto_order')->writeError($e);
92
+ $this->_getSession()->addError('Reset failed: ' . $e->getMessage());
93
+ }
94
+ }
95
+
96
+ $this->_redirect('*/system_config/edit', array('section' => 'bronto_order'));
97
+ }
98
+
99
+ /**
100
+ * @return bool
101
+ */
102
+ protected function _isAllowed()
103
+ {
104
+ return $this->_isSectionAllowed('bronto_order');
105
+ }
106
+
107
+ /**
108
+ * Check if specified section allowed in ACL
109
+ *
110
+ * Will forward to deniedAction(), if not allowed.
111
+ *
112
+ * @param string $section
113
+ * @return bool
114
+ */
115
+ protected function _isSectionAllowed($section)
116
+ {
117
+ try {
118
+ $session = Mage::getSingleton('admin/session');
119
+ $resourceLookup = "admin/system/config/{$section}";
120
+ if ($session->getData('acl') instanceof Mage_Admin_Model_Acl) {
121
+ $resourceId = $session->getData('acl')->get($resourceLookup)->getResourceId();
122
+ if (!$session->isAllowed($resourceId)) {
123
+ throw new Exception('');
124
+ }
125
+ return true;
126
+ }
127
+ } catch (Zend_Acl_Exception $e) {
128
+ $this->norouteAction();
129
+ $this->setFlag('', self::FLAG_NO_DISPATCH, true);
130
+ return false;
131
+ } catch (Exception $e) {
132
+ $this->deniedAction();
133
+ $this->setFlag('', self::FLAG_NO_DISPATCH, true);
134
+ return false;
135
+ }
136
+ }
137
+ }
app/code/community/Bronto/Order/etc/adminhtml.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <admin>
6
+ <children>
7
+ <system>
8
+ <children>
9
+ <config>
10
+ <children>
11
+ <bronto_order module="bronto_order">
12
+ <title>Bronto Order Import Section</title>
13
+ </bronto_order>
14
+ </children>
15
+ </config>
16
+ </children>
17
+ </system>
18
+ </children>
19
+ </admin>
20
+ </resources>
21
+ </acl>
22
+ </config>
app/code/community/Bronto/Order/etc/config.xml ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Bronto_Order>
5
+ <version>1.1.5</version>
6
+ </Bronto_Order>
7
+ </modules>
8
+ <global>
9
+ <fieldsets>
10
+ <sales_convert_quote>
11
+ <bronto_tid><to_order>*</to_order></bronto_tid>
12
+ </sales_convert_quote>
13
+ <sales_convert_order>
14
+ <bronto_tid><to_quote>*</to_quote></bronto_tid>
15
+ </sales_convert_order>
16
+ </fieldsets>
17
+ <helpers>
18
+ <bronto_order>
19
+ <class>Bronto_Order_Helper</class>
20
+ </bronto_order>
21
+ </helpers>
22
+ <blocks>
23
+ <bronto_order>
24
+ <class>Bronto_Order_Block</class>
25
+ </bronto_order>
26
+ </blocks>
27
+ <models>
28
+ <bronto_order>
29
+ <class>Bronto_Order_Model</class>
30
+ <resourceModel>bronto_order_resource</resourceModel>
31
+ </bronto_order>
32
+ <bronto_order_resource>
33
+ <class>Bronto_Order_Model_Resource</class>
34
+ </bronto_order_resource>
35
+ </models>
36
+ <resources>
37
+ <bronto_order_setup>
38
+ <setup>
39
+ <module>Bronto_Order</module>
40
+ <class>Bronto_Order_Model_Resource_Setup</class>
41
+ </setup>
42
+ <connection>
43
+ <use>core_setup</use>
44
+ </connection>
45
+ </bronto_order_setup>
46
+ <bronto_order_write>
47
+ <connection>
48
+ <use>core_write</use>
49
+ </connection>
50
+ </bronto_order_write>
51
+ <bronto_order_read>
52
+ <connection>
53
+ <use>core_read</use>
54
+ </connection>
55
+ </bronto_order_read>
56
+ </resources>
57
+ <events>
58
+ <sales_order_save_before>
59
+ <observers>
60
+ <bronto_order_sales_order_save_before>
61
+ <type>singleton</type>
62
+ <class>bronto_order/order_observer</class>
63
+ <method>markOrderForReimport</method>
64
+ </bronto_order_sales_order_save_before>
65
+ </observers>
66
+ </sales_order_save_before>
67
+ <sales_order_creditmemo_refund>
68
+ <observers>
69
+ <bronto_order_sales_order_creditmemo_refund>
70
+ <type>singleton</type>
71
+ <class>bronto_order/order_observer</class>
72
+ <method>resetCreditMemoOrder</method>
73
+ </bronto_order_sales_order_creditmemo_refund>
74
+ </observers>
75
+ </sales_order_creditmemo_refund>
76
+ <sales_order_payment_cancel>
77
+ <observers>
78
+ <bronto_order_sales_order_payment_cancel>
79
+ <type>singleton</type>
80
+ <class>bronto_order/order_observer</class>
81
+ <method>resetPaymentCancelOrder</method>
82
+ </bronto_order_sales_order_payment_cancel>
83
+ </observers>
84
+ </sales_order_payment_cancel>
85
+ </events>
86
+ </global>
87
+ <frontend>
88
+ <events>
89
+ <sales_quote_save_before>
90
+ <observers>
91
+ <bronto_order_sales_quote_save_before>
92
+ <type>singleton</type>
93
+ <class>bronto_order/quote_observer</class>
94
+ <method>addTidToQuote</method>
95
+ </bronto_order_sales_quote_save_before>
96
+ </observers>
97
+ </sales_quote_save_before>
98
+ </events>
99
+ </frontend>
100
+ <admin>
101
+ <blocks>
102
+ <adminhtml>
103
+ <rewrite>
104
+ <sales_order_view_tab_info>bronto_order/adminhtml_sales_order_view_tab_info</sales_order_view_tab_info>
105
+ </rewrite>
106
+ </adminhtml>
107
+ </blocks>
108
+ <routers>
109
+ <adminhtml>
110
+ <args>
111
+ <modules>
112
+ <bronto_order before="Mage_Adminhtml">Bronto_Order_Adminhtml</bronto_order>
113
+ </modules>
114
+ </args>
115
+ </adminhtml>
116
+ </routers>
117
+ </admin>
118
+ <default>
119
+ <bronto_order>
120
+ <settings>
121
+ <enabled>0</enabled>
122
+ <frequency>D</frequency>
123
+ <interval>15</interval>
124
+ <minutes>0</minutes>
125
+ <limit>250</limit>
126
+ <description_attribute>short_description</description_attribute>
127
+ </settings>
128
+ </bronto_order>
129
+ </default>
130
+ <crontab>
131
+ <jobs>
132
+ <bronto_order_import>
133
+ <schedule><cron_expr>*/15 * * * *</cron_expr></schedule>
134
+ <run><model>bronto_order/observer::processOrders</model></run>
135
+ </bronto_order_import>
136
+ </jobs>
137
+ </crontab>
138
+ <adminhtml>
139
+ <events>
140
+ <controller_action_predispatch>
141
+ <observers>
142
+ <bronto_order_controller_action_predispatch>
143
+ <class>bronto_order/observer</class>
144
+ <method>checkBrontoRequirements</method>
145
+ </bronto_order_controller_action_predispatch>
146
+ </observers>
147
+ </controller_action_predispatch>
148
+ </events>
149
+ <acl>
150
+ <resources>
151
+ <admin>
152
+ <children>
153
+ <system>
154
+ <children>
155
+ <config>
156
+ <children>
157
+ <bronto_order module="bronto_order">
158
+ <title>Bronto Order Import Section</title>
159
+ </bronto_order>
160
+ </children>
161
+ </config>
162
+ </children>
163
+ </system>
164
+ </children>
165
+ </admin>
166
+ </resources>
167
+ </acl>
168
+ </adminhtml>
169
+ <phpunit>
170
+ <suite>
171
+ <modules>
172
+ <Bronto_Order />
173
+ </modules>
174
+ </suite>
175
+ </phpunit>
176
+ </config>
app/code/community/Bronto/Order/etc/system.xml ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <bronto_order module="bronto_order">
5
+ <label>Order Import</label>
6
+ <tab>bronto</tab>
7
+ <frontend_type>text</frontend_type>
8
+ <sort_order>300</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
+ <about>
14
+ <frontend_type>text</frontend_type>
15
+ <frontend_model>bronto_order/adminhtml_system_config_about</frontend_model>
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
+ </about>
21
+ <settings>
22
+ <label>Settings</label>
23
+ <frontend_type>text</frontend_type>
24
+ <sort_order>1</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ <fields>
29
+ <enabled>
30
+ <label>Enable Module</label>
31
+ <frontend_type>select</frontend_type>
32
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
33
+ <source_model>adminhtml/system_config_source_yesno</source_model>
34
+ <sort_order>0</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
+ </enabled>
39
+ <frequency>
40
+ <label>Frequency</label>
41
+ <depends><enabled>1</enabled></depends>
42
+ <frontend_type>select</frontend_type>
43
+ <source_model>bronto_common/system_config_source_cron_frequency</source_model>
44
+ <backend_model>bronto_order/system_config_backend_cron</backend_model>
45
+ <sort_order>20</sort_order>
46
+ <show_in_default>1</show_in_default>
47
+ <show_in_website>0</show_in_website>
48
+ <show_in_store>0</show_in_store>
49
+ </frequency>
50
+ <interval>
51
+ <label>Interval</label>
52
+ <depends><frequency>I</frequency></depends>
53
+ <frontend_type>select</frontend_type>
54
+ <source_model>bronto_common/system_config_source_cron_minutes</source_model>
55
+ <sort_order>30</sort_order>
56
+ <show_in_default>1</show_in_default>
57
+ <show_in_website>0</show_in_website>
58
+ <show_in_store>0</show_in_store>
59
+ <comment>Set this value larger than your cron.php launch period.</comment>
60
+ </interval>
61
+ <minutes>
62
+ <label>Minute of the Hour</label>
63
+ <depends><frequency>H</frequency></depends>
64
+ <frontend_type>text</frontend_type>
65
+ <sort_order>40</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
+ <comment>Valid range: 0-59 (default 0).</comment>
70
+ </minutes>
71
+ <time>
72
+ <label>Start Time</label>
73
+ <depends><enabled>1</enabled></depends>
74
+ <frontend_type>time</frontend_type>
75
+ <sort_order>50</sort_order>
76
+ <show_in_default>1</show_in_default>
77
+ <show_in_website>0</show_in_website>
78
+ <show_in_store>0</show_in_store>
79
+ </time>
80
+ <limit>
81
+ <label>Limit</label>
82
+ <depends><enabled>1</enabled></depends>
83
+ <frontend_type>select</frontend_type>
84
+ <source_model>bronto_order/system_config_source_limit</source_model>
85
+ <sort_order>60</sort_order>
86
+ <show_in_default>1</show_in_default>
87
+ <show_in_website>0</show_in_website>
88
+ <show_in_store>0</show_in_store>
89
+ <comment>Total Orders to process every cron run.</comment>
90
+ </limit>
91
+ <description_attribute>
92
+ <label>Product Description Attribute</label>
93
+ <depends><enabled>1</enabled></depends>
94
+ <frontend_type>select</frontend_type>
95
+ <source_model>bronto_order/system_config_source_description</source_model>
96
+ <sort_order>70</sort_order>
97
+ <show_in_default>1</show_in_default>
98
+ <show_in_website>1</show_in_website>
99
+ <show_in_store>1</show_in_store>
100
+ <comment>Product attribute used for description field.</comment>
101
+ </description_attribute>
102
+ </fields>
103
+ </settings>
104
+ <cron_list>
105
+ <frontend_type>text</frontend_type>
106
+ <frontend_model>bronto_order/adminhtml_system_config_cron</frontend_model>
107
+ <sort_order>2</sort_order>
108
+ <show_in_default>1</show_in_default>
109
+ <show_in_website>0</show_in_website>
110
+ <show_in_store>1</show_in_store>
111
+ </cron_list>
112
+ </groups>
113
+ </bronto_order>
114
+ </sections>
115
+ </config>
app/code/community/Bronto/Order/sql/bronto_order_setup/mysql4-install-1.0.0.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Bronto_Order_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ //
9
+ // Quote Attributes
10
+ $installer->addAttribute('quote', 'bronto_tid', array(
11
+ 'type' => 'varchar',
12
+ 'required' => false,
13
+ ));
14
+
15
+ //
16
+ // Order Attributes
17
+ $installer->addAttribute('order', 'bronto_tid', array(
18
+ 'type' => 'varchar',
19
+ 'required' => false,
20
+ ));
21
+
22
+ $installer->addAttribute('order', 'bronto_imported', array(
23
+ 'type' => 'datetime',
24
+ 'required' => false,
25
+ ));
26
+
27
+ try {
28
+ $installer->getConnection()->addKey(
29
+ $installer->getTable('sales/order'), 'IDX_BRONTO_IMPORTED', 'bronto_imported'
30
+ );
31
+ } catch (Exception $e) {
32
+ // Already exists...
33
+ }
34
+
35
+ $installer->endSetup();
36
+
37
+ // Mark installation date
38
+ $config = Mage::getConfig();
39
+ $config->saveConfig(Bronto_Order_Helper_Data::XML_PATH_INSTALL_DATE, time());
app/code/community/Bronto/PermissionChecker/Block/Adminhtml/System/Config/About.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * About header for admin module config
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package PermissionChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+
21
+ /**
22
+ * About header for admin module config
23
+ *
24
+ * @category Bronto
25
+ * @package PermissionChecker
26
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
27
+ * @copyright 2012 Atlantic BT
28
+ * @license http://www.atlanticbt.com/ Atlantic BT
29
+ * @version Release: @package_version@
30
+ * @link <>
31
+ * @see References to other sections (if any)...
32
+ */
33
+ class Bronto_PermissionChecker_Block_Adminhtml_System_Config_About
34
+ extends Bronto_Common_Block_Adminhtml_System_Config_About
35
+ {
36
+ // {{{ properties
37
+
38
+
39
+ /**
40
+ * Module name
41
+ * @var string
42
+ * @access protected
43
+ */
44
+ protected $_module = 'bronto_permissionchecker';
45
+
46
+ /**
47
+ * User descriptive module name
48
+ * @var string
49
+ * @access protected
50
+ */
51
+ protected $_name = 'Bronto File System Permissions Checker Module';
52
+
53
+ // }}}
54
+ }
app/code/community/Bronto/PermissionChecker/Block/Adminhtml/System/Config/Permissionchecker.php ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Permission checker
5
+ *
6
+ * This is the heart of the permission checker that glues together and fires
7
+ * the Chain of responsibility
8
+ *
9
+ * PHP version 5
10
+ *
11
+ * The license text...
12
+ *
13
+ * @category Bronto
14
+ * @package PermissionChecker
15
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
16
+ * @copyright 2012 Atlantic BT
17
+ * @license http://www.atlanticbt.com/ Atlantic BT
18
+ * @version CVS: $Id:$
19
+ * @link <>
20
+ * @see References to other sections (if any)...
21
+ */
22
+
23
+ /**
24
+ * Permission checker
25
+ *
26
+ * This is the heart of the permission checker that glues together and fires
27
+ * the Chain of responsibility
28
+ *
29
+ * @category Bronto
30
+ * @package PermissionChecker
31
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
32
+ * @copyright 2012 Atlantic BT
33
+ * @license http://www.atlanticbt.com/ Atlantic BT
34
+ * @version Release: @package_version@
35
+ * @link <>
36
+ * @see References to other sections (if any)...
37
+ */
38
+ class Bronto_PermissionChecker_Block_Adminhtml_System_Config_Permissionchecker
39
+ extends Mage_Adminhtml_Block_Abstract
40
+ implements Varien_Data_Form_Element_Renderer_Interface
41
+ {
42
+ // {{{ render()
43
+
44
+
45
+ /**
46
+ * Render all files that don't validate to the proper permissions
47
+ *
48
+ * @param Varien_Data_Form_Element_Abstract $element Form element
49
+ *
50
+ * @return string
51
+ * @access public
52
+ */
53
+ public function render(Varien_Data_Form_Element_Abstract $element)
54
+ {
55
+ // Chain of Responsibility
56
+ // each checker looks through its designated area to validate the node we're at.
57
+ $file = Mage::getModel('bronto_permissionchecker/validator_file');
58
+ $dir = Mage::getModel('bronto_permissionchecker/validator_directory', array($file));
59
+ $group = Mage::getModel('bronto_permissionchecker/validator_group', array($dir));
60
+ $owner = Mage::getModel('bronto_permissionchecker/validator_owner', array($group));
61
+
62
+ $checker = Mage::getModel('bronto_permissionchecker/validator_checker', array($owner));
63
+
64
+ $directory = new RecursiveDirectoryIterator(Mage::getBaseDir());
65
+ $filter = new Bronto_PermissionChecker_Model_Validator_Filter_PatternIterator($directory);
66
+ $iterator = new RecursiveIteratorIterator(
67
+ $filter,
68
+ RecursiveIteratorIterator::LEAVES_ONLY,
69
+ RecursiveIteratorIterator::CATCH_GET_CHILD
70
+ );
71
+ $invalidFiles = $checker->validateSettings($iterator);
72
+
73
+ $printer = new Bronto_PermissionChecker_Model_Validator_Printer();
74
+ return $printer->render($invalidFiles);
75
+ }
76
+
77
+ // }}}
78
+ }
app/code/community/Bronto/PermissionChecker/Block/Printer.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Table generator
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package PermissionChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Table generator
22
+ *
23
+ * @category Bronto
24
+ * @package PermissionChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_PermissionChecker_Block_Printer
33
+ extends Mage_Adminhtml_Block_Template
34
+ {
35
+ // {{{ properties
36
+
37
+
38
+ /**
39
+ * Parity bit
40
+ * @var integer
41
+ * @access protected
42
+ */
43
+ protected $_i = 0;
44
+
45
+ // }}}
46
+ // {{{ _construct()
47
+
48
+
49
+ /**
50
+ * psuedo constructor
51
+ *
52
+ * @return void
53
+ * @access public
54
+ */
55
+ public function _construct()
56
+ {
57
+ parent::_construct();
58
+ $this->setTemplate('bronto/permissionchecker/errors.phtml');
59
+ }
60
+
61
+ // }}}
62
+ // {{{ getParity()
63
+
64
+
65
+ /**
66
+ * Get if even or odd
67
+ *
68
+ * @return string
69
+ * @access public
70
+ */
71
+ public function getParity()
72
+ {
73
+ return $this->_i++ % 2 ? 'even' : '';
74
+ }
75
+
76
+ // }}}
77
+ }
app/code/community/Bronto/PermissionChecker/Helper/Data.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Data helper
4
+ *
5
+ * PHP version 5
6
+ *
7
+ * The license text...
8
+ *
9
+ * @category Permissions
10
+ * @package PermissionChecker
11
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
12
+ * @copyright 2012 Atlantic BT
13
+ * @license http://www.atlanticbt.com/ Atlantic BT
14
+ * @version CVS: $Id:$
15
+ * @link <>
16
+ * @see References to other sections (if any)...
17
+ */
18
+
19
+ /**
20
+ * Data helper
21
+ *
22
+ * @category Permissions
23
+ * @package PermissionChecker
24
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
25
+ * @copyright 2012 Atlantic BT
26
+ * @license http://www.atlanticbt.com/ Atlantic BT
27
+ * @version Release: @package_version@
28
+ * @link <>
29
+ * @see References to other sections (if any)...
30
+ */
31
+ class Bronto_PermissionChecker_Helper_Data extends Bronto_Common_Helper_Data
32
+ {
33
+ }
app/code/community/Bronto/PermissionChecker/Model/Validator/Checker.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * file system checker
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package PermissionChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * File system checker
22
+ *
23
+ * This is the client of the Chain of Responsibility
24
+ *
25
+ * @category Bronto
26
+ * @package PermissionChecker
27
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
28
+ * @copyright 2012 Atlantic BT
29
+ * @license http://www.atlanticbt.com/ Atlantic BT
30
+ * @version Release: @package_version@
31
+ * @link <>
32
+ * @see References to other sections (if any)...
33
+ */
34
+ class Bronto_PermissionChecker_Model_Validator_Checker
35
+ extends Bronto_PermissionChecker_Model_Validator_ValidatorAbstract
36
+ {
37
+ // {{{ validateSettings()
38
+
39
+ /**
40
+ * Validate all settings defined in the chain of responsibility
41
+ *
42
+ * This is the client in the chain of responsibility
43
+ *
44
+ * @param RecursiveIteratorIterator $path Path to the beginning of the directory tree
45
+ *
46
+ * @return array All the files which were found that deviate from the expected settings
47
+ * @access public
48
+ */
49
+ public function validateSettings(RecursiveIteratorIterator $path)
50
+ {
51
+ $badFiles = array();
52
+ foreach ($path as $filePath => $fileInfo) {
53
+ $badFiles = $this->validateSetting($fileInfo, $badFiles);
54
+ }
55
+
56
+ return $badFiles;
57
+ }
58
+
59
+ // }}}
60
+ }
app/code/community/Bronto/PermissionChecker/Model/Validator/Directory.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Directory Validator
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package PermissionChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Directory Validator
22
+ *
23
+ * @category Bronto
24
+ * @package PermissionChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_PermissionChecker_Model_Validator_Directory
33
+ extends Bronto_PermissionChecker_Model_Validator_ValidatorAbstract
34
+ {
35
+ // {{{ validateSetting()
36
+
37
+
38
+ /**
39
+ * Validate directory
40
+ *
41
+ * Checks to see if file is directory and if permissions match expected
42
+ *
43
+ * @param SplFileInfo $file File to check
44
+ * @param array $badFiles current array of bad files to report
45
+ *
46
+ * @return array
47
+ * @access public
48
+ */
49
+ public function validateSetting(SplFileInfo $file, array $badFiles)
50
+ {
51
+ if ($file->isDir()) {
52
+ $filePermission = Mage::getStoreConfig('permission_checker/settings/directories');
53
+ $filePermLen = strlen($filePermission);
54
+ $octalPerms = substr(sprintf('%o', $file->getPerms()), -$filePermLen);
55
+
56
+ if ($octalPerms != $filePermission) {
57
+ $path = substr_replace($file->__toString(), '', 0, strlen(Mage::getBaseDir()) + 1);
58
+ $badFiles[$path]['perms'] = $octalPerms;
59
+ }
60
+ }
61
+ return parent::validateSetting($file, $badFiles);
62
+ }
63
+
64
+ // }}}
65
+ }
app/code/community/Bronto/PermissionChecker/Model/Validator/File.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Validate file permission
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package PermissionChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Validate file permission
22
+ *
23
+ * @category Bronto
24
+ * @package PermissionChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_PermissionChecker_Model_Validator_File
33
+ extends Bronto_PermissionChecker_Model_Validator_ValidatorAbstract
34
+ {
35
+ // {{{ validateSetting()
36
+
37
+
38
+ /**
39
+ * Validate file permissions
40
+ *
41
+ * Checks to see if file permissions match correctly
42
+ *
43
+ * @param SplFileInfo $file File to check
44
+ * @param array $badFiles current array of bad files to report
45
+ *
46
+ * @return array
47
+ * @access public
48
+ */
49
+ public function validateSetting(SplFileInfo $file, array $badFiles)
50
+ {
51
+ if ($file->isFile()) {
52
+ $filePermission = Mage::getStoreConfig('permission_checker/settings/files');
53
+ // This allows us to handle how big a sub string to return
54
+ // which will dynamically account for extra permission bits. i.e. (sticky bits)
55
+ $filePermLen = strlen($filePermission);
56
+ $octalPerms = substr(sprintf('%o', $file->getPerms()), -$filePermLen);
57
+
58
+ if ($octalPerms != $filePermission) {
59
+ $path = substr_replace($file->__toString(), '', 0, strlen(Mage::getBaseDir()) + 1);
60
+ $badFiles[$path]['perms'] = $octalPerms;
61
+ }
62
+ }
63
+ return parent::validateSetting($file, $badFiles);
64
+ }
65
+
66
+ // }}}
67
+ }
app/code/community/Bronto/PermissionChecker/Model/Validator/Filter/PatternIterator.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * File Filter iterator
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package PermissionChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * File Filter iterator
22
+ *
23
+ * @category Bronto
24
+ * @package PermissionChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_PermissionChecker_Model_Validator_Filter_PatternIterator
33
+ extends RecursiveFilterIterator
34
+ {
35
+ // {{{ accept()
36
+
37
+ /**
38
+ * Check file name to see if it matches anything that needs to be filtered
39
+ *
40
+ * @return boolean
41
+ * @access public
42
+ */
43
+ public function accept()
44
+ {
45
+ $exclusions = Mage::getStoreConfig('permission_checker/settings/exclude');
46
+ $exclusions = explode(',', $exclusions);
47
+ $exclusions[] = '.';
48
+ $exclusions[] = '..';
49
+ array_walk($exclusions, create_function('&$val', '$val = trim($val);'));
50
+
51
+ return !in_array($this->current()->getBasename(), $exclusions);
52
+ }
53
+
54
+ // }}}
55
+ }
app/code/community/Bronto/PermissionChecker/Model/Validator/Group.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Validate File Group
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package PermissionChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Validate File Group
22
+ *
23
+ * @category Bronto
24
+ * @package PermissionChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_PermissionChecker_Model_Validator_Group
33
+ extends Bronto_PermissionChecker_Model_Validator_ValidatorAbstract
34
+ {
35
+ // {{{ validateSetting()
36
+
37
+
38
+ /**
39
+ * Validate Group
40
+ *
41
+ * Checks to see if file group setting matches expected
42
+ *
43
+ * @param SplFileInfo $file File to check
44
+ * @param array $badFiles current array of bad files to report
45
+ *
46
+ * @return array
47
+ * @access public
48
+ */
49
+ public function validateSetting(SplFileInfo $file, array $badFiles)
50
+ {
51
+ $targetGroup = Mage::getStoreConfig('permission_checker/settings/group');
52
+ if (!empty($targetGroup)) {
53
+ // Account for name and/or gid
54
+ if (filter_var($targetGroup, FILTER_VALIDATE_INT)) {
55
+ $actualGroup = $file->getGroup();
56
+ } else {
57
+ $group = posix_getgrgid($file->getGroup());
58
+ $actualGroup = $group['name'];
59
+ }
60
+ if ($actualGroup != $targetGroup) {
61
+ $path = substr_replace($file->__toString(), '', 0, strlen(Mage::getBaseDir()) + 1);
62
+ $badFiles[$path]['group'] = $actualGroup;
63
+ }
64
+ }
65
+ return parent::validateSetting($file, $badFiles);
66
+ }
67
+
68
+ // }}}
69
+ }
app/code/community/Bronto/PermissionChecker/Model/Validator/Owner.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * File Owner Validator
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package PermissionChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * File Owner Validator
22
+ *
23
+ * @category Bronto
24
+ * @package PermissionChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_PermissionChecker_Model_Validator_Owner
33
+ extends Bronto_PermissionChecker_Model_Validator_ValidatorAbstract
34
+ {
35
+ // {{{ validateSetting()
36
+
37
+
38
+ /**
39
+ * Validate Owner
40
+ *
41
+ * Checks to see if file owner setting matches expected
42
+ *
43
+ * @param SplFileInfo $file File to check
44
+ * @param array $badFiles current array of bad files to report
45
+ *
46
+ * @return array
47
+ * @access public
48
+ */
49
+ public function validateSetting(SplFileInfo $file, array $badFiles)
50
+ {
51
+ $targetOwner = Mage::getStoreConfig('permission_checker/settings/owner');
52
+ if (!empty($targetOwner)) {
53
+ // Account for name and/or gid
54
+ if (filter_var($targetGroup, FILTER_VALIDATE_INT)) {
55
+ $actualOwner = $file->getOwner();
56
+ } else {
57
+ $owner = posix_getpwuid($file->getOwner());
58
+ $actualOwner = $owner['name'];
59
+ }
60
+ if ($actualOwner != $targetOwner) {
61
+ $path = substr_replace($file->__toString(), '', 0, strlen(Mage::getBaseDir()) + 1);
62
+ $badFiles[$path]['owner'] = $actualOwner;
63
+ }
64
+ }
65
+ return parent::validateSetting($file, $badFiles);
66
+ }
67
+
68
+ // }}}
69
+ }
app/code/community/Bronto/PermissionChecker/Model/Validator/Printer.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Render the block view
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package PermissionChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Render the block view
22
+ *
23
+ * @category Bronto
24
+ * @package PermissionChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_PermissionChecker_Model_Validator_Printer
33
+ {
34
+ // {{{ render()
35
+
36
+
37
+ /**
38
+ * Render block view
39
+ *
40
+ * @param array $errors bad files to print
41
+ *
42
+ * @return string
43
+ * @access public
44
+ */
45
+ public function render(array $errors)
46
+ {
47
+ $block = Mage::app()->getLayout()->createBlock('bronto_permissionchecker/printer');
48
+ $block->setErrors($errors);
49
+ return $block->toHtml();
50
+ }
51
+
52
+ // }}}
53
+ }
app/code/community/Bronto/PermissionChecker/Model/Validator/ValidatorAbstract.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Abstracted validator
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package PermissionChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Abstracted validator
22
+ *
23
+ * @category Bronto
24
+ * @package PermissionChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ abstract class Bronto_PermissionChecker_Model_Validator_ValidatorAbstract
33
+ extends Mage_Core_Model_Abstract
34
+ implements Bronto_PermissionChecker_Model_Validator_ValidatorInterface
35
+ {
36
+ // {{{ properties
37
+
38
+
39
+ /**
40
+ * Link List
41
+ *
42
+ * This is the pointer to the next node in the link list
43
+ * @var object
44
+ * @access protected
45
+ */
46
+ protected $_nextHandler = NULL;
47
+
48
+ // }}}
49
+ // {{{ _construct()
50
+
51
+
52
+ /**
53
+ * pseudo constructor
54
+ *
55
+ * @return void
56
+ * @access public
57
+ */
58
+ public function _construct()
59
+ {
60
+ if (isset($this->_data[0])) {
61
+ $this->_nextHandler = $this->_data[0];
62
+ }
63
+ }
64
+
65
+ // }}}
66
+ // {{{ validateSetting()
67
+
68
+
69
+ /**
70
+ * Validate the settings
71
+ *
72
+ * If there are no more links in the list, then return the growing
73
+ * array of bad files to report on. Else call to the next validatore to
74
+ * check the node
75
+ *
76
+ * @param SplFileInfo $file File to validate
77
+ * @param array $badFiles existing bad files to report on
78
+ *
79
+ * @return array
80
+ * @access public
81
+ */
82
+ public function validateSetting(SplFileInfo $file, array $badFiles)
83
+ {
84
+ if (!is_null($this->_nextHandler)) {
85
+ return $this->_nextHandler->validateSetting($file, $badFiles);
86
+ } else {
87
+ return $badFiles;
88
+ }
89
+ }
90
+
91
+ // }}}
92
+ }
app/code/community/Bronto/PermissionChecker/Model/Validator/ValidatorInterface.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Validator interface
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package PermissionChecker
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Validator interface
22
+ *
23
+ * @category Bronto
24
+ * @package PermissionChecker
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ interface Bronto_PermissionChecker_Model_Validator_ValidatorInterface
33
+ {
34
+ // {{{ validateSetting()
35
+
36
+
37
+ /**
38
+ * Validate business logic for chain of responsibility nodes
39
+ *
40
+ * @param SplFileInfo $file File node to check
41
+ * @param array $badFiles existing bad files to report on
42
+ *
43
+ * @access public
44
+ */
45
+ public function validateSetting(SplFileInfo $file, array $badFiles);
46
+
47
+ // }}}
48
+ }
app/code/community/Bronto/PermissionChecker/Test/Config/Config.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_PermissionChecker_Test_Config_Config
3
+ extends EcomDev_PHPUnit_Test_Case_Config
4
+ {
5
+ public function blocksProvider()
6
+ {
7
+ return array(
8
+ array('bronto_permissionchecker/printer', 'Bronto_PermissionChecker_Block_Printer'),
9
+ array('bronto_permissionchecker/adminhtml_system_config_about', 'Bronto_PermissionChecker_Block_Adminhtml_System_Config_About'),
10
+ array('bronto_permissionchecker/adminhtml_system_config_permissionchecker', 'Bronto_PermissionChecker_Block_Adminhtml_System_Config_Permissionchecker'),
11
+ );
12
+ }
13
+
14
+ public function resourceModelProvider()
15
+ {
16
+ return array();
17
+ }
18
+
19
+ public function modelsProvider()
20
+ {
21
+ return array(
22
+ array('bronto_permissionchecker/validator_checker', 'Bronto_PermissionChecker_Model_Validator_Checker'),
23
+ array('bronto_permissionchecker/validator_directory', 'Bronto_PermissionChecker_Model_Validator_Directory'),
24
+ array('bronto_permissionchecker/validator_file', 'Bronto_PermissionChecker_Model_Validator_File'),
25
+ array('bronto_permissionchecker/validator_group', 'Bronto_PermissionChecker_Model_Validator_Group'),
26
+ array('bronto_permissionchecker/validator_owner', 'Bronto_PermissionChecker_Model_Validator_Owner'),
27
+ array('bronto_permissionchecker/validator_printer', 'Bronto_PermissionChecker_Model_Validator_Printer'),
28
+ array('bronto_permissionchecker/validator_validatorabstract', 'Bronto_PermissionChecker_Model_Validator_Validatorabstract'),
29
+ array('bronto_permissionchecker/validator_validatorinterface', 'Bronto_PermissionChecker_Model_Validator_Validatorinterface'),
30
+ array('bronto_permissionchecker/validator_filter_patterniterator', 'Bronto_PermissionChecker_Model_Validator_Filter_Patterniterator'),
31
+ );
32
+ }
33
+
34
+ public function helpersProvider()
35
+ {
36
+ return array(
37
+ array('bronto_permissionchecker/data', 'Bronto_PermissionChecker_Helper_Data'),
38
+ );
39
+ }
40
+
41
+ public function observersProvider()
42
+ {
43
+ return array();
44
+ }
45
+
46
+ public function definedLayoutFilesProvider()
47
+ {
48
+ return array();
49
+ }
50
+
51
+ public function themeLayoutFilesExistProvider()
52
+ {
53
+ return array();
54
+ }
55
+
56
+ public function dependsProvider()
57
+ {
58
+ return array();
59
+ }
60
+
61
+ /**
62
+ * @test
63
+ * @group amd
64
+ * @group config
65
+ */
66
+ public function assertPermissionCheckerModuleVersionGreaterThanOrEquals()
67
+ {
68
+ $this->assertModuleVersionGreaterThanOrEquals('0.1.0');
69
+ }
70
+
71
+ /**
72
+ * @test
73
+ * @group amd
74
+ * @group config
75
+ */
76
+ public function assertPermissionCheckerModuleInCommunityCodePool()
77
+ {
78
+ $this->assertModuleCodePool('community');
79
+ }
80
+
81
+ /**
82
+ * test
83
+ * @group amd
84
+ * @group config
85
+ * @dataProvider dependsProvider
86
+ */
87
+ public function assertPermissionCheckerModuleDepends(
88
+ $requiredModuleName
89
+ ) {
90
+ $this->assertModuleDepends($requiredModuleName);
91
+ }
92
+
93
+ /**
94
+ * @test
95
+ * @group amd
96
+ * @group config
97
+ * @dataProvider modelsProvider
98
+ */
99
+ public function assertPermissionCheckerModelAliases(
100
+ $classAlias,
101
+ $expectedClassName
102
+ ) {
103
+ $this->assertModelAlias($classAlias, $expectedClassName);
104
+ }
105
+
106
+ /**
107
+ * test
108
+ * @group amd
109
+ * @group config
110
+ * @dataProvider resourceModelProvider
111
+ */
112
+ public function assertPermissionCheckerResourceModelAliases(
113
+ $classAlias,
114
+ $expectedClassName
115
+ ) {
116
+ $this->assertResourceModelAlias($classAlias, $expectedClassName);
117
+ }
118
+
119
+ /**
120
+ * @test
121
+ * @group amd
122
+ * @group config
123
+ * @dataProvider blocksProvider
124
+ */
125
+ public function assertPermissionCheckerBlockAliases(
126
+ $classAlias,
127
+ $expectedClassName
128
+ ) {
129
+ $this->assertBlockAlias($classAlias, $expectedClassName);
130
+ }
131
+
132
+ /**
133
+ * @test
134
+ * @group amd
135
+ * @group config
136
+ * @dataProvider helpersProvider
137
+ */
138
+ public function assertPermissionCheckerHelperAliases(
139
+ $classAlias,
140
+ $expectedClassName
141
+ ) {
142
+ $this->assertHelperAlias($classAlias, $expectedClassName);
143
+ }
144
+
145
+ /**
146
+ * test
147
+ * @group amd
148
+ * @group config
149
+ * @dataProvider observersProvider
150
+ */
151
+ function assertPermissionCheckerEventObserverDefined (
152
+ $area,
153
+ $eventName,
154
+ $observerClassAlias,
155
+ $observerMethod
156
+ ) {
157
+ $this->assertEventObserverDefined(
158
+ $area,
159
+ $eventName,
160
+ $observerClassAlias,
161
+ $observerMethod
162
+ );
163
+ }
164
+
165
+ /**
166
+ * test
167
+ * @group amd
168
+ * @group config
169
+ * @dataProvider definedLayoutFilesProvider
170
+ */
171
+ public function assertPermissionCheckerLayoutFileDefined (
172
+ $area,
173
+ $expectedFileName
174
+ ) {
175
+ $this->assertLayoutFileDefined($area, $expectedFileName);
176
+ }
177
+
178
+ /**
179
+ * test
180
+ * @group amd
181
+ * @group config
182
+ * @dataProvider themeLayoutFilesExistProvider
183
+ */
184
+ public function assertPermissionCheckerLayoutFileExistsInTheme (
185
+ $area,
186
+ $filename,
187
+ $theme,
188
+ $designPackage
189
+ ) {
190
+ $this->assertLayoutFileExistsInTheme(
191
+ $area,
192
+ $filename,
193
+ $theme,
194
+ $designPackage
195
+ );
196
+ }
197
+ }
app/code/community/Bronto/PermissionChecker/etc/adminhtml.xml ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * @category Bronto
5
+ * @package PermissionChecker
6
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
7
+ * @copyright 2012 Atlantic BT
8
+ * @license http://www.atlanticbt.com/ Atlantic BT
9
+ */
10
+ -->
11
+ <config>
12
+ <acl>
13
+ <resources>
14
+ <admin>
15
+ <children>
16
+ <system>
17
+ <children>
18
+ <config>
19
+ <children>
20
+ <permission_checker translate="title" module="bronto_permissionchecker">
21
+ <title>Permission Checker</title>
22
+ <sort_order>10</sort_order>
23
+ </permission_checker>
24
+ </children>
25
+ </config>
26
+ </children>
27
+ </system>
28
+ </children>
29
+ </admin>
30
+ </resources>
31
+ </acl>
32
+ </config>
app/code/community/Bronto/PermissionChecker/etc/config.xml ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * @category Bronto
5
+ * @package PermissionChecker
6
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
7
+ * @copyright 2012 Atlantic BT
8
+ * @license http://www.atlanticbt.com/ Atlantic BT
9
+ */
10
+ -->
11
+ <config>
12
+ <modules>
13
+ <Bronto_PermissionChecker>
14
+ <version>0.1.0</version>
15
+ </Bronto_PermissionChecker>
16
+ </modules>
17
+
18
+ <global>
19
+ <blocks>
20
+ <bronto_permissionchecker>
21
+ <class>Bronto_PermissionChecker_Block</class>
22
+ </bronto_permissionchecker>
23
+ </blocks>
24
+
25
+ <helpers>
26
+ <bronto_permissionchecker>
27
+ <class>Bronto_PermissionChecker_Helper</class>
28
+ </bronto_permissionchecker>
29
+ </helpers>
30
+
31
+ <models>
32
+ <bronto_permissionchecker>
33
+ <class>Bronto_PermissionChecker_Model</class>
34
+ </bronto_permissionchecker>
35
+ </models>
36
+ </global>
37
+ <admin>
38
+ <routers>
39
+ <adminhtml>
40
+ <args>
41
+ <modules>
42
+ <bronto_permissionchecker before="Mage_Adminhtml">Bronto_PermissionChecker_Adminhtml</bronto_permissionchecker>
43
+ </modules>
44
+ </args>
45
+ </adminhtml>
46
+ </routers>
47
+ </admin>
48
+ <phpunit>
49
+ <suite>
50
+ <modules>
51
+ <Bronto_PermissionChecker />
52
+ </modules>
53
+ </suite>
54
+ </phpunit>
55
+ <default>
56
+ <permission_checker>
57
+ <settings>
58
+ <directories>755</directories>
59
+ <files>644</files>
60
+ <exclude>media, var, errors, build, .git, .svn, shell, pkginfo, includes</exclude>
61
+ </settings>
62
+ </permission_checker>
63
+ </default>
64
+ </config>
app/code/community/Bronto/PermissionChecker/etc/system.xml ADDED
@@ -0,0 +1,78 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <permission_checker translate="label" module="core">
5
+ <label>Permission Checker</label>
6
+ <tab>bronto</tab>
7
+ <sort_order>800</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
+ <settings translate="label">
13
+ <label>Settings</label>
14
+ <frontend_type>text</frontend_type>
15
+ <sort_order>1</sort_order>
16
+ <show_in_default>1</show_in_default>
17
+ <show_in_website>1</show_in_website>
18
+ <show_in_store>1</show_in_store>
19
+ <fields>
20
+ <owner translate="label comment">
21
+ <label>Owner</label>
22
+ <comment>Owner to check for, (can be name or uid)</comment>
23
+ <frontend_type>text</frontend_type>
24
+ <sort_order>1</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ </owner>
29
+ <group translate="label comment">
30
+ <label>Group</label>
31
+ <comment>Group to check for, (can be name or gid)</comment>
32
+ <frontend_type>text</frontend_type>
33
+ <sort_order>2</sort_order>
34
+ <show_in_default>1</show_in_default>
35
+ <show_in_website>1</show_in_website>
36
+ <show_in_store>1</show_in_store>
37
+ </group>
38
+ <directories translate="label comment">
39
+ <label>Directories</label>
40
+ <comment>Directory permission to check, standard is 755</comment>
41
+ <frontend_type>text</frontend_type>
42
+ <sort_order>3</sort_order>
43
+ <show_in_default>1</show_in_default>
44
+ <show_in_website>1</show_in_website>
45
+ <show_in_store>1</show_in_store>
46
+ </directories>
47
+ <files translate="label comment">
48
+ <label>Files</label>
49
+ <comment>File permission to check, standard is 644</comment>
50
+ <frontend_type>text</frontend_type>
51
+ <sort_order>4</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
+ </files>
56
+ <exclude translate="label comment">
57
+ <label>Exclude Patterns</label>
58
+ <comment>Nodes to exclude</comment>
59
+ <frontend_type>text</frontend_type>
60
+ <sort_order>5</sort_order>
61
+ <show_in_default>1</show_in_default>
62
+ <show_in_website>1</show_in_website>
63
+ <show_in_store>1</show_in_store>
64
+ </exclude>
65
+ </fields>
66
+ </settings>
67
+ <permissionchecker>
68
+ <frontend_type>text</frontend_type>
69
+ <frontend_model>bronto_permissionchecker/adminhtml_system_config_permissionchecker</frontend_model>
70
+ <sort_order>2</sort_order>
71
+ <show_in_default>1</show_in_default>
72
+ <show_in_website>1</show_in_website>
73
+ <show_in_store>1</show_in_store>
74
+ </permissionchecker>
75
+ </groups>
76
+ </permission_checker>
77
+ </sections>
78
+ </config>
app/code/community/Bronto/Reminder/Block/Adminhtml/Promo/Notice.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_Promo_Notice extends Mage_Adminhtml_Block_Template
9
+ {
10
+ /**
11
+ * Preparing block layout
12
+ *
13
+ * @return Bronto_Reminder_Block_Adminhtml_Promo_Notice
14
+ */
15
+ protected function _prepareLayout()
16
+ {
17
+ if ($salesRule = Mage::registry('current_promo_quote_rule')) {
18
+ $resource = Mage::getResourceModel('bronto_reminder/rule');
19
+ if ($count = $resource->getAssignedRulesCount($salesRule->getId())) {
20
+ $confirm = Mage::helper('bronto_reminder')->__('This rule is assigned to %s automated reminder rule(s). Deleting this rule will automatically unassign it.', $count);
21
+ $block = $this->getLayout()->getBlock('promo_quote_edit');
22
+ if ($block instanceof Mage_Adminhtml_Block_Promo_Quote_Edit) {
23
+ $block->updateButton('delete', 'onclick', 'deleteConfirm(\'' . $confirm . '\', \'' . $block->getDeleteUrl() . '\')');
24
+ }
25
+ }
26
+ }
27
+ return $this;
28
+ }
29
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_Reminder extends Mage_Adminhtml_Block_Widget_Grid_Container
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_controller = 'adminhtml_reminder';
14
+
15
+ /**
16
+ * @var string
17
+ */
18
+ protected $_blockGroup = 'bronto_reminder';
19
+
20
+ public function __construct()
21
+ {
22
+ $this->_headerText = Mage::helper('bronto_reminder')->__('Bronto Reminder Email Rules');
23
+ $this->_addButtonLabel = Mage::helper('bronto_reminder')->__('Add New Rule');
24
+ parent::__construct();
25
+ }
26
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit.php ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_Reminder_Edit extends Mage_Adminhtml_Block_Widget_Form_Container
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_objectId = 'id';
14
+
15
+ /**
16
+ * @var string
17
+ */
18
+ protected $_controller = 'adminhtml_reminder';
19
+
20
+ /**
21
+ * @var string
22
+ */
23
+ protected $_blockGroup = 'bronto_reminder';
24
+
25
+ public function __construct()
26
+ {
27
+ parent::__construct();
28
+ $rule = Mage::registry('current_reminder_rule');
29
+ $this->removeButton('reset');
30
+
31
+ if ($rule) {
32
+ $this->_updateButton('save', 'label', Mage::helper('bronto_reminder')->__('Save'));
33
+ $this->_updateButton('delete', 'label', Mage::helper('bronto_reminder')->__('Delete'));
34
+
35
+ if ($rule->getId()) {
36
+ $confirm = Mage::helper('bronto_reminder')->__('Are you sure you want to match this rule now?');
37
+ $this->_addButton('match_now', array(
38
+ 'label' => Mage::helper('bronto_reminder')->__('Match Now'),
39
+ 'onclick' => "confirmSetLocation('{$confirm}', '{$this->getMatchUrl()}')"
40
+ ), -1);
41
+ if ($limit = Mage::helper('bronto_reminder')->getOneRunLimit()) {
42
+ $confirm .= ' ' . Mage::helper('bronto_reminder')->__('Up to %s customers may receive a reminder email after this action.', $limit);
43
+ }
44
+ $this->_addButton('run_now', array(
45
+ 'label' => Mage::helper('bronto_reminder')->__('Send Now'),
46
+ 'onclick' => "confirmSetLocation('{$confirm}', '{$this->getRunUrl()}')"
47
+ ), -1);
48
+ }
49
+
50
+ $this->_addButton('save_and_continue_edit', array(
51
+ 'class' => 'save',
52
+ 'label' => Mage::helper('bronto_reminder')->__('Save and Continue Edit'),
53
+ 'onclick' => 'editForm.submit($(\'edit_form\').action + \'back/edit/\')',
54
+ ), 3);
55
+ }
56
+ }
57
+
58
+ public function getHeaderText()
59
+ {
60
+ $rule = Mage::registry('current_reminder_rule');
61
+ if ($rule->getRuleId()) {
62
+ return Mage::helper('bronto_reminder')->__("Edit Rule '%s'", $this->htmlEscape($rule->getName()));
63
+ }
64
+ else {
65
+ return Mage::helper('bronto_reminder')->__('New Rule');
66
+ }
67
+ }
68
+
69
+ /**
70
+ * Get url for immidiately run sending process
71
+ *
72
+ * @return string
73
+ */
74
+ public function getRunUrl()
75
+ {
76
+ $rule = Mage::registry('current_reminder_rule');
77
+ return $this->getUrl('*/*/run', array('id' => $rule->getRuleId()));
78
+ }
79
+
80
+ /**
81
+ * Get url for immidiately matching customers
82
+ *
83
+ * @return string
84
+ */
85
+ public function getMatchUrl()
86
+ {
87
+ $rule = Mage::registry('current_reminder_rule');
88
+ return $this->getUrl('*/*/match', array('id' => $rule->getRuleId()));
89
+ }
90
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit/Form.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_Reminder_Edit_Form extends Mage_Adminhtml_Block_Widget_Form
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setId('bronto_reminder_rule_form');
14
+ $this->setTitle(Mage::helper('bronto_reminder')->__('Email Reminder Rule'));
15
+ }
16
+
17
+ protected function _prepareForm()
18
+ {
19
+ $form = new Varien_Data_Form(array('id' => 'edit_form', 'action' => $this->getData('action'), 'method' => 'post'));
20
+ $form->setUseContainer(true);
21
+ $this->setForm($form);
22
+ return parent::_prepareForm();
23
+ }
24
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit/Tab/Bronto.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_Reminder_Edit_Tab_Bronto extends Mage_Adminhtml_Block_Widget_Form
9
+ {
10
+ /**
11
+ * Prepare general properties form
12
+ *
13
+ * @return Bronto_Reminder_Block_Adminhtml_Reminder_Edit_Tab_Bronto
14
+ */
15
+ protected function _prepareForm()
16
+ {
17
+ $form = new Varien_Data_Form();
18
+ $model = Mage::registry('current_reminder_rule');
19
+
20
+ $fieldset = $form->addFieldset('message_fieldset', array(
21
+ 'legend' => Mage::helper('bronto_reminder')->__('Bronto Messages'),
22
+ 'table_class' => 'form-list stores-tree',
23
+ 'comment' => Mage::helper('bronto_reminder')->__('Messages will be sent only for specified store views. Message store view matches the store view customer was registered on.'),
24
+ ));
25
+
26
+ foreach (Mage::app()->getWebsites() as $website) {
27
+ $fieldset->addField("website_message_{$website->getId()}", 'note', array(
28
+ 'label' => $website->getName(),
29
+ 'fieldset_html_class' => 'website',
30
+ ));
31
+ foreach ($website->getGroups() as $group) {
32
+ $stores = $group->getStores();
33
+ if (count($stores) == 0) {
34
+ continue;
35
+ }
36
+ $fieldset->addField("group_message_{$group->getId()}", 'note', array(
37
+ 'label' => $group->getName(),
38
+ 'fieldset_html_class' => 'store-group',
39
+ ));
40
+ foreach ($stores as $store) {
41
+ $token = $store->getConfig(Bronto_Common_Helper_Data::XML_PATH_API_TOKEN);
42
+ $source = Mage::getModel('bronto_common/system_config_source_message');
43
+ // $values = $source->toOptionArray($token);
44
+ $values = Mage::helper('bronto_reminder/message')->getMessagesOptionsArray($store->getId(), $website->getId());
45
+ $fieldset->addField("store_message_{$store->getId()}", 'select', array(
46
+ 'name' => "store_messages[{$store->getId()}]",
47
+ 'required' => false,
48
+ 'label' => $store->getName(),
49
+ 'values' => $values,
50
+ 'fieldset_html_class' => 'store',
51
+ 'disabled' => count($values) == 1 ? true : false,
52
+ ));
53
+ }
54
+ }
55
+ }
56
+
57
+ $form->setValues($model->getData());
58
+ $this->setForm($form);
59
+
60
+ return parent::_prepareForm();
61
+ }
62
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit/Tab/Conditions.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_Reminder_Edit_Tab_Conditions extends Mage_Adminhtml_Block_Widget_Form
9
+ {
10
+ protected function _prepareForm()
11
+ {
12
+ $form = new Varien_Data_Form();
13
+ $model = Mage::registry('current_reminder_rule');
14
+
15
+ $renderer = Mage::getBlockSingleton('adminhtml/widget_form_renderer_fieldset')
16
+ ->setTemplate('promo/fieldset.phtml')
17
+ ->setNewChildUrl($this->getUrl('*/*/newConditionHtml/form/rule_conditions_fieldset'));
18
+ $fieldset = $form->addFieldset('rule_conditions_fieldset', array(
19
+ 'legend' => Mage::helper('bronto_reminder')->__('Conditions'),
20
+ 'comment' => Mage::helper('bronto_reminder')->__('Rule will work only if at least one condition is specified.'),
21
+ ))->setRenderer($renderer);
22
+
23
+ $fieldset->addField('conditions', 'text', array(
24
+ 'name' => 'conditions',
25
+ 'required' => true,
26
+ ))->setRule($model)->setRenderer(Mage::getBlockSingleton('rule/conditions'));
27
+
28
+ $form->setValues($model->getData());
29
+ $this->setForm($form);
30
+
31
+ return parent::_prepareForm();
32
+ }
33
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit/Tab/Customers.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_Reminder_Edit_Tab_Customers extends Mage_Adminhtml_Block_Widget_Grid
9
+ {
10
+ /**
11
+ * Intialize grid
12
+ */
13
+ public function __construct()
14
+ {
15
+ parent::__construct();
16
+ $this->setId('customerGrid');
17
+ $this->setUseAjax(true);
18
+ $this->setDefaultSort('entity_id');
19
+ $this->setDefaultDir('ASC');
20
+ $this->setDefaultFilter(array('grid_is_active' => 1));
21
+ }
22
+
23
+ /**
24
+ * Instantiate and prepare collection
25
+ *
26
+ * @return Bronto_Reminder_Block_Adminhtml_Reminder_Edit_Tab_Customers
27
+ */
28
+ protected function _prepareCollection()
29
+ {
30
+ /* @var $collection Bronto_Reminder_Model_Mysql4_Customer_Collection */
31
+ $collection = Mage::getResourceModel('bronto_reminder/customer_collection');
32
+ $this->setCollection($collection);
33
+
34
+ return parent::_prepareCollection();
35
+ }
36
+
37
+ /**
38
+ * Prepare columns for grid
39
+ *
40
+ * @return Bronto_Reminder_Block_Adminhtml_Reminder_Edit_Tab_Customers
41
+ */
42
+ protected function _prepareColumns()
43
+ {
44
+ $this->addColumn('grid_entity_id', array(
45
+ 'header' => Mage::helper('bronto_reminder')->__('ID'),
46
+ 'align' => 'center',
47
+ 'width' => 50,
48
+ 'index' => 'entity_id',
49
+ 'renderer' => 'bronto_reminder/adminhtml_widget_grid_column_renderer_id'
50
+ ));
51
+
52
+ $this->addColumn('grid_email', array(
53
+ 'header' => Mage::helper('bronto_reminder')->__('Email'),
54
+ 'type' => 'text',
55
+ 'align' => 'left',
56
+ 'index' => 'email',
57
+ 'renderer' => 'bronto_reminder/adminhtml_widget_grid_column_renderer_email'
58
+ ));
59
+
60
+ $this->addColumn('grid_associated_at', array(
61
+ 'header' => Mage::helper('bronto_reminder')->__('Matched At'),
62
+ 'align' => 'left',
63
+ 'width' => 150,
64
+ 'type' => 'datetime',
65
+ 'default' => '--',
66
+ 'index' => 'associated_at'
67
+ ));
68
+
69
+ $this->addColumn('grid_is_active', array(
70
+ 'header' => Mage::helper('bronto_reminder')->__('Thread Active'),
71
+ 'align' => 'left',
72
+ 'type' => 'options',
73
+ 'index' => 'is_active',
74
+ 'options' => array(
75
+ '0' => Mage::helper('bronto_reminder')->__('No'),
76
+ '1' => Mage::helper('bronto_reminder')->__('Yes')
77
+ )
78
+ ));
79
+
80
+ if (class_exists('Mage_SalesRule_Model_Coupon', false)) {
81
+
82
+ $this->addColumn('grid_code', array(
83
+ 'header' => Mage::helper('bronto_reminder')->__('Coupon'),
84
+ 'align' => 'left',
85
+ 'default' => Mage::helper('bronto_reminder')->__('N/A'),
86
+ 'index' => 'code'
87
+ ));
88
+
89
+ $this->addColumn('grid_usage_limit', array(
90
+ 'header' => Mage::helper('bronto_reminder')->__('Coupon Usage Limit'),
91
+ 'align' => 'left',
92
+ 'default' => '0',
93
+ 'index' => 'usage_limit'
94
+ ));
95
+
96
+ $this->addColumn('grid_usage_per_customer', array(
97
+ 'header' => Mage::helper('bronto_reminder')->__('Coupon Usage per Customer'),
98
+ 'align' => 'left',
99
+ 'default' => '0',
100
+ 'index' => 'usage_per_customer'
101
+ ));
102
+
103
+ }
104
+
105
+ $this->addColumn('grid_emails_sent', array(
106
+ 'header' => Mage::helper('bronto_reminder')->__('Emails Sent'),
107
+ 'align' => 'left',
108
+ 'default' => '0',
109
+ 'index' => 'emails_sent'
110
+ ));
111
+
112
+ $this->addColumn('grid_emails_failed', array(
113
+ 'header' => Mage::helper('bronto_reminder')->__('Emails Failed'),
114
+ 'align' => 'left',
115
+ 'index' => 'emails_failed'
116
+ ));
117
+
118
+ $this->addColumn('grid_last_sent', array(
119
+ 'header' => Mage::helper('bronto_reminder')->__('Last Sent At'),
120
+ 'align' => 'left',
121
+ 'width' => 150,
122
+ 'type' => 'datetime',
123
+ 'default' => '--',
124
+ 'index' => 'last_sent'
125
+ ));
126
+
127
+ return parent::_prepareColumns();
128
+ }
129
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit/Tab/General.php ADDED
@@ -0,0 +1,136 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_Reminder_Edit_Tab_General extends Mage_Adminhtml_Block_Widget_Form
9
+ {
10
+ protected function _prepareForm()
11
+ {
12
+ $form = new Varien_Data_Form();
13
+ $model = Mage::registry('current_reminder_rule');
14
+
15
+ $fieldset = $form->addFieldset('base_fieldset', array(
16
+ 'legend' => Mage::helper('bronto_reminder')->__('General'),
17
+ 'comment' => Mage::helper('bronto_reminder')->__('Reminder emails may promote a shopping cart price rule with or without coupon. If a shopping cart price rule defines an auto-generated coupon, this reminder rule will generate a random coupon code for each customer.'),
18
+ ));
19
+
20
+ if ($model->getId()) {
21
+ $fieldset->addField('rule_id', 'hidden', array(
22
+ 'name' => 'rule_id',
23
+ ));
24
+ }
25
+
26
+ $fieldset->addField('name', 'text', array(
27
+ 'name' => 'name',
28
+ 'label' => Mage::helper('bronto_reminder')->__('Rule Name'),
29
+ 'required' => true,
30
+ ));
31
+
32
+ $fieldset->addField('description', 'textarea', array(
33
+ 'name' => 'description',
34
+ 'label' => Mage::helper('bronto_reminder')->__('Description'),
35
+ 'style' => 'width: 98%; height: 100px;',
36
+ ));
37
+
38
+ if (class_exists('Mage_Adminhtml_Block_Promo_Widget_Chooser', false)) {
39
+
40
+ $field = $fieldset->addField('salesrule_id', 'note', array(
41
+ 'name' => 'salesrule_id',
42
+ 'label' => Mage::helper('bronto_reminder')->__('Shopping Cart Price Rule'),
43
+ 'class' => 'widget-option',
44
+ 'value' => $model->getSalesruleId(),
45
+ 'note' => Mage::helper('bronto_reminder')->__('Promotion rule this reminder will advertise.'),
46
+ ));
47
+
48
+ $model->unsSalesruleId();
49
+ $helperBlock = $this->getLayout()->createBlock('adminhtml/promo_widget_chooser');
50
+
51
+ if ($helperBlock instanceof Varien_Object) {
52
+ $helperBlock->setConfig($this->getChooserConfig())
53
+ ->setFieldsetId($fieldset->getId())
54
+ ->setTranslationHelper(Mage::helper('salesrule'))
55
+ ->prepareElementHtml($field);
56
+ }
57
+
58
+ }
59
+
60
+ if (!Mage::app()->isSingleStoreMode()) {
61
+ $fieldset->addField('website_ids','multiselect',array(
62
+ 'name' => 'website_ids',
63
+ 'required' => true,
64
+ 'label' => Mage::helper('newsletter')->__('Assigned to Websites'),
65
+ 'values' => Mage::getSingleton('adminhtml/system_store')->getWebsiteValuesForForm(),
66
+ 'value' => $model->getWebsiteIds()
67
+ ));
68
+ }
69
+
70
+ $fieldset->addField('is_active', 'select', array(
71
+ 'label' => Mage::helper('bronto_reminder')->__('Status'),
72
+ 'name' => 'is_active',
73
+ 'required' => true,
74
+ 'options' => array(
75
+ '1' => Mage::helper('bronto_reminder')->__('Active'),
76
+ '0' => Mage::helper('bronto_reminder')->__('Inactive'),
77
+ ),
78
+ ));
79
+
80
+ if (!$model->getId()) {
81
+ $model->setData('is_active', '1');
82
+ }
83
+
84
+ $dateFormatIso = Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT);
85
+
86
+ $fieldset->addField('active_from', 'date', array(
87
+ 'name' => 'active_from',
88
+ 'label' => Mage::helper('bronto_reminder')->__('Active From'),
89
+ 'title' => Mage::helper('bronto_reminder')->__('Active From'),
90
+ 'image' => $this->getSkinUrl('images/grid-cal.gif'),
91
+ 'input_format' => Varien_Date::DATE_INTERNAL_FORMAT,
92
+ 'format' => $dateFormatIso
93
+ ));
94
+
95
+ $fieldset->addField('active_to', 'date', array(
96
+ 'name' => 'active_to',
97
+ 'label' => Mage::helper('bronto_reminder')->__('Active To'),
98
+ 'title' => Mage::helper('bronto_reminder')->__('Active To'),
99
+ 'image' => $this->getSkinUrl('images/grid-cal.gif'),
100
+ 'input_format' => Varien_Date::DATE_INTERNAL_FORMAT,
101
+ 'format' => $dateFormatIso
102
+ ));
103
+
104
+ $subfieldset = $form->addFieldset('sub_fieldset', array(
105
+ 'legend' => Mage::helper('bronto_reminder')->__('Repeat Schedule'),
106
+ 'comment' => '
107
+ By default, a rule will only send a Reminder Email to a customer once.
108
+ To allow a rule to re-send a message (as long as the conditions still match) to a customer, you must configure the Repeat Schedule.
109
+ ',
110
+ ));
111
+
112
+ $subfieldset->addField('schedule', 'text', array(
113
+ 'name' => 'schedule',
114
+ 'label' => Mage::helper('bronto_reminder')->__('Schedule (Days)'),
115
+ 'note' => '
116
+ Enter days, comma-separated.<br/>
117
+ <strong>Examples:</strong><br/>
118
+ "<span style="font-family:monospace">0</span>": Message to be sent again the same day.<br/>
119
+ "<span style="font-family:monospace">1</span>": Message to be sent again the next day.<br/>
120
+ ',
121
+ ));
122
+
123
+ $form->setValues($model->getData());
124
+ $this->setForm($form);
125
+
126
+ return parent::_prepareForm();
127
+ }
128
+
129
+ public function getChooserConfig()
130
+ {
131
+ return array(
132
+ 'button' => array('open'=>'Select Rule...'),
133
+ 'type' => 'adminhtml/promo_widget_chooser_rule'
134
+ );
135
+ }
136
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Edit/Tabs.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_Reminder_Edit_Tabs extends Mage_Adminhtml_Block_Widget_Tabs
9
+ {
10
+ /**
11
+ * Intialize form
12
+ *
13
+ * @return void
14
+ */
15
+ public function __construct()
16
+ {
17
+ parent::__construct();
18
+ $this->setId('bronto_reminder_rule_tabs');
19
+ $this->setDestElementId('edit_form');
20
+ $this->setTitle(Mage::helper('bronto_reminder')->__('Email Reminder Rule'));
21
+ }
22
+
23
+ /**
24
+ * Add tab sections
25
+ *
26
+ * @return Bronto_Reminder_Block_Adminhtml_Reminder_Edit_Tabs
27
+ */
28
+ protected function _beforeToHtml()
29
+ {
30
+ $this->addTab('general_section', array(
31
+ 'label' => Mage::helper('bronto_reminder')->__('Rule Information'),
32
+ 'content' => $this->getLayout()->createBlock('bronto_reminder/adminhtml_reminder_edit_tab_general')->toHtml(),
33
+ ));
34
+
35
+ $this->addTab('conditions_section', array(
36
+ 'label' => Mage::helper('bronto_reminder')->__('Conditions'),
37
+ 'content' => $this->getLayout()->createBlock('bronto_reminder/adminhtml_reminder_edit_tab_conditions')->toHtml()
38
+ ));
39
+
40
+ $this->addTab('bronto_section', array(
41
+ 'label' => Mage::helper('bronto_reminder')->__('Bronto Settings'),
42
+ 'content' => $this->getLayout()->createBlock('bronto_reminder/adminhtml_reminder_edit_tab_bronto')->toHtml()
43
+ ));
44
+
45
+ $rule = Mage::registry('current_reminder_rule');
46
+ if ($rule && $rule->getId()) {
47
+ $this->addTab('matched_customers', array(
48
+ 'label' => Mage::helper('bronto_reminder')->__('Matched Customers'),
49
+ 'url' => $this->getUrl('*/*/customerGrid', array('rule_id' => $rule->getId())),
50
+ 'class' => 'ajax'
51
+ ));
52
+ }
53
+
54
+ return parent::_beforeToHtml();
55
+ }
56
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/Reminder/Grid.php ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_Reminder_Grid extends Mage_Adminhtml_Block_Widget_Grid
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setId('reminderGrid');
14
+ $this->setIdFieldName('rule_id');
15
+ $this->setDefaultSort('rule_id', 'asc');
16
+ }
17
+
18
+ protected function _prepareCollection()
19
+ {
20
+ $collection = Mage::getModel('bronto_reminder/rule')->getCollection();
21
+ $collection->addWebsitesToResult();
22
+ $this->setCollection($collection);
23
+ return parent::_prepareCollection();
24
+ }
25
+
26
+ protected function _prepareColumns()
27
+ {
28
+ $this->addColumn('rule_id', array(
29
+ 'header' => Mage::helper('bronto_reminder')->__('ID'),
30
+ 'align' => 'right',
31
+ 'width' => '50px',
32
+ 'index' => 'rule_id',
33
+ ));
34
+
35
+ $this->addColumn('name', array(
36
+ 'header' => Mage::helper('bronto_reminder')->__('Rule Name'),
37
+ 'align' => 'left',
38
+ 'index' => 'name',
39
+ ));
40
+
41
+ $this->addColumn('from_date', array(
42
+ 'header' => Mage::helper('bronto_reminder')->__('Active From'),
43
+ 'align' => 'left',
44
+ 'width' => '120px',
45
+ 'type' => 'date',
46
+ 'default' => '--',
47
+ 'index' => 'active_from',
48
+ ));
49
+
50
+ $this->addColumn('to_date', array(
51
+ 'header' => Mage::helper('bronto_reminder')->__('Active To'),
52
+ 'align' => 'left',
53
+ 'width' => '120px',
54
+ 'type' => 'date',
55
+ 'default' => '--',
56
+ 'index' => 'active_to',
57
+ ));
58
+
59
+ $this->addColumn('is_active', array(
60
+ 'header' => Mage::helper('bronto_reminder')->__('Status'),
61
+ 'align' => 'left',
62
+ 'width' => '80px',
63
+ 'index' => 'is_active',
64
+ 'type' => 'options',
65
+ 'options' => array(
66
+ 1 => 'Active',
67
+ 0 => 'Inactive',
68
+ ),
69
+ ));
70
+
71
+ if (!Mage::app()->isSingleStoreMode()) {
72
+ $this->addColumn('rule_website', array(
73
+ 'header' => Mage::helper('bronto_reminder')->__('Website'),
74
+ 'align' =>'left',
75
+ 'index' => 'website_ids',
76
+ 'type' => 'options',
77
+ 'sortable' => false,
78
+ 'options' => Mage::getSingleton('adminhtml/system_store')->getWebsiteOptionHash(),
79
+ 'width' => 200,
80
+ ));
81
+ }
82
+ return parent::_prepareColumns();
83
+ }
84
+
85
+ /**
86
+ * Return url for current row
87
+ *
88
+ * @param Bronto_Reminder_Model_Rule $row
89
+ * @return string
90
+ */
91
+ public function getRowUrl($row)
92
+ {
93
+ return $this->getUrl('*/*/edit', array('id' => $row->getRuleId()));
94
+ }
95
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/System/Config/About.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_System_Config_About extends Bronto_Common_Block_Adminhtml_System_Config_About
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_module = 'bronto_reminder';
14
+
15
+ /**
16
+ * @var string
17
+ */
18
+ protected $_name = 'Bronto Reminder/Follow Up Email Module';
19
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/System/Config/Cron.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_System_Config_Cron extends Bronto_Common_Block_Adminhtml_System_Config_Cron
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_jobCode = 'bronto_reminder_send_notification';
14
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/Widget/Grid/Column/Renderer/Email.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_Widget_Grid_Column_Renderer_Email extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
9
+ {
10
+ /**
11
+ * Render customer email as mailto link
12
+ *
13
+ * @param Varien_Object $row
14
+ * @return string
15
+ */
16
+ protected function _getValue(Varien_Object $row)
17
+ {
18
+ $customerEmail = $this->htmlEscape($row->getData($this->getColumn()->getIndex()));
19
+ return '<a href="mailto:' . $customerEmail . '">' . $this->htmlEscape($customerEmail) . '</a>';
20
+ }
21
+ }
app/code/community/Bronto/Reminder/Block/Adminhtml/Widget/Grid/Column/Renderer/Id.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Block_Adminhtml_Widget_Grid_Column_Renderer_Id extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
9
+ {
10
+ /**
11
+ * Render customer id linked to its account edit page
12
+ *
13
+ * @param Varien_Object $row
14
+ * @return string
15
+ */
16
+ protected function _getValue(Varien_Object $row)
17
+ {
18
+ $customerId = $this->htmlEscape($row->getData($this->getColumn()->getIndex()));
19
+ return '<a href="' . Mage::getSingleton('adminhtml/url')->getUrl('*/customer/edit',
20
+ array('id' => $customerId)) . '">' . $customerId . '</a>';
21
+ }
22
+ }
app/code/community/Bronto/Reminder/Helper/Contact.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Helper_Contact extends Bronto_Common_Helper_Contact
9
+ {
10
+ /**
11
+ * Retrieve helper module name
12
+ *
13
+ * @return string
14
+ */
15
+ protected function _getModuleName()
16
+ {
17
+ return 'Bronto_Reminder';
18
+ }
19
+
20
+ /**
21
+ * @param string $email
22
+ * @return Bronto_Api_Contact_Row
23
+ */
24
+ public function getContactByEmail($email, $customSource = 'bronto_reminder', $store = null)
25
+ {
26
+ return parent::getContactByEmail($email, $customSource, $store);
27
+ }
28
+ }
app/code/community/Bronto/Reminder/Helper/Data.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Helper_Data extends Bronto_Common_Helper_Data implements Bronto_Common_Helper_DataInterface
9
+ {
10
+ const XML_PATH_ENABLED = 'bronto_reminder/settings/enabled';
11
+ const XML_PATH_INTERVAL = 'bronto_reminder/settings/interval';
12
+ const XML_PATH_SEND_LIMIT = 'bronto_reminder/settings/limit';
13
+ const XML_PATH_EMAIL_IDENTITY = 'bronto_reminder/settings/identity';
14
+ const XML_PATH_EMAIL_THRESHOLD = 'bronto_reminder/settings/threshold';
15
+
16
+ /**
17
+ * Retrieve helper module name
18
+ *
19
+ * @return string
20
+ */
21
+ protected function _getModuleName()
22
+ {
23
+ return 'Bronto_Reminder';
24
+ }
25
+
26
+ /**
27
+ * @return bool
28
+ */
29
+ public function isEnabled()
30
+ {
31
+ return (bool) Mage::getStoreConfig(self::XML_PATH_ENABLED);
32
+ }
33
+
34
+ /**
35
+ * @param string $path
36
+ *
37
+ * @return bool
38
+ */
39
+ public function disableModule($scope = 'default', $scopeId = 0)
40
+ {
41
+ return $this->_disableModule(self::XML_PATH_ENABLED, $scope, $scopeId);
42
+ }
43
+
44
+ /**
45
+ * @return int
46
+ */
47
+ public function getCronInterval()
48
+ {
49
+ return (int) Mage::getStoreConfig(self::XML_PATH_INTERVAL);
50
+ }
51
+
52
+ /**
53
+ * @return int
54
+ */
55
+ public function getOneRunLimit()
56
+ {
57
+ return (int) Mage::getStoreConfig(self::XML_PATH_SEND_LIMIT);
58
+ }
59
+
60
+ /**
61
+ * @return string
62
+ */
63
+ public function getEmailIdentity()
64
+ {
65
+ return (string) Mage::getStoreConfig(self::XML_PATH_EMAIL_IDENTITY);
66
+ }
67
+
68
+ /**
69
+ * @return int
70
+ */
71
+ public function getSendFailureThreshold()
72
+ {
73
+ if (Mage::helper('bronto_common')->isTestModeEnabled()) {
74
+ return 0;
75
+ }
76
+
77
+ return (int) Mage::getStoreConfig(self::XML_PATH_EMAIL_THRESHOLD);
78
+ }
79
+ }
app/code/community/Bronto/Reminder/Helper/Message.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Helper_Message extends Bronto_Common_Helper_Message
9
+ {
10
+ /**
11
+ * Retrieve helper module name
12
+ *
13
+ * @return string
14
+ */
15
+ protected function _getModuleName()
16
+ {
17
+ return 'Bronto_Reminder';
18
+ }
19
+ }
app/code/community/Bronto/Reminder/Model/Condition/Abstract.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Condition_Abstract extends Mage_Rule_Model_Condition_Abstract
9
+ {
10
+ /**
11
+ * Customize default operator input by type mapper for some types
12
+ * @return array
13
+ */
14
+ public function getDefaultOperatorInputByType()
15
+ {
16
+ if (null === $this->_defaultOperatorInputByType) {
17
+ parent::getDefaultOperatorInputByType();
18
+ $this->_defaultOperatorInputByType['numeric'] = array('==', '!=', '>=', '>', '<=', '<');
19
+ $this->_defaultOperatorInputByType['string'] = array('==', '!=', '{}', '!{}');
20
+ }
21
+ return $this->_defaultOperatorInputByType;
22
+ }
23
+
24
+ /**
25
+ * Get condition combine resource model
26
+ *
27
+ * @return Bronto_Reminder_Model_Mysql4_Rule
28
+ */
29
+ public function getResource()
30
+ {
31
+ return Mage::getResourceSingleton('bronto_reminder/rule');
32
+ }
33
+
34
+ /**
35
+ * Generate customer condition string
36
+ *
37
+ * @param $customer
38
+ * @param string $fieldName
39
+ * @return string
40
+ */
41
+ protected function _createCustomerFilter($customer, $fieldName)
42
+ {
43
+ return "{$fieldName} = root.entity_id";
44
+ }
45
+
46
+ /**
47
+ * Limit select by website with joining to store table
48
+ *
49
+ * @param Zend_Db_Select $select
50
+ * @param int | Zend_Db_Expr $website
51
+ * @param string $storeIdField
52
+ * @return Bronto_Reminder_Model_Condition_Abstract
53
+ */
54
+ protected function _limitByStoreWebsite(Zend_Db_Select $select, $website, $storeIdField)
55
+ {
56
+ $storeTable = $this->getResource()->getTable('core/store');
57
+ $select->join(array('store' => $storeTable), $storeIdField . '=store.store_id', array())
58
+ ->where('store.website_id=?', $website);
59
+ return $this;
60
+ }
61
+ }
app/code/community/Bronto/Reminder/Model/Condition/Combine/Abstract.php ADDED
@@ -0,0 +1,188 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ abstract class Bronto_Reminder_Model_Condition_Combine_Abstract extends Mage_Rule_Model_Condition_Combine
9
+ {
10
+ /**
11
+ * Customize default operator input by type mapper for some types
12
+ *
13
+ * @return array
14
+ */
15
+ public function getDefaultOperatorInputByType()
16
+ {
17
+ if (null === $this->_defaultOperatorInputByType) {
18
+ parent::getDefaultOperatorInputByType();
19
+ $this->_defaultOperatorInputByType['numeric'] = array('==', '!=', '>=', '>', '<=', '<');
20
+ $this->_defaultOperatorInputByType['string'] = array('==', '!=', '{}', '!{}');
21
+ }
22
+ return $this->_defaultOperatorInputByType;
23
+ }
24
+
25
+ /**
26
+ * Add operator when loading array
27
+ *
28
+ * @param array $arr
29
+ * @param string $key
30
+ * @return Bronto_Reminder_Model_Rule_Condition_Combine
31
+ */
32
+ public function loadArray($arr, $key = 'conditions')
33
+ {
34
+ if (isset($arr['operator'])) {
35
+ $this->setOperator($arr['operator']);
36
+ }
37
+
38
+ if (isset($arr['attribute'])) {
39
+ $this->setAttribute($arr['attribute']);
40
+ }
41
+
42
+ return parent::loadArray($arr, $key);
43
+ }
44
+
45
+ /**
46
+ * Get condition combine resource model
47
+ *
48
+ * @return Bronto_Reminder_Model_Mysql4_Rule
49
+ */
50
+ public function getResource()
51
+ {
52
+ return Mage::getResourceSingleton('bronto_reminder/rule');
53
+ }
54
+
55
+ /**
56
+ * Get filter by customer condition for rule matching sql
57
+ *
58
+ * @param int|Zend_Db_Expr $customer
59
+ * @param string $fieldName
60
+ * @return string
61
+ */
62
+ protected function _createCustomerFilter($customer, $fieldName)
63
+ {
64
+ return "{$fieldName} = root.entity_id";
65
+ }
66
+
67
+ /**
68
+ * Build query for matching customer to rule condition
69
+ *
70
+ * @param $customer
71
+ * @param $website
72
+ * @return Varien_Db_Select
73
+ */
74
+ protected function _prepareConditionsSql($customer, $website)
75
+ {
76
+ $select = $this->getResource()->createSelect();
77
+ $table = $this->getResource()->getTable('customer/entity');
78
+ $select->from($table, array(new Zend_Db_Expr(1)));
79
+ $select->where($this->_createCustomerFilter($customer, 'entity_id'));
80
+ return $select;
81
+ }
82
+
83
+ /**
84
+ * Check if condition is required. It affect condition select result comparison type (= || <>)
85
+ *
86
+ * @return bool
87
+ */
88
+ protected function _getRequiredValidation()
89
+ {
90
+ return ($this->getValue() == 1);
91
+ }
92
+
93
+ /**
94
+ * Get SQL select for matching customer to rule condition
95
+ *
96
+ * @param $customer
97
+ * @param $website
98
+ * @return Varien_Db_Select
99
+ */
100
+ public function getConditionsSql($customer, $website)
101
+ {
102
+ /**
103
+ * Build base SQL
104
+ */
105
+ $select = $this->_prepareConditionsSql($customer, $website);
106
+ $required = $this->_getRequiredValidation();
107
+ $whereFunction = ($this->getAggregator() == 'all') ? 'where' : 'orWhere';
108
+ $operator = $required ? '=' : '<>';
109
+ //$operator = '=';
110
+
111
+ $gotConditions = false;
112
+
113
+ /**
114
+ * Add children subselects conditions
115
+ */
116
+ foreach ($this->getConditions() as $condition) {
117
+ if ($sql = $condition->getConditionsSql($customer, $website)) {
118
+ $criteriaSql = "(IFNULL(($sql), 0) {$operator} 1)";
119
+ $select->$whereFunction($criteriaSql);
120
+ $gotConditions = true;
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Process combine subfilters. Subfilters are part of base select which can be affected by children.
126
+ */
127
+ $subfilterMap = $this->_getSubfilterMap();
128
+ if ($subfilterMap) {
129
+ foreach ($this->getConditions() as $condition) {
130
+ $subfilterType = $condition->getSubfilterType();
131
+ if (isset($subfilterMap[$subfilterType])) {
132
+ $subfilter = $condition->getSubfilterSql($subfilterMap[$subfilterType], $required, $website);
133
+ if ($subfilter) {
134
+ $select->$whereFunction($subfilter);
135
+ $gotConditions = true;
136
+ }
137
+ }
138
+ }
139
+ }
140
+
141
+ if (!$gotConditions) {
142
+ $select->where('1=1');
143
+ }
144
+
145
+ return $select;
146
+ }
147
+
148
+ /**
149
+ * Get infromation about subfilters map. Map contain children condition type and associated
150
+ * column name from itself select.
151
+ * Example: array('my_subtype'=>'my_table.my_column')
152
+ * In practice - date range can be as subfilter for different types of condition combines.
153
+ * Logic of this filter apply is same - but column names different
154
+ *
155
+ * @return array
156
+ */
157
+ protected function _getSubfilterMap()
158
+ {
159
+ return array();
160
+ }
161
+
162
+ /**
163
+ * Limit select by website with joining to store table
164
+ *
165
+ * @param Zend_Db_Select $select
166
+ * @param int|Zend_Db_Expr $website
167
+ * @param string $storeIdField
168
+ * @return Bronto_Reminder_Model_Condition_Abstract
169
+ */
170
+ protected function _limitByStoreWebsite(Zend_Db_Select $select, $website, $storeIdField)
171
+ {
172
+ $storeTable = $this->getResource()->getTable('core/store');
173
+ $select->join(array('store' => $storeTable), $storeIdField . '=store.store_id', array())
174
+ ->where('store.website_id=?', $website);
175
+ return $this;
176
+ }
177
+
178
+ /**
179
+ * Getter for "Conditions Combination" select option for recursive combines
180
+ */
181
+ protected function _getRecursiveChildSelectOption()
182
+ {
183
+ if (method_exists('Mage_Rule_Model_Condition_Combine', '_getRecursiveChildSelectOption')) {
184
+ return parent::_getRecursiveChildSelectOption();
185
+ }
186
+ return array('value' => $this->getType(), 'label' => Mage::helper('rule')->__('Conditions Combination'));
187
+ }
188
+ }
app/code/community/Bronto/Reminder/Model/Email/Message.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Email_Message extends Bronto_Common_Model_Email_Message
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_helper = 'bronto_reminder';
14
+ }
app/code/community/Bronto/Reminder/Model/Guest.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Guest extends Mage_Core_Model_Abstract
9
+ {
10
+ public function _construct()
11
+ {
12
+ parent::_construct();
13
+ $this->_init('bronto_reminder/guest');
14
+ }
15
+ }
app/code/community/Bronto/Reminder/Model/Mysql4/Customer/Collection.php ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Mysql4_Customer_Collection extends Mage_Customer_Model_Entity_Customer_Collection
9
+ {
10
+ /**
11
+ * Instantiate select to get matched customers
12
+ *
13
+ * @return Bronto_Reminder_Model_Mysql4_Customer_Collection
14
+ */
15
+ protected function _initSelect()
16
+ {
17
+ $rule = Mage::registry('current_reminder_rule');
18
+ $select = $this->getSelect();
19
+
20
+ $customerTable = $this->getTable('customer/entity');
21
+ $couponTable = $this->getTable('bronto_reminder/coupon');
22
+ $logTable = $this->getTable('bronto_reminder/log');
23
+
24
+ try {
25
+ $salesRuleCouponTable = $this->getTable('salesrule/coupon');
26
+ } catch (Exception $e) {
27
+ $salesRuleCouponTable = false;
28
+ }
29
+
30
+ $select->from(array('c' => $couponTable), array('associated_at', 'emails_failed', 'is_active'));
31
+ $select->where('c.rule_id = ?', $rule->getId());
32
+
33
+ $select->joinInner(
34
+ array('e' => $customerTable),
35
+ 'e.entity_id = c.customer_id',
36
+ array('entity_id', 'email')
37
+ );
38
+
39
+ $subSelect = $this->getConnection()->select();
40
+ $subSelect->from(array('g' => $logTable), array(
41
+ 'customer_id',
42
+ 'rule_id',
43
+ 'emails_sent' => new Zend_Db_Expr('COUNT(log_id)'),
44
+ 'last_sent' => new Zend_Db_Expr('MAX(sent_at)')
45
+ ));
46
+
47
+ $subSelect->where('rule_id = ?', $rule->getId());
48
+ $subSelect->group(array('customer_id', 'rule_id'));
49
+
50
+ $select->joinLeft(
51
+ array('l' => $subSelect),
52
+ 'l.rule_id = c.rule_id AND l.customer_id = c.customer_id',
53
+ array('l.emails_sent', 'l.last_sent')
54
+ );
55
+
56
+ if ($salesRuleCouponTable) {
57
+ $select->joinLeft(
58
+ array('sc' => $salesRuleCouponTable),
59
+ 'sc.coupon_id = c.coupon_id',
60
+ array('code', 'usage_limit', 'usage_per_customer')
61
+ );
62
+ }
63
+
64
+ $this->_joinFields['associated_at'] = array('table'=>'c', 'field' => 'associated_at');
65
+ $this->_joinFields['emails_failed'] = array('table'=>'c', 'field' => 'emails_failed');
66
+ $this->_joinFields['is_active'] = array('table'=>'c', 'field' => 'is_active');
67
+
68
+ if ($salesRuleCouponTable) {
69
+ $this->_joinFields['code'] = array('table'=>'sc', 'field' => 'code');
70
+ $this->_joinFields['usage_limit'] = array('table'=>'sc', 'field' => 'usage_limit');
71
+ $this->_joinFields['usage_per_customer'] = array('table'=>'sc', 'field' => 'usage_per_customer');
72
+ }
73
+
74
+ $this->_joinFields['emails_sent'] = array('table'=>'l', 'field' => 'emails_sent');
75
+ $this->_joinFields['last_sent'] = array('table'=>'l', 'field' => 'last_sent');
76
+
77
+ return $this;
78
+ }
79
+ }
app/code/community/Bronto/Reminder/Model/Mysql4/Guest.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Mysql4_Guest extends Mage_Core_Model_Mysql4_Abstract
9
+ {
10
+ public function _construct()
11
+ {
12
+ $this->_init('bronto_reminder/guest', 'guest_email_id');
13
+ }
14
+ }
app/code/community/Bronto/Reminder/Model/Mysql4/Guest/Collection.php ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Mysql4_Guest_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
9
+ {
10
+ public function _construct()
11
+ {
12
+ parent::_construct();
13
+ $this->_init('bronto_reminder/guest');
14
+ }
15
+ }
app/code/community/Bronto/Reminder/Model/Mysql4/Rule.php ADDED
@@ -0,0 +1,500 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Mysql4_Rule extends Mage_Core_Model_Mysql4_Abstract
9
+ {
10
+ /**
11
+ * Rule websites table name
12
+ *
13
+ * @var string
14
+ */
15
+ protected $_websiteTable;
16
+
17
+ protected function _construct()
18
+ {
19
+ $this->_init('bronto_reminder/rule', 'rule_id');
20
+ $this->_websiteTable = $this->getTable('bronto_reminder/website');
21
+ }
22
+
23
+ /**
24
+ * Get empty select object
25
+ *
26
+ * @return Varien_Db_Select
27
+ */
28
+ public function createSelect()
29
+ {
30
+ return $this->_getReadAdapter()->select();
31
+ }
32
+
33
+ /**
34
+ * Quote parameters into condition string
35
+ *
36
+ * @param string $string
37
+ * @param string | array $param
38
+ * @return string
39
+ */
40
+ public function quoteInto($string, $param)
41
+ {
42
+ return $this->_getReadAdapter()->quoteInto($string, $param);
43
+ }
44
+
45
+ /**
46
+ * Prepare object data for saving
47
+ *
48
+ * @param Mage_Core_Model_Abstract $object
49
+ */
50
+ protected function _beforeSave(Mage_Core_Model_Abstract $object)
51
+ {
52
+ if (!$object->getActiveFrom()) {
53
+ $object->setActiveFrom(new Zend_Db_Expr('NULL'));
54
+ }
55
+ else {
56
+ if ($object->getActiveFrom() instanceof Zend_Date) {
57
+ $object->setActiveFrom($object->getActiveFrom()->toString(Varien_Date::DATETIME_INTERNAL_FORMAT));
58
+ }
59
+ }
60
+
61
+ if (!$object->getActiveTo()) {
62
+ $object->setActiveTo(new Zend_Db_Expr('NULL'));
63
+ }
64
+ else {
65
+ if ($object->getActiveTo() instanceof Zend_Date) {
66
+ $object->setActiveTo($object->getActiveTo()->toString(Varien_Date::DATETIME_INTERNAL_FORMAT));
67
+ }
68
+ }
69
+ parent::_beforeSave($object);
70
+ }
71
+
72
+ /**
73
+ * Perform actions after object save
74
+ *
75
+ * @param Mage_Core_Model_Abstract $rule
76
+ * @return Mage_Core_Model_Mysql4_Abstract
77
+ */
78
+ protected function _afterSave(Mage_Core_Model_Abstract $rule)
79
+ {
80
+ if ($rule->hasData('website_ids')) {
81
+ $this->_saveWebsiteIds($rule);
82
+ }
83
+ if ($rule->hasData('store_messages')) {
84
+ $this->_saveMessageData($rule);
85
+ }
86
+ return parent::_afterSave($rule);
87
+ }
88
+
89
+ /**
90
+ * Save all website ids associated to rule
91
+ *
92
+ * @param $rule
93
+ * @return Bronto_Reminder_Model_Mysql4_Rule
94
+ */
95
+ protected function _saveWebsiteIds($rule)
96
+ {
97
+ $adapter = $this->_getWriteAdapter();
98
+ $adapter->delete($this->_websiteTable, array('rule_id=?' => $rule->getId()));
99
+ $websiteIds = $rule->getWebsiteIds();
100
+ if (!is_array($websiteIds)) {
101
+ $websiteIds = array($websiteIds);
102
+ }
103
+ foreach ($websiteIds as $websiteId) {
104
+ $adapter->insert($this->_websiteTable, array(
105
+ 'website_id' => $websiteId,
106
+ 'rule_id' => $rule->getId()
107
+ ));
108
+ }
109
+ return $this;
110
+ }
111
+
112
+ /**
113
+ * Get website ids associated to the rule id
114
+ *
115
+ * @param int $ruleId
116
+ * @return array
117
+ */
118
+ public function getWebsiteIds($ruleId)
119
+ {
120
+ $select = $this->_getReadAdapter()->select()
121
+ ->from($this->_websiteTable, 'website_id')
122
+ ->where('rule_id=?', $ruleId);
123
+ return $this->_getReadAdapter()->fetchCol($select);
124
+ }
125
+
126
+ /**
127
+ * Save store Messages
128
+ *
129
+ * @param $rule
130
+ * @return Bronto_Reminder_Model_Mysql4_Rule
131
+ */
132
+ protected function _saveMessageData($rule)
133
+ {
134
+ $adapter = $this->_getWriteAdapter();
135
+ $messageTable = $this->getTable('bronto_reminder/message');
136
+ $adapter->delete($messageTable, array('rule_id = ?' => $rule->getId()));
137
+
138
+ $labels = $rule->getStoreLabels();
139
+ $descriptions = $rule->getStoreDescriptions();
140
+
141
+ foreach ($rule->getStoreMessages() as $storeId => $messageId) {
142
+ if (!$messageId) {
143
+ continue;
144
+ }
145
+ $adapter->insert($messageTable, array(
146
+ 'rule_id' => $rule->getId(),
147
+ 'store_id' => $storeId,
148
+ 'message_id' => $messageId,
149
+ 'label' => $labels[$storeId],
150
+ 'description' => $descriptions[$storeId]
151
+ ));
152
+ }
153
+ return $this;
154
+ }
155
+
156
+ /**
157
+ * Get Message data assigned to reminder rule
158
+ *
159
+ * @param int $ruleId
160
+ * @return array
161
+ */
162
+ public function getMessageData($ruleId)
163
+ {
164
+ $messageTable = $this->getTable('bronto_reminder/message');
165
+ $select = $this->createSelect()
166
+ ->from($messageTable, array('store_id', 'message_id', 'label', 'description'))
167
+ ->where('rule_id = ?', $ruleId);
168
+ return $this->_getReadAdapter()->fetchAll($select);
169
+ }
170
+
171
+ /**
172
+ * Get store data (labels and descriptions) assigned to reminder rule.
173
+ * If labels and descriptions are not specified it will be replaced with default values.
174
+ *
175
+ * @param int $ruleId
176
+ * @param int $storeId
177
+ * @return array
178
+ */
179
+ public function getStoreMessageData($ruleId, $storeId)
180
+ {
181
+ $messageTable = $this->getTable('bronto_reminder/message');
182
+ $ruleTable = $this->getTable('bronto_reminder/rule');
183
+
184
+ $select = $this->createSelect()->from(array('m' => $messageTable),
185
+ 'm.message_id,
186
+ IF(m.label != \'\', m.label, r.default_label) as label,
187
+ IF(m.description != \'\', m.description, r.default_description) as description'
188
+ );
189
+
190
+ $select->join(
191
+ array('r' => $ruleTable),
192
+ 'r.rule_id = m.rule_id',
193
+ array()
194
+ );
195
+
196
+ $select->where('m.rule_id = ?', $ruleId);
197
+ $select->where('m.store_id = ?', $storeId);
198
+
199
+ return $this->_getReadAdapter()->fetchRow($select);
200
+ }
201
+
202
+ /**
203
+ * @param int $ruleId
204
+ * @param int $customerId
205
+ * @param string $messageId
206
+ * @return array
207
+ */
208
+ public function getRuleLogItemsData($ruleId, $customerId, $messageId = null)
209
+ {
210
+ $logTable = $this->getTable('bronto_reminder/log');
211
+
212
+ $select = $this->createSelect()->from(array('l' => $logTable));
213
+ $select->where('l.rule_id = ?', $ruleId);
214
+ $select->where('l.customer_id = ?', $customerId);
215
+ if (!empty($messageId)) {
216
+ $select->where('l.bronto_message_id = ?', $messageId);
217
+ }
218
+ $select->order('l.sent_at DESC');
219
+ $select->limit(1);
220
+
221
+ return $this->_getReadAdapter()->fetchRow($select);
222
+ }
223
+
224
+ /**
225
+ * Get comparison condition for rule condition operator which will be used in SQL query
226
+ *
227
+ * @param string $operator
228
+ * @return string
229
+ */
230
+ public function getSqlOperator($operator)
231
+ {
232
+ switch ($operator) {
233
+ case '==':
234
+ return '=';
235
+ case '!=':
236
+ return '<>';
237
+ case '{}':
238
+ return 'LIKE';
239
+ case '!{}':
240
+ return 'NOT LIKE';
241
+ case 'between':
242
+ return "BETWEEN '%s' AND '%s'";
243
+ case '>':
244
+ case '<':
245
+ case '>=':
246
+ case '<=':
247
+ return $operator;
248
+ default:
249
+ Mage::throwException(Mage::helper('bronto_reminder')->__('Unknown operator specified.'));
250
+ }
251
+ }
252
+
253
+ /**
254
+ * Create string for select "where" condition based on field name, comparison operator and vield value
255
+ *
256
+ * @param string $field
257
+ * @param string $operator
258
+ * @param mixed $value
259
+ * @return string
260
+ */
261
+ public function createConditionSql($field, $operator, $value)
262
+ {
263
+ $sqlOperator = $this->getSqlOperator($operator);
264
+ $condition = '';
265
+ switch ($operator) {
266
+ case '{}':
267
+ case '!{}':
268
+ if (is_array($value)) {
269
+ if (!empty($value)) {
270
+ $sqlOperator = ($operator == '{}') ? 'IN' : 'NOT IN';
271
+ $condition = $this->quoteInto($field . ' ' . $sqlOperator . ' (?)', $value);
272
+ }
273
+ } else {
274
+ $condition = $this->quoteInto($field. ' ' . $sqlOperator . ' ?', '%' . $value . '%');
275
+ }
276
+ break;
277
+ case 'between':
278
+ $condition = $field . ' ' . sprintf($sqlOperator, $value['start'], $value['end']);
279
+ break;
280
+ default:
281
+ $condition = $this->quoteInto($field . ' ' . $sqlOperator . ' ?', $value);
282
+ break;
283
+ }
284
+ return $condition;
285
+ }
286
+
287
+ /**
288
+ * Deactivate already matched customers before new matching process
289
+ *
290
+ * @param int $ruleId
291
+ * @return Bronto_Reminder_Model_Mysql4_Rule
292
+ */
293
+ public function deactivateMatchedCustomers($ruleId)
294
+ {
295
+ $this->_getWriteAdapter()->update(
296
+ $this->getTable('bronto_reminder/coupon'),
297
+ array('is_active' => '0'),
298
+ array('rule_id = ?' => $ruleId)
299
+ );
300
+ return $this;
301
+ }
302
+
303
+ /**
304
+ * Try to associate reminder rule with matched customers.
305
+ * If customer was added earlier, update is_active column.
306
+ *
307
+ * @param Bronto_Reminder_Model_Rule $rule
308
+ * @param Mage_SalesRule_Model_Rule $salesRule
309
+ * @param int $websiteId
310
+ * @return Bronto_Reminder_Model_Mysql4_Rule
311
+ */
312
+ public function saveMatchedCustomers($rule, $salesRule, $websiteId, $threshold=null)
313
+ {
314
+ /* This was moved out to Bronto_Reminder_Model_Rule::_matchCustomers() */
315
+ // $rule->setConditions(null);
316
+ // $rule->afterLoad();
317
+ $select = $rule->getConditions()->getConditionsSql(null, $websiteId);
318
+
319
+ if (!$rule->getConditionSql()) {
320
+ return $this;
321
+ }
322
+ if ($threshold) {
323
+ $select->where('c.emails_failed IS NULL OR c.emails_failed < ? ', $threshold);
324
+ }
325
+
326
+ $i = 0;
327
+ $ruleId = $rule->getId();
328
+ $adapter = $this->_getWriteAdapter();
329
+ $currentDate = $this->formatDate(time());
330
+ $dataToInsert = array();
331
+ Mage::helper('bronto_reminder')->writeDebug('ruleId: ' . $rule->getId() . ' website: ' . $websiteId, 'bronto_reminder_sql.log');
332
+ Mage::helper('bronto_reminder')->writeDebug($select->__toString(), 'bronto_reminder_sql.log');
333
+ /* @var $stmt Varien_Db_Statement_Pdo_Mysql */
334
+ $stmt = $adapter->query($select, array('rule_id' => $ruleId));
335
+
336
+ Mage::helper('bronto_reminder')->writeDebug('saveMatchedCustomers():', 'bronto_reminder_sql.log');
337
+
338
+ try {
339
+ $adapter->beginTransaction();
340
+ while ($row = $stmt->fetch()) {
341
+ if (empty($row['coupon_id']) && $salesRule) {
342
+ $coupon = $salesRule->acquireCoupon();
343
+ $couponId = ($coupon !== null) ? $coupon->getId() : null;
344
+ }
345
+ else {
346
+ $couponId = $row['coupon_id'];
347
+ }
348
+
349
+ $dataToInsert[] = array(
350
+ 'rule_id' => $ruleId,
351
+ 'coupon_id' => $couponId,
352
+ 'customer_id' => $row['entity_id'],
353
+ 'associated_at' => $currentDate,
354
+ 'is_active' => '1'
355
+ );
356
+ $i++;
357
+
358
+ if (($i % 1000) == 0) {
359
+ $this->_saveMatchedCustomerData($dataToInsert);
360
+ $adapter->commit();
361
+ $adapter->beginTransaction();
362
+ $dataToInsert = array();
363
+ }
364
+ }
365
+ $this->_saveMatchedCustomerData($dataToInsert);
366
+ $adapter->commit();
367
+ } catch (Exception $e) {
368
+ $adapter->rollBack();
369
+ throw $e;
370
+ }
371
+
372
+ return $this;
373
+ }
374
+
375
+ /**
376
+ * Save data by matched customer coupons
377
+ *
378
+ * @param array $data
379
+ */
380
+ protected function _saveMatchedCustomerData($data)
381
+ {
382
+ if ($data) {
383
+ $table = $this->getTable('bronto_reminder/coupon');
384
+ $this->_getWriteAdapter()->insertOnDuplicate($table, $data, array('is_active'));
385
+ }
386
+ }
387
+
388
+ /**
389
+ * Return list of customers for notification process.
390
+ * This process can be initialized system cron or by admin for some rule
391
+ *
392
+ * @param int|null $limit
393
+ * @param int|null $ruleId
394
+ * @return array
395
+ */
396
+ public function getCustomersForNotification($limit=null, $ruleId=null)
397
+ {
398
+ $couponTable = $this->getTable('bronto_reminder/coupon');
399
+ $ruleTable = $this->getTable('bronto_reminder/rule');
400
+ $logTable = $this->getTable('bronto_reminder/log');
401
+ $currentDate = $this->formatDate(time());
402
+
403
+ $select = $this->createSelect()->from(
404
+ array('c' => $couponTable),
405
+ array('customer_id', 'coupon_id', 'rule_id')
406
+ );
407
+
408
+ $select->join(
409
+ array('r' => $ruleTable),
410
+ 'c.rule_id = r.rule_id AND r.is_active = 1',
411
+ array('schedule')
412
+ );
413
+
414
+ $select->joinLeft(
415
+ array('l' => $logTable),
416
+ 'c.rule_id=l.rule_id AND c.customer_id=l.customer_id',
417
+ array()
418
+ );
419
+
420
+ if ($ruleId) {
421
+ $select->where('c.rule_id = ?', $ruleId);
422
+ }
423
+
424
+ $select->where('c.is_active = 1');
425
+ $select->group(array('c.customer_id', 'c.rule_id'));
426
+ $select->having("(MAX(l.sent_at) IS NULL) OR (FIND_IN_SET(TO_DAYS('{$currentDate}') - TO_DAYS(MIN(l.sent_at)), r.schedule))");
427
+
428
+ if ($limit) {
429
+ $select->limit($limit);
430
+ }
431
+
432
+ /**
433
+ SELECT `c`.`customer_id`, `c`.`coupon_id`, `c`.`rule_id`, `r`.`schedule`
434
+ FROM `bronto_reminder_rule_coupon` AS `c`
435
+ INNER JOIN `bronto_reminder_rule` AS `r` ON c.rule_id = r.rule_id AND r.is_active = 1
436
+ LEFT JOIN `bronto_reminder_rule_log` AS `l` ON c.rule_id=l.rule_id AND c.customer_id=l.customer_id
437
+ WHERE (c.rule_id = '1') AND (c.is_active = 1)
438
+ GROUP BY `c`.`customer_id`, `c`.`rule_id`
439
+ HAVING ((MAX(l.sent_at) IS NULL)
440
+ OR (FIND_IN_SET(TO_DAYS('2012-05-11 09:21:27') - TO_DAYS(MIN(l.sent_at)), r.schedule)
441
+ AND TO_DAYS('2012-05-11 09:21:27') != TO_DAYS(MAX(l.sent_at))))
442
+ LIMIT 100
443
+ */
444
+
445
+ return $this->_getReadAdapter()->fetchAll($select);
446
+ }
447
+
448
+ /**
449
+ * Add notification log row after letter was successfully sent.
450
+ *
451
+ * @param int $ruleId
452
+ * @param int $customerId
453
+ * @return Bronto_Reminder_Model_Mysql4_Rule
454
+ */
455
+ public function addNotificationLog($ruleId, $customerId, $deliveryId = null, $messageId = null)
456
+ {
457
+ $data = array(
458
+ 'rule_id' => $ruleId,
459
+ 'customer_id' => $customerId,
460
+ 'sent_at' => $this->formatDate(time()),
461
+ 'bronto_delivery_id' => $deliveryId,
462
+ 'bronto_message_id' => $messageId,
463
+ );
464
+
465
+ $this->_getWriteAdapter()->insert($this->getTable('bronto_reminder/log'), $data);
466
+ return $this;
467
+ }
468
+
469
+ /**
470
+ * Update failed email counter.
471
+ *
472
+ * @param int $ruleId
473
+ * @param int $customerId
474
+ * @return Bronto_Reminder_Model_Mysql4_Rule
475
+ */
476
+ public function updateFailedEmailsCounter($ruleId, $customerId)
477
+ {
478
+ $this->_getWriteAdapter()->update($this->getTable('bronto_reminder/coupon'),
479
+ array('emails_failed' => new Zend_Db_Expr('emails_failed + 1')),
480
+ array('rule_id = ?' => $ruleId, 'customer_id = ?' => $customerId)
481
+ );
482
+ return $this;
483
+ }
484
+
485
+ /**
486
+ * Return count of reminder rules assigned to specified sales rule.
487
+ *
488
+ * @param int $salesruleId
489
+ * @return int
490
+ */
491
+ public function getAssignedRulesCount($salesruleId)
492
+ {
493
+ $select = $this->createSelect()->from(
494
+ array('r' => $this->getTable('bronto_reminder/rule')),
495
+ array(new Zend_Db_Expr('count(*)'))
496
+ );
497
+ $select->where('r.salesrule_id = ?', $salesruleId);
498
+ return $this->_getReadAdapter()->fetchOne($select);
499
+ }
500
+ }
app/code/community/Bronto/Reminder/Model/Mysql4/Rule/Collection.php ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Mysql4_Rule_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
9
+ {
10
+ /**
11
+ * Intialize collection
12
+ *
13
+ * @return void
14
+ */
15
+ protected function _construct()
16
+ {
17
+ $this->_init('bronto_reminder/rule');
18
+ }
19
+
20
+ /**
21
+ * Limit rules collection by is_active column
22
+ *
23
+ * @param int $value
24
+ * @return Bronto_Reminder_Model_Mysql4_Rule_Collection
25
+ */
26
+ public function addIsActiveFilter($value)
27
+ {
28
+ $this->getSelect()->where('main_table.is_active = ?', $value);
29
+ return $this;
30
+ }
31
+
32
+ /**
33
+ * Limit rules collection by date columns
34
+ *
35
+ * @param int $value
36
+ * @return Bronto_Reminder_Model_Mysql4_Rule_Collection
37
+ */
38
+ public function addDateFilter($date)
39
+ {
40
+ $this->getSelect()
41
+ ->where($this->getConnection()->quoteInto('active_from IS NULL OR active_from <= ?', $date))
42
+ ->where($this->getConnection()->quoteInto('active_to IS NULL OR active_to >= ?', $date));
43
+
44
+ return $this;
45
+ }
46
+
47
+ /**
48
+ * Limit rules collection by separate rule
49
+ *
50
+ * @param int $value
51
+ * @return Bronto_Reminder_Model_Mysql4_Rule_Collection
52
+ */
53
+ public function addRuleFilter($value)
54
+ {
55
+ $this->getSelect()->where('main_table.rule_id = ?', $value);
56
+ return $this;
57
+ }
58
+
59
+ /**
60
+ * Redeclare after load method for adding website ids to items
61
+ *
62
+ * @return Bronto_Reminder_Model_Mysql4_Rule_Collection
63
+ */
64
+ protected function _afterLoad()
65
+ {
66
+ parent::_afterLoad();
67
+ if ($this->getFlag('add_websites_to_result') && $this->_items) {
68
+ $select = $this->getConnection()->select()
69
+ ->from($this->getTable('bronto_reminder/website'), array(
70
+ 'rule_id',
71
+ new Zend_Db_Expr('GROUP_CONCAT(website_id)')
72
+ ))
73
+ ->where('rule_id IN (?)', array_keys($this->_items))
74
+ ->group('rule_id');
75
+ $websites = $this->getConnection()->fetchPairs($select);
76
+ foreach ($this->_items as $item) {
77
+ if (isset($websites[$item->getId()])) {
78
+ $item->setWebsiteIds(explode(',', $websites[$item->getId()]));
79
+ }
80
+ }
81
+ }
82
+
83
+ return $this;
84
+ }
85
+
86
+ /**
87
+ * Init flag for adding rule website ids to collection result
88
+ *
89
+ * @param bool | null $flag
90
+ * @return Bronto_Reminder_Model_Mysql4_Rule_Collection
91
+ */
92
+ public function addWebsitesToResult($flag = null)
93
+ {
94
+ $flag = ($flag === null) ? true : $flag;
95
+ $this->setFlag('add_websites_to_result', $flag);
96
+ return $this;
97
+ }
98
+
99
+ /**
100
+ * Limit rules collection by specific website
101
+ *
102
+ * @param int | array | Mage_Core_Model_Website $websiteId
103
+ * @return Bronto_Reminder_Model_Mysql4_Rule_Collection
104
+ */
105
+ public function addWebsiteFilter($websiteId)
106
+ {
107
+ if (!$this->getFlag('is_website_table_joined')) {
108
+ $this->setFlag('is_website_table_joined', true);
109
+ $this->getSelect()->joinInner(
110
+ array('website' => $this->getTable('bronto_reminder/website')),
111
+ 'main_table.rule_id = website.rule_id',
112
+ array()
113
+ );
114
+ }
115
+
116
+ if ($websiteId instanceof Mage_Core_Model_Website) {
117
+ $websiteId = $websiteId->getId();
118
+ }
119
+ $this->getSelect()->where('website.website_id IN (?)', $websiteId);
120
+
121
+ return $this;
122
+ }
123
+
124
+ /**
125
+ * Redeclared for support website id filter
126
+ *
127
+ * @param string $field
128
+ * @param mixed $condition
129
+ * @return Bronto_Reminder_Model_Mysql4_Rule_Collection
130
+ */
131
+ public function addFieldToFilter($field, $condition=null)
132
+ {
133
+ if ($field == 'website_ids') {
134
+ return $this->addWebsiteFilter($condition);
135
+ }
136
+ return parent::addFieldToFilter($field, $condition);
137
+ }
138
+ }
app/code/community/Bronto/Reminder/Model/Observer.php ADDED
@@ -0,0 +1,127 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Observer
9
+ {
10
+ const NOTICE_IDENTIFER = 'bronto_reminder';
11
+
12
+ /**
13
+ * @param Varien_Event_Observer $observer
14
+ *
15
+ * @return mixed
16
+ */
17
+ public function checkBrontoRequirements(Varien_Event_Observer $observer)
18
+ {
19
+ if (!Mage::getSingleton('admin/session')->isLoggedIn()) {
20
+ return;
21
+ }
22
+
23
+ // Verify Requirements
24
+ if (!Mage::helper(self::NOTICE_IDENTIFER)->varifyRequirements(self::NOTICE_IDENTIFER, array('soap', 'openssl'))) {
25
+ return;
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Include auto coupon type
31
+ *
32
+ * @param Varien_Event_Observer $observer
33
+ *
34
+ * @return Bronto_Reminder_Model_Observer
35
+ */
36
+ public function getCouponTypes($observer)
37
+ {
38
+ if ($transport = $observer->getEvent()->getTransport()) {
39
+ $transport->setIsCouponTypeAutoVisible(true);
40
+ }
41
+ return $this;
42
+ }
43
+
44
+ /**
45
+ * Add custom comment after coupon type field
46
+ *
47
+ * @param Varien_Event_Observer $observer
48
+ *
49
+ * @return Bronto_Reminder_Model_Observer
50
+ */
51
+ public function updatePromoQuoteTabMainForm($observer)
52
+ {
53
+ $form = $observer->getEvent()->getForm();
54
+ if (!$form) {
55
+ return $this;
56
+ }
57
+ if ($fieldset = $form->getElements()->searchById('base_fieldset')) {
58
+ if ($couponTypeFiled = $fieldset->getElements()->searchById('coupon_type')) {
59
+ $couponTypeFiled->setNote(Mage::helper('bronto_reminder')->__('Coupons can be auto-generated by reminder promotion rules.'));
60
+ }
61
+ }
62
+ return $this;
63
+ }
64
+
65
+ /**
66
+ * Send scheduled notifications
67
+ *
68
+ * @return Bronto_Reminder_Model_Observer
69
+ */
70
+ public function scheduledNotification()
71
+ {
72
+ Mage::helper('bronto_reminder')->writeDebug('scheduledNotification() triggered...');
73
+ if (Mage::helper('bronto_reminder')->isEnabled()) {
74
+ $result = Mage::getModel('bronto_reminder/rule')->sendReminderEmails();
75
+ return $result;
76
+ } else {
77
+ return 'Bronto_Reminder module is not enabled.';
78
+ }
79
+ Mage::helper('bronto_reminder')->writeDebug('Done!');
80
+ }
81
+
82
+ /**
83
+ * @return void
84
+ */
85
+ public function storeGuestEmailCheckout($observer)
86
+ {
87
+ $quote = $observer->getQuote();
88
+ $postData = Mage::app()->getRequest()->getPost();
89
+ if ( Mage_Checkout_Model_Type_Onepage::METHOD_GUEST == $quote->getCheckoutMethod()
90
+ && isset($postData['billing'])
91
+ ) {
92
+ $session = Mage::getSingleton('core/session');
93
+ $guestCheck = Mage::getModel('bronto_reminder/guest')
94
+ ->getCollection()
95
+ ->addFieldToFilter('session_id', $session->getSessionId());
96
+
97
+ if ($guestCheck->count() == 0) {
98
+ $guestModel = Mage::getModel('bronto_reminder/guest');
99
+ $guestModel->setEmailAddress($quote->getCustomerEmail())
100
+ ->setFirstname($quote->getCustomerFirstname())
101
+ ->setLastname($quote->getCustomerLastname())
102
+ ->setSessionId($session->getSessionId())
103
+ ->setStoreId(Mage::app()->getStore()->getStoreId())
104
+ ->setQuoteId(Mage::getSingleton('checkout/session')->getQuote()->getId())
105
+ ->save();
106
+ }
107
+ }
108
+ }
109
+
110
+ /**
111
+ * @return void
112
+ */
113
+ public function guestCheckoutCompleted(Varien_Event_Observer $observer)
114
+ {
115
+ if (!Mage::helper('customer')->isLoggedIn()) {
116
+ // Remove this guest from the extended table
117
+ // so that they do not get reminder emails
118
+ $guests = Mage::getModel('bronto_reminder/guest')
119
+ ->getCollection()
120
+ ->addFieldToFilter('session_id', session_id());
121
+
122
+ foreach ($guests as $guest) {
123
+ $guest->delete();
124
+ }
125
+ }
126
+ }
127
+ }
app/code/community/Bronto/Reminder/Model/Rule.php ADDED
@@ -0,0 +1,377 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ * @method Bronto_Reminder_Model_Mysql4_Rule _getResource()
8
+ */
9
+ class Bronto_Reminder_Model_Rule extends Mage_Rule_Model_Rule
10
+ {
11
+ /**
12
+ * Contains data defined per store view, will be used in Messages as variables
13
+ * @var array
14
+ */
15
+ protected $_messageData = array();
16
+
17
+ protected function _construct()
18
+ {
19
+ parent::_construct();
20
+ $this->_init('bronto_reminder/rule');
21
+ }
22
+
23
+ /**
24
+ * Perform actions after object load
25
+ *
26
+ * @return Bronto_Reminder_Model_Rule
27
+ */
28
+ protected function _afterLoad()
29
+ {
30
+ Mage_Core_Model_Abstract::_afterLoad();
31
+
32
+ $version = Mage::getVersionInfo();
33
+ if ( 1 == $version['major']
34
+ && (6 >= $version['minor'] || 9 == $version['minor'])
35
+ ) {
36
+ $conditionsArr = unserialize($this->getConditionsSerialized());
37
+ if (!empty($conditionsArr) && is_array($conditionsArr)) {
38
+ $this->getConditions()->loadArray($conditionsArr);
39
+ }
40
+ }
41
+
42
+ $messageData = $this->_getResource()->getMessageData($this->getId());
43
+
44
+ foreach ($messageData as $data) {
45
+ $message = (empty($data['message_id'])) ? null : $data['message_id'];
46
+ $this->setData('store_message_' . $data['store_id'], $message);
47
+ }
48
+
49
+ return $this;
50
+ }
51
+
52
+ /**
53
+ * Perform actions before object save.
54
+ */
55
+ protected function _beforeSave()
56
+ {
57
+ $this->setConditionSql(
58
+ $this->getConditions()->getConditionsSql(null, new Zend_Db_Expr(':website_id'))
59
+ );
60
+
61
+ if (!$this->getSalesruleId()) {
62
+ $this->setSalesruleId(null);
63
+ }
64
+ parent::_beforeSave();
65
+ }
66
+
67
+ /**
68
+ * Live website ids data as is
69
+ *
70
+ * @return Bronto_Reminder_Model_Rule
71
+ */
72
+ protected function _prepareWebsiteIds()
73
+ {
74
+ return $this;
75
+ }
76
+
77
+ /**
78
+ * Return conditions instance
79
+ *
80
+ * @return Bronto_Reminder_Model_Rule_Condition_Combine
81
+ */
82
+ public function getConditionsInstance()
83
+ {
84
+ return Mage::getModel('bronto_reminder/rule_condition_combine_root');
85
+ }
86
+
87
+ /**
88
+ * Get rule associated website ids
89
+ *
90
+ * @return array
91
+ */
92
+ public function getWebsiteIds()
93
+ {
94
+ if (!$this->hasData('website_ids')) {
95
+ $this->setData('website_ids', $this->_getResource()->getWebsiteIds($this->getId()));
96
+ }
97
+ return $this->_getData('website_ids');
98
+ }
99
+
100
+ /**
101
+ * Send reminder emails
102
+ *
103
+ * @param bool $dontSend
104
+ * @return Bronto_Reminder_Model_Rule
105
+ */
106
+ public function sendReminderEmails($dontSend = false)
107
+ {
108
+ /* @var $mail Bronto_Reminder_Model_Email_Message */
109
+ $mail = Mage::getModel('bronto_reminder/email_message');
110
+ $limit = Mage::helper('bronto_reminder')->getOneRunLimit();
111
+ $identity = Mage::helper('bronto_reminder')->getEmailIdentity();
112
+
113
+ $this->_matchCustomers();
114
+
115
+ $recipients = $this->_getResource()->getCustomersForNotification($limit, $this->getRuleId());
116
+ $recipients = array_merge( $recipients, $this->_getGuestAbandons() );
117
+
118
+ if ($dontSend) {
119
+ return $this;
120
+ }
121
+
122
+ $total = 0;
123
+ $success = 0;
124
+ $error = 0;
125
+ foreach ($recipients as $recipient) {
126
+ $total++;
127
+
128
+ if($recipient['customer_id'] != 0) {
129
+ /* @var $customer Mage_Customer_Model_Customer */
130
+ $customer = Mage::getModel('customer/customer')->load($recipient['customer_id']);
131
+ if (!$customer || !$customer->getId()) {
132
+ $error++;
133
+ continue;
134
+ }
135
+ } else {
136
+ // Guest Abandon. Create Customer on the fly
137
+ $storeId = $recipient['guest']->getStoreId();
138
+ $customer = Mage::getModel('customer/customer');
139
+ $customer
140
+ ->setFirstName($recipient['guest']->getFirstName())
141
+ ->setLastName($recipient['guest']->getLastName())
142
+ ->setEmail($recipient['guest']->getEmailAddress())
143
+ ->setStoreId($storeId)
144
+ ->setId(0)
145
+ ->setWebsiteId(Mage::getModel('core/store')->load($storeId)->getWebsiteId());
146
+ }
147
+
148
+ if ($customer->getStoreId()) {
149
+ $store = $customer->getStore();
150
+ } else {
151
+ $store = Mage::app()->getWebsite($customer->getWebsiteId())->getDefaultStore();
152
+ }
153
+
154
+ $messageData = $this->getMessageData($recipient['rule_id'], $store->getId(), $customer->getWebsiteId());
155
+ if (!$messageData) {
156
+ Mage::helper('bronto_reminder')->writeInfo("Rule doesn't have an associated Bronto message.");
157
+ $error++;
158
+ continue;
159
+ }
160
+
161
+ $coupon = false;
162
+ if (class_exists('Mage_SalesRule_Model_Coupon', false)) {
163
+ /* @var $coupon Mage_SalesRule_Model_Coupon */
164
+ $coupon = Mage::getModel('salesrule/coupon')->load($recipient['coupon_id']);
165
+ }
166
+
167
+ /* @var $quote Mage_Sales_Model_Quote */
168
+ if($customer->getId() != 0) {
169
+ $quote = Mage::getModel('sales/quote')
170
+ ->setStoreId($store->getId())
171
+ ->loadByCustomer($customer->getId());
172
+ } else {
173
+ // Load quote stored for guest
174
+ $quote = Mage::getModel('sales/quote')
175
+ ->setStoreId($store->getId())
176
+ ->loadByIdWithoutStore($recipient['guest']->getQuoteId());
177
+ }
178
+
179
+ $templateVars = array(
180
+ 'store' => $store,
181
+ 'customer' => $customer,
182
+ 'promotion_name' => $messageData['label'],
183
+ 'promotion_description' => $messageData['description'],
184
+ 'coupon' => $coupon,
185
+ 'rule' => $this,
186
+ 'quote' => $quote
187
+ );
188
+
189
+ Mage::helper('bronto_reminder')->writeDebug('Sending message to: ' . $customer->getEmail());
190
+
191
+ try {
192
+ $message = Mage::helper('bronto_reminder/message')->getMessageById($messageData['message_id'], $store->getId(), $customer->getWebsiteId());
193
+
194
+ $mail->sendTransactional(
195
+ $message,
196
+ $identity,
197
+ $customer->getEmail(),
198
+ null,
199
+ $templateVars,
200
+ $store->getId()
201
+ );
202
+
203
+ } catch (Exception $e) {
204
+ Mage::helper('bronto_reminder')->writeError(' ' . $e->getMessage());
205
+ }
206
+
207
+ if ($mail->getSentSuccess()) {
208
+ Mage::helper('bronto_reminder')->writeDebug(' Success');
209
+
210
+ if($customer->getId() != 0) {
211
+ $this->_getResource()->addNotificationLog(
212
+ $recipient['rule_id'], $customer->getId(), $mail->getLastDeliveryId(), $messageData['message_id']
213
+ );
214
+
215
+ } else {
216
+ // Add notification log for guest abandon email
217
+ $this->_getResource()->addNotificationLog(
218
+ $recipient['rule_id'], 0, $mail->getLastDeliveryId(), $messageData['message_id']
219
+ );
220
+ // Update guest to reflect they have received a reminder notification
221
+ $recipient['guest']->setEmailSent(1)->save();
222
+ }
223
+
224
+ $success++;
225
+ } else {
226
+ Mage::helper('bronto_reminder')->writeDebug(' Failed');
227
+ $this->_getResource()->updateFailedEmailsCounter($recipient['rule_id'], $customer->getId());
228
+ $error++;
229
+ }
230
+ }
231
+
232
+ return array(
233
+ 'total' => $total,
234
+ 'success' => $success,
235
+ 'error' => $error,
236
+ );
237
+ }
238
+
239
+ /**
240
+ * Match customers and assign coupons
241
+ *
242
+ * @return Bronto_Reminder_Model_Observer
243
+ */
244
+ protected function _matchCustomers()
245
+ {
246
+ $threshold = Mage::helper('bronto_reminder')->getSendFailureThreshold();
247
+
248
+ $currentDate = Mage::getModel('core/date')->date('Y-m-d');
249
+ $rules = $this->getCollection()->addDateFilter($currentDate)
250
+ ->addIsActiveFilter(1);
251
+
252
+ if ($ruleId = $this->getRuleId()) {
253
+ $rules->addRuleFilter($ruleId);
254
+ }
255
+
256
+ foreach ($rules as $rule) {
257
+ $this->_getResource()->deactivateMatchedCustomers($rule->getId());
258
+
259
+ if ($rule->getSalesruleId()) {
260
+ /* @var $salesRule Mage_SalesRule_Model_Rule */
261
+ $salesRule = Mage::getSingleton('salesrule/rule')->load($rule->getSalesruleId());
262
+ $websiteIds = array_intersect($rule->getWebsiteIds(), $salesRule->getWebsiteIds());
263
+ } else {
264
+ $salesRule = null;
265
+ $websiteIds = $rule->getWebsiteIds();
266
+ }
267
+
268
+ $rule->setConditions(null);
269
+ $rule->afterLoad();
270
+
271
+ foreach ($websiteIds as $websiteId) {
272
+ $this->_getResource()->saveMatchedCustomers($rule, $salesRule, $websiteId, $threshold);
273
+ }
274
+ }
275
+
276
+ return $this;
277
+ }
278
+
279
+ /**
280
+ * Return Message data
281
+ *
282
+ * @param int $ruleId
283
+ * @param int $storeId
284
+ * @return array|false
285
+ */
286
+ public function getMessageData($ruleId, $storeId)
287
+ {
288
+ if (!isset($this->_messageData[$ruleId][$storeId])) {
289
+ if ($data = $this->_getResource()->getStoreMessageData($ruleId, $storeId)) {
290
+ if (empty($data['message_id'])) {
291
+ $data['message_id'] = null;
292
+ }
293
+ $this->_messageData[$ruleId][$storeId] = $data;
294
+ } else {
295
+ return false;
296
+ }
297
+ }
298
+ return $this->_messageData[$ruleId][$storeId];
299
+ }
300
+
301
+ /**
302
+ * @param int $ruleId
303
+ * @param int $customerId
304
+ * @param string $messageId
305
+ * @return boolean|array
306
+ */
307
+ public function getRuleLogItems($ruleId, $customerId, $messageId = null)
308
+ {
309
+ if ($data = $this->_getResource()->getRuleLogItemsData($ruleId, $customerId, $messageId)) {
310
+ return $data;
311
+ }
312
+ return false;
313
+ }
314
+
315
+ /**
316
+ * Returns an array containing information for sending abandoned cart notifications
317
+ * to guest users who abandoned the checkout process.
318
+ *
319
+ * @return array
320
+ */
321
+ private function _getGuestAbandons()
322
+ {
323
+ $guestAbandons = Mage::getModel('bronto_reminder/guest')
324
+ ->getCollection()
325
+ ->addFieldToFilter('email_sent', array('eq' => 0));
326
+ $retVal = array();
327
+ $ruleId = null;
328
+ $couponId = null;
329
+ $schedule = null;
330
+
331
+ $currentDate = Mage::getModel('core/date')->date('Y-m-d');
332
+
333
+ $rules = $this->getCollection()->addDateFilter($currentDate)
334
+ ->addIsActiveFilter(1);
335
+
336
+ if ($ruleId = $this->getRuleId()) {
337
+ $rules->addRuleFilter($ruleId);
338
+ }
339
+
340
+ foreach($guestAbandons as $guest) {
341
+ foreach ($rules as $rule) {
342
+ $this->_getResource()->deactivateMatchedCustomers($rule->getId());
343
+
344
+ if ($rule->getSalesruleId()) {
345
+ /* @var $salesRule Mage_SalesRule_Model_Rule */
346
+ $salesRule = Mage::getSingleton('salesrule/rule')->load($rule->getSalesruleId());
347
+ $websiteIds = array_intersect($rule->getWebsiteIds(), $salesRule->getWebsiteIds());
348
+ $coupon = $salesRule->acquireCoupon();
349
+ $couponId = ($coupon !== null) ? $coupon->getId() : null;
350
+ } else {
351
+ $salesRule = null;
352
+ $websiteIds = $rule->getWebsiteIds();
353
+ }
354
+
355
+ $rule->setConditions(null);
356
+ $rule->afterLoad();
357
+
358
+ foreach ($websiteIds as $websiteId) {
359
+ // Saving matched guests
360
+ $retVal[] = array(
361
+ 'customer_id' => 0,
362
+ 'rule_id' => $rule->getId(),
363
+ 'coupon_id' => $couponId,
364
+ 'schedule' => $schedule,
365
+ // Additional index for guest abandons used to create the
366
+ // Magento Customer object when sending reminder emails
367
+ 'guest' => $guest,
368
+ );
369
+ }
370
+
371
+ $couponId = null;
372
+ }
373
+ }
374
+
375
+ return $retVal;
376
+ }
377
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart.php ADDED
@@ -0,0 +1,237 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Cart extends Bronto_Reminder_Model_Condition_Combine_Abstract
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_cart');
14
+ $this->setValue(null);
15
+ }
16
+
17
+ /**
18
+ * Get list of available subconditions
19
+ *
20
+ * @return array
21
+ */
22
+ public function getNewChildSelectOptions()
23
+ {
24
+ return Mage::getModel('bronto_reminder/rule_condition_cart_combine')->getNewChildSelectOptions();
25
+ }
26
+
27
+ /**
28
+ * Get input type for attribute value
29
+ *
30
+ * @return string
31
+ */
32
+ public function getValueElementType()
33
+ {
34
+ return 'text';
35
+ }
36
+
37
+ /**
38
+ * Override parent method
39
+ *
40
+ * @return Bronto_Reminder_Model_Rule_Condition_Cart
41
+ */
42
+ public function loadValueOptions()
43
+ {
44
+ $this->setValueOption(array());
45
+ return $this;
46
+ }
47
+
48
+ /**
49
+ * Prepare operator select options
50
+ *
51
+ * @return Bronto_Reminder_Model_Rule_Condition_Cart
52
+ */
53
+ public function loadOperatorOptions()
54
+ {
55
+ $this->setOperatorOption(array(
56
+ '==' => Mage::helper('rule')->__('for'),
57
+ '>' => Mage::helper('rule')->__('for greater than'),
58
+ '>=' => Mage::helper('rule')->__('for or greater than'),
59
+ '<' => Mage::helper('rule')->__('for less than'),
60
+ '<=' => Mage::helper('rule')->__('for or less than'),
61
+ ));
62
+ return $this;
63
+ }
64
+
65
+ /**
66
+ * Return required validation
67
+ *
68
+ * @return true
69
+ */
70
+ protected function _getRequiredValidation()
71
+ {
72
+ return true;
73
+ }
74
+
75
+ /**
76
+ * Init available options list
77
+ *
78
+ * @return Bronto_Reminder_Model_Rule_Condition_Cart_Amount
79
+ */
80
+ public function loadAttributeOptions()
81
+ {
82
+ $this->setAttributeOption(array(
83
+ 'days' => Mage::helper('bronto_reminder')->__('days'),
84
+ 'hours' => Mage::helper('bronto_reminder')->__('hours'),
85
+ 'minutes' => Mage::helper('bronto_reminder')->__('minutes')
86
+ ));
87
+ return $this;
88
+ }
89
+
90
+ /**
91
+ * Get HTML of condition string
92
+ *
93
+ * @return string
94
+ */
95
+ public function asHtml()
96
+ {
97
+ return $this->getTypeElementHtml()
98
+ . Mage::helper('bronto_reminder')->__('Shopping cart is not empty and abandoned %s %s %s and %s of these conditions match:',
99
+ $this->getOperatorElementHtml(),
100
+ $this->getValueElementHtml(),
101
+ $this->getAttributeElementHtml(),
102
+ $this->getAggregatorElement()->getHtml())
103
+ . $this->getRemoveLinkHtml();
104
+ }
105
+
106
+ /**
107
+ * Get condition SQL select
108
+ *
109
+ * @param int|Zend_Db_Expr $customer
110
+ * @param int|Zend_Db_Expr $website
111
+ * @return Varien_Db_Select
112
+ */
113
+ protected function _prepareConditionsSql($customer, $website)
114
+ {
115
+ $interval = Mage::helper('bronto_reminder')->getCronInterval();
116
+ $attributeValue = strtolower($this->getAttribute());
117
+
118
+ switch ($attributeValue) {
119
+ case 'hours':
120
+ $currentDateStart = now(false);
121
+ $durationSql = 'HOUR';
122
+ $conditionValue = (int) $this->getValue();
123
+ if ($conditionValue < 1) {
124
+ Mage::throwException(Mage::helper('bronto_reminder')->__('Root shopping cart condition should have %s value at least 1.', $attributeValue));
125
+ }
126
+ break;
127
+ case 'minutes':
128
+ $currentDateStart = now(false);
129
+ $durationSql = 'MINUTE';
130
+ $conditionValue = (int) $this->getValue();
131
+ if (!Mage::helper('bronto_common')->isTestModeEnabled()) {
132
+ if ($conditionValue < 30) {
133
+ Mage::throwException(Mage::helper('bronto_reminder')->__('Root shopping cart condition should have %s value at least 30.', $attributeValue));
134
+ }
135
+ }
136
+ break;
137
+ case 'days':
138
+ default:
139
+ $currentDateStart = now(true);
140
+ $durationSql = 'DAY';
141
+ $conditionValue = (int) $this->getValue();
142
+ if ($conditionValue < 1) {
143
+ Mage::throwException(Mage::helper('bronto_reminder')->__('Root shopping cart condition should have %s value at least 1.', $attributeValue));
144
+ }
145
+ break;
146
+ }
147
+
148
+ if ($conditionValue <= 0) {
149
+ Mage::throwException(Mage::helper('bronto_reminder')->__('Root shopping cart condition should have %s value greater than 0.', $attributeValue));
150
+ }
151
+
152
+ $table = $this->getResource()->getTable('sales/quote');
153
+ $operator = $this->getResource()->getSqlOperator($this->getOperator());
154
+
155
+ $select = $this->getResource()->createSelect();
156
+ $select->from(array('quote' => $table), array(new Zend_Db_Expr(1)));
157
+
158
+ $this->_limitByStoreWebsite($select, $website, 'quote.store_id');
159
+
160
+ if ($operator == '=') {
161
+ switch ($attributeValue) {
162
+ case 'hours':
163
+ // cart + X hour(s) <= [now] <= cart + (X hour(s) * 60) + interval minute(s)
164
+ // 3 hours: cart + 180 minutes <= [now] <= cart + 195 minutes
165
+ $conditionValueInMinutes = $conditionValue * 60;
166
+ $select->where("'{$currentDateStart}' >= DATE_ADD(quote.updated_at, INTERVAL ? HOUR)", $conditionValue);
167
+ $select->where("'{$currentDateStart}' <= DATE_ADD(quote.updated_at, INTERVAL ? MINUTE)", $conditionValueInMinutes + $interval);
168
+ break;
169
+ case 'minutes':
170
+ // cart + X minute(s) <= [now] <= cart + X minute(s) + interval minute(s)
171
+ // 60 minutes: cart + 60 minutes <= [now] <= cart + 75 minutes
172
+ $select->where("'{$currentDateStart}' >= DATE_ADD(quote.updated_at, INTERVAL ? MINUTE)", $conditionValue);
173
+ $select->where("'{$currentDateStart}' <= DATE_ADD(quote.updated_at, INTERVAL ? MINUTE)", $conditionValue + $interval);
174
+ break;
175
+ case 'days':
176
+ default:
177
+ // cart + X day(s) <= [now] <= cart + (X day(s) * 1440) + interval minute(s)
178
+ // 1 day: cart + 1 day <= [now] <= cart + 1455 minutes
179
+ $conditionValueInMinutes = $conditionValue * 1440;
180
+ $select->where("'{$currentDateStart}' >= DATE_ADD(quote.updated_at, INTERVAL ? DAY)", $conditionValue);
181
+ $select->where("'{$currentDateStart}' <= DATE_ADD(quote.updated_at, INTERVAL ? MINUTE)", $conditionValueInMinutes + $interval);
182
+ break;
183
+ }
184
+ } else {
185
+ if ($operator == '>=') {
186
+ if ($conditionValue > 0) {
187
+ $conditionValue--;
188
+ } else {
189
+ $currentDateStart = now();
190
+ }
191
+ } elseif ($operator == '<=') {
192
+ if ($conditionValue > 0) {
193
+ $conditionValue++;
194
+ } else {
195
+ $currentDateStart = now();
196
+ }
197
+ }
198
+
199
+ $select->where("DATE_SUB('{$currentDateStart}', INTERVAL ? {$durationSql}) {$operator} quote.updated_at", $conditionValue);
200
+ }
201
+
202
+ $select->where('quote.is_active = 1');
203
+ $select->where('quote.items_count > 0');
204
+ $select->where($this->_createCustomerFilter($customer, 'quote.customer_id'));
205
+ $select->limit(1);
206
+
207
+ return $select;
208
+ }
209
+
210
+ /**
211
+ * Get base SQL select
212
+ *
213
+ * @param int|Zend_Db_Expr $customer
214
+ * @param int|Zend_Db_Expr $website
215
+ * @return Varien_Db_Select
216
+ */
217
+ public function getConditionsSql($customer, $website)
218
+ {
219
+ $select = $this->_prepareConditionsSql($customer, $website);
220
+ $required = $this->_getRequiredValidation();
221
+ $aggregator = ($this->getAggregator() == 'all') ? ' AND ' : ' OR ';
222
+ $operator = $required ? '=' : '<>';
223
+ $conditions = array();
224
+
225
+ foreach ($this->getConditions() as $condition) {
226
+ if ($sql = $condition->getConditionsSql($customer, $website)) {
227
+ $conditions[] = "(IFNULL(($sql), 0) {$operator} 1)";
228
+ }
229
+ }
230
+
231
+ if (!empty($conditions)) {
232
+ $select->where(implode($aggregator, $conditions));
233
+ }
234
+
235
+ return $select;
236
+ }
237
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Amount.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Cart_Amount extends Bronto_Reminder_Model_Condition_Abstract
9
+ {
10
+ /**
11
+ * Description for protected
12
+ * @var string
13
+ */
14
+ protected $_inputType = 'numeric';
15
+
16
+ public function __construct()
17
+ {
18
+ parent::__construct();
19
+ $this->setType('bronto_reminder/rule_condition_cart_amount');
20
+ $this->setValue(null);
21
+ }
22
+
23
+ /**
24
+ * Get information for being presented in condition list
25
+ *
26
+ * @return array
27
+ */
28
+ public function getNewChildSelectOptions()
29
+ {
30
+ return array('value' => $this->getType(),
31
+ 'label' => Mage::helper('bronto_reminder')->__('Total Amount'));
32
+ }
33
+
34
+ /**
35
+ * Init available options list
36
+ *
37
+ * @return Bronto_Reminder_Model_Rule_Condition_Cart_Amount
38
+ */
39
+ public function loadAttributeOptions()
40
+ {
41
+ $this->setAttributeOption(array(
42
+ 'subtotal' => Mage::helper('bronto_reminder')->__('subtotal'),
43
+ 'grand_total' => Mage::helper('bronto_reminder')->__('grand total')
44
+ ));
45
+ return $this;
46
+ }
47
+
48
+ /**
49
+ * Condition string on conditions page
50
+ *
51
+ * @return string
52
+ */
53
+ public function asHtml()
54
+ {
55
+ return $this->getTypeElementHtml()
56
+ . Mage::helper('bronto_reminder')->__('Shopping cart %s amount %s %s:',
57
+ $this->getAttributeElementHtml(), $this->getOperatorElementHtml(), $this->getValueElementHtml())
58
+ . $this->getRemoveLinkHtml();
59
+ }
60
+
61
+ /**
62
+ * Build condition limitations sql string for specific website
63
+ *
64
+ * @param $customer
65
+ * @param int | Zend_Db_Expr $website
66
+ * @return Varien_Db_Select
67
+ */
68
+ public function getConditionsSql($customer, $website)
69
+ {
70
+ $table = $this->getResource()->getTable('sales/quote');
71
+ $operator = $this->getResource()->getSqlOperator($this->getOperator());
72
+
73
+ $select = $this->getResource()->createSelect();
74
+ $select->from(array('quote' => $table), array(new Zend_Db_Expr(1)));
75
+
76
+ switch ($this->getAttribute()) {
77
+ case 'subtotal':
78
+ $field = 'quote.base_subtotal';
79
+ break;
80
+ case 'grand_total':
81
+ $field = 'quote.base_grand_total';
82
+ break;
83
+ default:
84
+ Mage::throwException(Mage::helper('bronto_reminder')->__('Unknown quote total specified'));
85
+ }
86
+
87
+ $this->_limitByStoreWebsite($select, $website, 'quote.store_id');
88
+ $select->where('quote.is_active = 1');
89
+ $select->where("{$field} {$operator} ?", $this->getValue());
90
+ $select->where($this->_createCustomerFilter($customer, 'customer_id'));
91
+ $select->limit(1);
92
+ return $select;
93
+ }
94
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Attributes.php ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Cart_Attributes extends Bronto_Reminder_Model_Condition_Abstract
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_inputType = 'numeric';
14
+
15
+ public function __construct()
16
+ {
17
+ parent::__construct();
18
+ $this->setType('bronto_reminder/rule_condition_cart_attributes');
19
+ $this->setValue(null);
20
+ }
21
+
22
+ /**
23
+ * Get information for being presented in condition list
24
+ *
25
+ * @return array
26
+ */
27
+ public function getNewChildSelectOptions()
28
+ {
29
+ return array('value' => $this->getType(),
30
+ 'label' => Mage::helper('bronto_reminder')->__('Numeric Attribute'));
31
+ }
32
+
33
+ /**
34
+ * Init available options list
35
+ *
36
+ * @return Bronto_Reminder_Model_Rule_Condition_Cart_Attributes
37
+ */
38
+ public function loadAttributeOptions()
39
+ {
40
+ $this->setAttributeOption(array(
41
+ 'weight' => Mage::helper('bronto_reminder')->__('weight'),
42
+ 'row_weight' => Mage::helper('bronto_reminder')->__('row weight'),
43
+ 'qty' => Mage::helper('bronto_reminder')->__('quantity'),
44
+ 'price' => Mage::helper('bronto_reminder')->__('base price'),
45
+ 'base_cost' => Mage::helper('bronto_reminder')->__('base cost')
46
+ ));
47
+ return $this;
48
+ }
49
+
50
+ /**
51
+ * Condition string on conditions page
52
+ *
53
+ * @return string
54
+ */
55
+ public function asHtml()
56
+ {
57
+ return $this->getTypeElementHtml()
58
+ . Mage::helper('bronto_reminder')->__('Item %s %s %s:',
59
+ $this->getAttributeElementHtml(), $this->getOperatorElementHtml(), $this->getValueElementHtml())
60
+ . $this->getRemoveLinkHtml();
61
+ }
62
+
63
+ /**
64
+ * Build condition limitations sql string for specific website
65
+ *
66
+ * @param $customer
67
+ * @param int | Zend_Db_Expr $website
68
+ * @return Varien_Db_Select
69
+ */
70
+ public function getConditionsSql($customer, $website)
71
+ {
72
+ $quoteTable = $this->getResource()->getTable('sales/quote');
73
+ $quoteItemTable = $this->getResource()->getTable('sales/quote_item');
74
+ $operator = $this->getResource()->getSqlOperator($this->getOperator());
75
+
76
+ $select = $this->getResource()->createSelect();
77
+ $select->from(array('item' => $quoteItemTable), array(new Zend_Db_Expr(1)));
78
+
79
+ $select->joinInner(
80
+ array('quote' => $quoteTable),
81
+ 'item.quote_id = quote.entity_id',
82
+ array()
83
+ );
84
+
85
+ switch ($this->getAttribute()) {
86
+ case 'weight':
87
+ $field = 'item.weight';
88
+ break;
89
+ case 'row_weight':
90
+ $field = 'item.row_weight';
91
+ break;
92
+ case 'qty':
93
+ $field = 'item.qty';
94
+ break;
95
+ case 'price':
96
+ $field = 'item.price';
97
+ break;
98
+ case 'base_cost':
99
+ $field = 'item.base_cost';
100
+ break;
101
+ default:
102
+ Mage::throwException(Mage::helper('bronto_reminder')->__('Unknown attribute specified'));
103
+ }
104
+
105
+ $this->_limitByStoreWebsite($select, $website, 'quote.store_id');
106
+ $select->where('quote.is_active = 1');
107
+ $select->where("{$field} {$operator} ?", $this->getValue());
108
+ $select->where($this->_createCustomerFilter($customer, 'quote.customer_id'));
109
+ $select->limit(1);
110
+ return $select;
111
+ }
112
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Combine.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Cart_Combine extends Bronto_Reminder_Model_Condition_Combine_Abstract
9
+ {
10
+ /**
11
+ * Intialize model
12
+ *
13
+ * @return void
14
+ */
15
+ public function __construct()
16
+ {
17
+ parent::__construct();
18
+ $this->setType('bronto_reminder/rule_condition_cart_combine');
19
+ }
20
+
21
+ /**
22
+ * Get inherited conditions selectors
23
+ *
24
+ * @return array
25
+ */
26
+ public function getNewChildSelectOptions()
27
+ {
28
+ $prefix = 'bronto_reminder/rule_condition_cart_';
29
+
30
+ return array_merge_recursive(
31
+ parent::getNewChildSelectOptions(), array(
32
+ $this->_getRecursiveChildSelectOption(),
33
+ Mage::getModel("{$prefix}couponcode")->getNewChildSelectOptions(),
34
+ Mage::getModel("{$prefix}itemsquantity")->getNewChildSelectOptions(),
35
+ Mage::getModel("{$prefix}totalquantity")->getNewChildSelectOptions(),
36
+ Mage::getModel("{$prefix}virtual")->getNewChildSelectOptions(),
37
+ Mage::getModel("{$prefix}amount")->getNewChildSelectOptions(),
38
+ array( // subselection combo
39
+ 'value' => 'bronto_reminder/rule_condition_cart_subselection',
40
+ 'label' => Mage::helper('bronto_reminder')->__('Items Subselection')
41
+ )
42
+ )
43
+ );
44
+ }
45
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Couponcode.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Cart_Couponcode extends Bronto_Reminder_Model_Condition_Abstract
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_cart_couponcode');
14
+ $this->setValue(1);
15
+ }
16
+
17
+ /**
18
+ * Get inherited conditions selectors
19
+ *
20
+ * @return array
21
+ */
22
+ public function getNewChildSelectOptions()
23
+ {
24
+ return array('value' => $this->getType(),
25
+ 'label' => Mage::helper('bronto_reminder')->__('Coupon Code'));
26
+ }
27
+
28
+ /**
29
+ * Get HTML of condition string
30
+ *
31
+ * @return string
32
+ */
33
+ public function asHtml()
34
+ {
35
+ return $this->getTypeElementHtml()
36
+ . Mage::helper('bronto_reminder')->__('Shopping cart %s a coupon applied',
37
+ $this->getValueElementHtml())
38
+ . $this->getRemoveLinkHtml();
39
+ }
40
+
41
+ /**
42
+ * Get element type for value select
43
+ *
44
+ * @return string
45
+ */
46
+ public function getValueElementType()
47
+ {
48
+ return 'select';
49
+ }
50
+
51
+ /**
52
+ * Init list of available values
53
+ *
54
+ * @return Bronto_Reminder_Model_Rule_Condition_Cart_Couponcode
55
+ */
56
+ public function loadValueOptions()
57
+ {
58
+ $this->setValueOption(array(
59
+ '1' => Mage::helper('bronto_reminder')->__('has'),
60
+ '0' => Mage::helper('bronto_reminder')->__('does not have')
61
+ ));
62
+ return $this;
63
+ }
64
+
65
+ /**
66
+ * Get SQL select
67
+ *
68
+ * @param $customer
69
+ * @param int | Zend_Db_Expr $website
70
+ * @return Varien_Db_Select
71
+ */
72
+ public function getConditionsSql($customer, $website)
73
+ {
74
+ $table = $this->getResource()->getTable('sales/quote');
75
+ $inversion = ((int)$this->getValue() ? '' : '!');
76
+
77
+ $select = $this->getResource()->createSelect();
78
+ $select->from(array('quote' => $table), array(new Zend_Db_Expr(1)));
79
+
80
+ $this->_limitByStoreWebsite($select, $website, 'quote.store_id');
81
+ $select->where('quote.is_active = 1');
82
+ $select->where("{$inversion}(IFNULL(quote.coupon_code, '') <> '')");
83
+ $select->where($this->_createCustomerFilter($customer, 'quote.customer_id'));
84
+ $select->limit(1);
85
+
86
+ return $select;
87
+ }
88
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Itemsquantity.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Cart_Itemsquantity extends Bronto_Reminder_Model_Condition_Abstract
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_inputType = 'numeric';
14
+
15
+ public function __construct()
16
+ {
17
+ parent::__construct();
18
+ $this->setType('bronto_reminder/rule_condition_cart_itemsquantity');
19
+ $this->setValue(null);
20
+ }
21
+
22
+ /**
23
+ * Get inherited conditions selectors
24
+ *
25
+ * @return array
26
+ */
27
+ public function getNewChildSelectOptions()
28
+ {
29
+ return array('value' => $this->getType(),
30
+ 'label' => Mage::helper('bronto_reminder')->__('Cart Line Items'));
31
+ }
32
+
33
+ /**
34
+ * Get HTML of condition string
35
+ *
36
+ * @return string
37
+ */
38
+ public function asHtml()
39
+ {
40
+ return $this->getTypeElementHtml()
41
+ . Mage::helper('bronto_reminder')->__('Number of shopping cart line items %s %s:',
42
+ $this->getOperatorElementHtml(), $this->getValueElementHtml())
43
+ . $this->getRemoveLinkHtml();
44
+ }
45
+
46
+ /**
47
+ * Get SQL select for matching shopping cart items count
48
+ *
49
+ * @param $customer
50
+ * @param int | Zend_Db_Expr $website
51
+ * @return Varien_Db_Select
52
+ */
53
+ public function getConditionsSql($customer, $website)
54
+ {
55
+ $table = $this->getResource()->getTable('sales/quote');
56
+ $operator = $this->getResource()->getSqlOperator($this->getOperator());
57
+
58
+ $select = $this->getResource()->createSelect();
59
+ $select->from(array('quote' => $table), array(new Zend_Db_Expr(1)));
60
+
61
+ $this->_limitByStoreWebsite($select, $website, 'quote.store_id');
62
+ $select->where('quote.is_active = 1');
63
+ $select->where("quote.items_count {$operator} ?", $this->getValue());
64
+ $select->where($this->_createCustomerFilter($customer, 'quote.customer_id'));
65
+ $select->limit(1);
66
+
67
+ return $select;
68
+ }
69
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Sku.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Cart_Sku extends Bronto_Reminder_Model_Condition_Abstract
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_cart_sku');
14
+ $this->setValue(null);
15
+ }
16
+
17
+ /**
18
+ * Get inherited conditions selectors
19
+ *
20
+ * @return array
21
+ */
22
+ public function getNewChildSelectOptions()
23
+ {
24
+ return array('value' => $this->getType(),
25
+ 'label' => Mage::helper('bronto_reminder')->__('SKU'));
26
+ }
27
+
28
+ /**
29
+ * Get HTML of condition string
30
+ *
31
+ * @return string
32
+ */
33
+ public function asHtml()
34
+ {
35
+ return $this->getTypeElementHtml()
36
+ . Mage::helper('bronto_reminder')->__('Item SKU %s %s ',
37
+ $this->getOperatorElementHtml(), $this->getValueElementHtml())
38
+ . $this->getRemoveLinkHtml();
39
+ }
40
+
41
+ /**
42
+ * Initialize value select options
43
+ *
44
+ * @return Bronto_Reminder_Model_Rule_Condition_Wishlist_Sku
45
+ */
46
+ public function loadValueOptions()
47
+ {
48
+ $this->setValueOption(Mage::getSingleton('adminhtml/system_store')->getStoreOptionHash());
49
+ return $this;
50
+ }
51
+
52
+ /**
53
+ * Get SQL select
54
+ *
55
+ * @param $customer
56
+ * @param int | Zend_Db_Expr $website
57
+ * @return Varien_Db_Select
58
+ */
59
+ public function getConditionsSql($customer, $website)
60
+ {
61
+ $quoteTable = $this->getResource()->getTable('sales/quote');
62
+ $quoteItemTable = $this->getResource()->getTable('sales/quote_item');
63
+ $operator = $this->getResource()->getSqlOperator($this->getOperator());
64
+
65
+ $select = $this->getResource()->createSelect();
66
+ $select->from(array('item' => $quoteItemTable), array(new Zend_Db_Expr(1)));
67
+
68
+ $select->joinInner(
69
+ array('quote' => $quoteTable),
70
+ 'item.quote_id = quote.entity_id',
71
+ array()
72
+ );
73
+
74
+ $this->_limitByStoreWebsite($select, $website, 'quote.store_id');
75
+ $select->where('quote.is_active = 1');
76
+ $select->where("item.sku {$operator} ?", $this->getValue());
77
+ $select->where($this->_createCustomerFilter($customer, 'quote.customer_id'));
78
+ $select->limit(1);
79
+
80
+ return $select;
81
+ }
82
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Storeview.php ADDED
@@ -0,0 +1,117 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Cart_Storeview extends Bronto_Reminder_Model_Condition_Abstract
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_cart_storeview');
14
+ $this->setValue(null);
15
+ }
16
+
17
+ /**
18
+ * Get inherited conditions selectors
19
+ *
20
+ * @return array
21
+ */
22
+ public function getNewChildSelectOptions()
23
+ {
24
+ return array('value' => $this->getType(),
25
+ 'label' => Mage::helper('bronto_reminder')->__('Store View'));
26
+ }
27
+
28
+ /**
29
+ * Get HTML of condition string
30
+ *
31
+ * @return string
32
+ */
33
+ public function asHtml()
34
+ {
35
+ return $this->getTypeElementHtml()
36
+ . Mage::helper('bronto_reminder')->__('Item was added to shopping cart %s store view %s',
37
+ $this->getOperatorElementHtml(), $this->getValueElementHtml())
38
+ . $this->getRemoveLinkHtml();
39
+ }
40
+
41
+ /**
42
+ * Initialize value select options
43
+ *
44
+ * @return Bronto_Reminder_Model_Rule_Condition_Cart_Storeview
45
+ */
46
+ public function loadValueOptions()
47
+ {
48
+ $this->setValueOption(Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm());
49
+ return $this;
50
+ }
51
+
52
+ /**
53
+ * Get select options
54
+ *
55
+ * @return array
56
+ */
57
+ public function getValueSelectOptions()
58
+ {
59
+ return $this->getValueOption();
60
+ }
61
+
62
+ /**
63
+ * Get input type for attribute value.
64
+ *
65
+ * @return string
66
+ */
67
+ public function getValueElementType()
68
+ {
69
+ return 'select';
70
+ }
71
+
72
+ /**
73
+ * Prepare operator select options
74
+ *
75
+ * @return Bronto_Reminder_Model_Rule_Condition_Wishlist_Storeview
76
+ */
77
+ public function loadOperatorOptions()
78
+ {
79
+ parent::loadOperatorOptions();
80
+ $this->setOperatorOption(array(
81
+ '==' => Mage::helper('rule')->__('from'),
82
+ '!=' => Mage::helper('rule')->__('not from')
83
+ ));
84
+ return $this;
85
+ }
86
+
87
+ /**
88
+ * Get SQL select
89
+ *
90
+ * @param $customer
91
+ * @param int | Zend_Db_Expr $website
92
+ * @return Varien_Db_Select
93
+ */
94
+ public function getConditionsSql($customer, $website)
95
+ {
96
+ $quoteTable = $this->getResource()->getTable('sales/quote');
97
+ $quoteItemTable = $this->getResource()->getTable('sales/quote_item');
98
+ $operator = $this->getResource()->getSqlOperator($this->getOperator());
99
+
100
+ $select = $this->getResource()->createSelect();
101
+ $select->from(array('item' => $quoteItemTable), array(new Zend_Db_Expr(1)));
102
+
103
+ $select->joinInner(
104
+ array('quote' => $quoteTable),
105
+ 'item.quote_id = quote.entity_id',
106
+ array()
107
+ );
108
+
109
+ $this->_limitByStoreWebsite($select, $website, 'quote.store_id');
110
+ $select->where('quote.is_active = 1');
111
+ $select->where("item.store_id {$operator} ?", $this->getValue());
112
+ $select->where($this->_createCustomerFilter($customer, 'quote.customer_id'));
113
+ $select->limit(1);
114
+
115
+ return $select;
116
+ }
117
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Subcombine.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Cart_Subcombine extends Bronto_Reminder_Model_Condition_Combine_Abstract
9
+ {
10
+ /**
11
+ * Intialize model
12
+ *
13
+ * @return void
14
+ */
15
+ public function __construct()
16
+ {
17
+ parent::__construct();
18
+ $this->setType('bronto_reminder/rule_condition_cart_subcombine');
19
+ }
20
+
21
+ /**
22
+ * Get inherited conditions selectors
23
+ *
24
+ * @return array
25
+ */
26
+ public function getNewChildSelectOptions()
27
+ {
28
+ $prefix = 'bronto_reminder/rule_condition_cart_';
29
+
30
+ return array_merge_recursive(
31
+ parent::getNewChildSelectOptions(), array(
32
+ $this->_getRecursiveChildSelectOption(),
33
+ Mage::getModel("{$prefix}storeview")->getNewChildSelectOptions(),
34
+ Mage::getModel("{$prefix}sku")->getNewChildSelectOptions(),
35
+ Mage::getModel("{$prefix}attributes")->getNewChildSelectOptions()
36
+ )
37
+ );
38
+ }
39
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Subselection.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Cart_Subselection extends Bronto_Reminder_Model_Condition_Combine_Abstract
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_cart_subselection');
14
+ }
15
+
16
+ /**
17
+ * Get inherited conditions selectors
18
+ *
19
+ * @return array
20
+ */
21
+ public function getNewChildSelectOptions()
22
+ {
23
+ return Mage::getModel('bronto_reminder/rule_condition_cart_subcombine')->getNewChildSelectOptions();
24
+ }
25
+
26
+ /**
27
+ * Get element type for value select
28
+ *
29
+ * @return string
30
+ */
31
+ public function getValueElementType()
32
+ {
33
+ return 'select';
34
+ }
35
+
36
+ /**
37
+ * Prepare operator select options
38
+ *
39
+ * @return Bronto_Reminder_Model_Rule_Condition_Cart_Subselection
40
+ */
41
+ public function loadOperatorOptions()
42
+ {
43
+ parent::loadOperatorOptions();
44
+ $this->setOperatorOption(array(
45
+ '==' => Mage::helper('bronto_reminder')->__('found'),
46
+ '!=' => Mage::helper('bronto_reminder')->__('not found')
47
+ ));
48
+ return $this;
49
+ }
50
+
51
+ /**
52
+ * Get HTML of condition string
53
+ *
54
+ * @return string
55
+ */
56
+ public function asHtml()
57
+ {
58
+ return $this->getTypeElementHtml()
59
+ . Mage::helper('bronto_reminder')->__('If an item is %s in the shopping cart with %s of these conditions match:',
60
+ $this->getOperatorElementHtml(),
61
+ $this->getAggregatorElement()->getHtml())
62
+ . $this->getRemoveLinkHtml();
63
+ }
64
+
65
+ /**
66
+ * Build query for matching shopping cart items
67
+ *
68
+ * @param $customer
69
+ * @param int | Zend_Db_Expr $website
70
+ * @return Varien_Db_Select
71
+ */
72
+ protected function _prepareConditionsSql($customer, $website)
73
+ {
74
+ $select = $this->getResource()->createSelect();
75
+ $quoteTable = $this->getResource()->getTable('sales/quote');
76
+ $quoteItemTable = $this->getResource()->getTable('sales/quote_item');
77
+
78
+ $select->from(array('item' => $quoteItemTable), array(new Zend_Db_Expr(1)));
79
+
80
+ $select->joinInner(
81
+ array('quote' => $quoteTable),
82
+ 'item.quote_id = quote.entity_id',
83
+ array()
84
+ );
85
+
86
+ $this->_limitByStoreWebsite($select, $website, 'quote.store_id');
87
+ $select->where('quote.is_active = 1');
88
+ $select->where($this->_createCustomerFilter($customer, 'quote.customer_id'));
89
+ $select->limit(1);
90
+
91
+ return $select;
92
+ }
93
+
94
+ /**
95
+ * Check if validation should be strict
96
+ *
97
+ * @return bool
98
+ */
99
+ protected function _getRequiredValidation()
100
+ {
101
+ return ($this->getOperator() == '==');
102
+ }
103
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Totalquantity.php ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Cart_Totalquantity extends Bronto_Reminder_Model_Condition_Abstract
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_inputType = 'numeric';
14
+
15
+ public function __construct()
16
+ {
17
+ parent::__construct();
18
+ $this->setType('bronto_reminder/rule_condition_cart_totalquantity');
19
+ $this->setValue(null);
20
+ }
21
+
22
+ /**
23
+ * Get inherited conditions selectors
24
+ *
25
+ * @return array
26
+ */
27
+ public function getNewChildSelectOptions()
28
+ {
29
+ return array('value' => $this->getType(),
30
+ 'label' => Mage::helper('bronto_reminder')->__('Items Quantity'));
31
+ }
32
+
33
+ /**
34
+ * Get HTML of condition string
35
+ *
36
+ * @return string
37
+ */
38
+ public function asHtml()
39
+ {
40
+ return $this->getTypeElementHtml()
41
+ . Mage::helper('bronto_reminder')->__('Total shopping cart items quantity %s %s:',
42
+ $this->getOperatorElementHtml(), $this->getValueElementHtml())
43
+ . $this->getRemoveLinkHtml();
44
+ }
45
+
46
+ /**
47
+ * Get SQL select for matching shopping cart products count
48
+ *
49
+ * @param $customer
50
+ * @param int | Zend_Db_Expr $website
51
+ * @return Varien_Db_Select
52
+ */
53
+ public function getConditionsSql($customer, $website)
54
+ {
55
+ $table = $this->getResource()->getTable('sales/quote');
56
+ $operator = $this->getResource()->getSqlOperator($this->getOperator());
57
+
58
+ $select = $this->getResource()->createSelect();
59
+ $select->from(array('quote' => $table), array(new Zend_Db_Expr(1)));
60
+
61
+ $this->_limitByStoreWebsite($select, $website, 'quote.store_id');
62
+ $select->where('quote.is_active = 1');
63
+ $select->where("quote.items_qty {$operator} ?", $this->getValue());
64
+ $select->where($this->_createCustomerFilter($customer, 'quote.customer_id'));
65
+ $select->limit(1);
66
+
67
+ return $select;
68
+ }
69
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Cart/Virtual.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Cart_Virtual extends Bronto_Reminder_Model_Condition_Abstract
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_cart_virtual');
14
+ $this->setValue(1);
15
+ }
16
+
17
+ /**
18
+ * Get inherited conditions selectors
19
+ *
20
+ * @return array
21
+ */
22
+ public function getNewChildSelectOptions()
23
+ {
24
+ return array('value' => $this->getType(),
25
+ 'label' => Mage::helper('bronto_reminder')->__('Virtual Only'));
26
+ }
27
+
28
+ /**
29
+ * Get HTML of condition string
30
+ *
31
+ * @return string
32
+ */
33
+ public function asHtml()
34
+ {
35
+ return $this->getTypeElementHtml()
36
+ . Mage::helper('bronto_reminder')->__('Shopping cart %s only virtual items',
37
+ $this->getValueElementHtml())
38
+ . $this->getRemoveLinkHtml();
39
+ }
40
+
41
+ /**
42
+ * Get element type for value select
43
+ *
44
+ * @return string
45
+ */
46
+ public function getValueElementType()
47
+ {
48
+ return 'select';
49
+ }
50
+
51
+ /**
52
+ * Init list of available values
53
+ *
54
+ * @return Bronto_Reminder_Model_Rule_Condition_Cart_Virtual
55
+ */
56
+ public function loadValueOptions()
57
+ {
58
+ $this->setValueOption(array(
59
+ '1' => Mage::helper('bronto_reminder')->__('has'),
60
+ '0' => Mage::helper('bronto_reminder')->__('does not have')
61
+ ));
62
+ return $this;
63
+ }
64
+
65
+ /**
66
+ * Get SQL select
67
+ *
68
+ * @param $customer
69
+ * @param int | Zend_Db_Expr $website
70
+ * @return Varien_Db_Select
71
+ */
72
+ public function getConditionsSql($customer, $website)
73
+ {
74
+ $table = $this->getResource()->getTable('sales/quote');
75
+
76
+ $select = $this->getResource()->createSelect();
77
+ $select->from(array('quote' => $table), array(new Zend_Db_Expr(1)));
78
+
79
+ $this->_limitByStoreWebsite($select, $website, 'quote.store_id');
80
+ $select->where('quote.is_active = 1');
81
+ $select->where("quote.is_virtual = ?", $this->getValue());
82
+ $select->where($this->_createCustomerFilter($customer, 'quote.customer_id'));
83
+ $select->limit(1);
84
+
85
+ return $select;
86
+ }
87
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Combine.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Combine extends Bronto_Reminder_Model_Condition_Combine_Abstract
9
+ {
10
+ /**
11
+ * Intialize model
12
+ *
13
+ * @return void
14
+ */
15
+ public function __construct()
16
+ {
17
+ parent::__construct();
18
+ $this->setType('bronto_reminder/rule_condition_combine');
19
+ }
20
+
21
+ /**
22
+ * Get inherited conditions selectors
23
+ *
24
+ * @return array
25
+ */
26
+ public function getNewChildSelectOptions()
27
+ {
28
+ $conditions = array(
29
+ array(
30
+ 'value' => 'bronto_reminder/rule_condition_wishlist',
31
+ 'label' => Mage::helper('bronto_reminder')->__('Wishlist')),
32
+ array(
33
+ 'value' => 'bronto_reminder/rule_condition_cart',
34
+ 'label' => Mage::helper('bronto_reminder')->__('Shopping Cart')),
35
+ );
36
+
37
+ $conditions = array_merge_recursive(parent::getNewChildSelectOptions(), $conditions);
38
+ return $conditions;
39
+ }
40
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Combine/Root.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Combine_Root extends Bronto_Reminder_Model_Rule_Condition_Combine
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_combine_root');
14
+ }
15
+
16
+ /**
17
+ * Prepare base select with limitation by customer
18
+ *
19
+ * @param null | array | int | Mage_Customer_Model_Customer $customer
20
+ * @param int | Zend_Db_Expr $website
21
+ * @return Varien_Db_Select
22
+ */
23
+ protected function _prepareConditionsSql($customer, $website)
24
+ {
25
+ $select = $this->getResource()->createSelect();
26
+ $rootTable = $this->getResource()->getTable('customer/entity');
27
+ $couponTable = $this->getResource()->getTable('bronto_reminder/coupon');
28
+
29
+ $select->from(array('root' => $rootTable), array('entity_id'));
30
+
31
+ $select->joinLeft(
32
+ array('c' => $couponTable),
33
+ 'c.customer_id=root.entity_id AND c.rule_id=:rule_id',
34
+ array('c.coupon_id')
35
+ );
36
+
37
+ if ($customer === null) {
38
+ if (Mage::getSingleton('customer/config_share')->isWebsiteScope()) {
39
+ $select->where('website_id=?', $website);
40
+ }
41
+ }
42
+ return $select;
43
+ }
44
+
45
+ /**
46
+ * Get SQL select.
47
+ * Rewrited for cover root conditions combination with additional condition by customer
48
+ *
49
+ * @param Mage_Customer_Model_Customer | Zend_Db_Select | Zend_Db_Expr $customer
50
+ * @param int | Zend_Db_Expr $website
51
+ * @return Varien_Db_Select
52
+ */
53
+ public function getConditionsSql($customer, $website)
54
+ {
55
+ $select = $this->_prepareConditionsSql($customer, $website);
56
+ $required = $this->_getRequiredValidation();
57
+ $aggregator = ($this->getAggregator() == 'all') ? ' AND ' : ' OR ';
58
+ $operator = $required ? '=' : '<>';
59
+ $conditions = array();
60
+
61
+ foreach ($this->getConditions() as $condition) {
62
+ if ($sql = $condition->getConditionsSql($customer, $website)) {
63
+ $conditions[] = "(IFNULL(($sql), 0) {$operator} 1)";
64
+ }
65
+ }
66
+
67
+ if (!empty($conditions)) {
68
+ $select->where(implode($aggregator, $conditions));
69
+ }
70
+ else {
71
+ $select->reset();
72
+ }
73
+
74
+ return $select;
75
+ }
76
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist.php ADDED
@@ -0,0 +1,149 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Wishlist extends Bronto_Reminder_Model_Condition_Combine_Abstract
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_wishlist');
14
+ $this->setValue(null);
15
+ }
16
+
17
+ /**
18
+ * Get list of available subconditions
19
+ *
20
+ * @return array
21
+ */
22
+ public function getNewChildSelectOptions()
23
+ {
24
+ return Mage::getModel('bronto_reminder/rule_condition_wishlist_combine')->getNewChildSelectOptions();
25
+ }
26
+
27
+ /**
28
+ * Get input type for attribute value
29
+ *
30
+ * @return string
31
+ */
32
+ public function getValueElementType()
33
+ {
34
+ return 'text';
35
+ }
36
+
37
+ /**
38
+ * Override parent method
39
+ *
40
+ * @return Bronto_Reminder_Model_Rule_Condition_Wishlist
41
+ */
42
+ public function loadValueOptions()
43
+ {
44
+ $this->setValueOption(array());
45
+ return $this;
46
+ }
47
+
48
+ /**
49
+ * Prepare operator select options
50
+ *
51
+ * @return Bronto_Reminder_Model_Rule_Condition_Wishlist
52
+ */
53
+ public function loadOperatorOptions()
54
+ {
55
+ $this->setOperatorOption(array(
56
+ '==' => Mage::helper('rule')->__('for'),
57
+ '>' => Mage::helper('rule')->__('for greater than'),
58
+ '>=' => Mage::helper('rule')->__('for or greater than')
59
+ ));
60
+ return $this;
61
+ }
62
+
63
+ /**
64
+ * Return required validation
65
+ *
66
+ * @return true
67
+ */
68
+ protected function _getRequiredValidation()
69
+ {
70
+ return true;
71
+ }
72
+
73
+ /**
74
+ * Get HTML of condition string
75
+ *
76
+ * @return string
77
+ */
78
+ public function asHtml()
79
+ {
80
+ return $this->getTypeElementHtml()
81
+ . Mage::helper('bronto_reminder')->__('Wishlist is not empty and abandoned %s %s days and %s of these conditions match:',
82
+ $this->getOperatorElementHtml(),
83
+ $this->getValueElementHtml(),
84
+ $this->getAggregatorElement()->getHtml())
85
+ . $this->getRemoveLinkHtml();
86
+ }
87
+
88
+ /**
89
+ * Get condition SQL select
90
+ *
91
+ * @param $customer
92
+ * @param $website
93
+ * @return Varien_Db_Select
94
+ */
95
+ protected function _prepareConditionsSql($customer, $website)
96
+ {
97
+ $conditionValue = (int)$this->getValue();
98
+ if ($conditionValue < 1) {
99
+ Mage::throwException(Mage::helper('bronto_reminder')->__('Root wishlist condition should have days value at least 1.'));
100
+ }
101
+
102
+ $wishlistTable = $this->getResource()->getTable('wishlist/wishlist');
103
+ $wishlistItemTable = $this->getResource()->getTable('wishlist/item');
104
+ $operator = $this->getResource()->getSqlOperator($this->getOperator());
105
+
106
+ $select = $this->getResource()->createSelect();
107
+ $select->from(array('item' => $wishlistItemTable), array(new Zend_Db_Expr(1)));
108
+
109
+ $select->joinInner(
110
+ array('list' => $wishlistTable),
111
+ 'item.wishlist_id = list.wishlist_id',
112
+ array()
113
+ );
114
+
115
+ $this->_limitByStoreWebsite($select, $website, 'item.store_id');
116
+ $select->where("UNIX_TIMESTAMP('" . now() . "' - INTERVAL ? DAY) {$operator} UNIX_TIMESTAMP(list.updated_at)", $conditionValue);
117
+ $select->where($this->_createCustomerFilter($customer, 'list.customer_id'));
118
+ $select->limit(1);
119
+ return $select;
120
+ }
121
+
122
+ /**
123
+ * Get base SQL select
124
+ *
125
+ * @param $customer
126
+ * @param $website
127
+ * @return Varien_Db_Select
128
+ */
129
+ public function getConditionsSql($customer, $website)
130
+ {
131
+ $select = $this->_prepareConditionsSql($customer, $website);
132
+ $required = $this->_getRequiredValidation();
133
+ $aggregator = ($this->getAggregator() == 'all') ? ' AND ' : ' OR ';
134
+ $operator = $required ? '=' : '<>';
135
+ $conditions = array();
136
+
137
+ foreach ($this->getConditions() as $condition) {
138
+ if ($sql = $condition->getConditionsSql($customer, $website)) {
139
+ $conditions[] = "(IFNULL(($sql), 0) {$operator} 1)";
140
+ }
141
+ }
142
+
143
+ if (!empty($conditions)) {
144
+ $select->where(implode($aggregator, $conditions));
145
+ }
146
+
147
+ return $select;
148
+ }
149
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Attributes.php ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Wishlist_Attributes extends Mage_CatalogRule_Model_Rule_Condition_Product
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_wishlist_attributes');
14
+ $this->setValue(null);
15
+ }
16
+
17
+ /**
18
+ * Customize default operator input by type mapper for some types
19
+ * @return array
20
+ */
21
+ public function getDefaultOperatorInputByType()
22
+ {
23
+ if (null === $this->_defaultOperatorInputByType) {
24
+ parent::getDefaultOperatorInputByType();
25
+ $this->_defaultOperatorInputByType['numeric'] = array('==', '!=', '>=', '>', '<=', '<');
26
+ $this->_defaultOperatorInputByType['string'] = array('==', '!=', '{}', '!{}');
27
+ $this->_defaultOperatorInputByType['category'] = array('{}', '!{}');
28
+ }
29
+ return $this->_defaultOperatorInputByType;
30
+ }
31
+
32
+ /**
33
+ * Get input type for attribute operators.
34
+ *
35
+ * @return string
36
+ */
37
+ public function getInputType()
38
+ {
39
+ if (!is_object($this->getAttributeObject())) {
40
+ return 'string';
41
+ }
42
+ if ($this->getAttributeObject()->getAttributeCode()=='category_ids') {
43
+ return 'category';
44
+ }
45
+ $input = $this->getAttributeObject()->getFrontendInput();
46
+ switch ($input) {
47
+ case 'select':
48
+ case 'multiselect':
49
+ case 'date':
50
+ return $input;
51
+ default:
52
+ return 'string';
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Get inherited conditions selectors
58
+ *
59
+ * @return array
60
+ */
61
+ public function getNewChildSelectOptions()
62
+ {
63
+ $attributes = $this->loadAttributeOptions()->getAttributeOption();
64
+ $conditions = array();
65
+ foreach ($attributes as $code => $label) {
66
+ $conditions[] = array('value' => $this->getType() . '|' . $code, 'label' => $label);
67
+ }
68
+
69
+ return array(
70
+ 'value' => $conditions,
71
+ 'label' => Mage::helper('bronto_reminder')->__('Product Attributes')
72
+ );
73
+ }
74
+
75
+ /**
76
+ * Get HTML of condition string
77
+ *
78
+ * @return string
79
+ */
80
+ public function asHtml()
81
+ {
82
+ return Mage::helper('bronto_reminder')->__('Product %s', strtolower(parent::asHtml()));
83
+ }
84
+
85
+ /**
86
+ * Get product attribute object
87
+ *
88
+ * @return Mage_Catalog_Model_Resource_Eav_Attribute
89
+ */
90
+ public function getAttributeObject()
91
+ {
92
+ return Mage::getSingleton('eav/config')->getAttribute('catalog_product', $this->getAttribute());
93
+ }
94
+
95
+ /**
96
+ * Get resource
97
+ *
98
+ * @return Bronto_Reminder_Model_Mysql4_Rule
99
+ */
100
+ public function getResource()
101
+ {
102
+ return Mage::getResourceSingleton('bronto_reminder/rule');
103
+ }
104
+
105
+ /**
106
+ * Get used subfilter type
107
+ *
108
+ * @return string
109
+ */
110
+ public function getSubfilterType()
111
+ {
112
+ return 'product';
113
+ }
114
+
115
+ /**
116
+ * Apply product attribute subfilter to parent/base condition query
117
+ *
118
+ * @param string $fieldName base query field name
119
+ * @param bool $requireValid strict validation flag
120
+ * @param $website
121
+ * @return string
122
+ */
123
+ public function getSubfilterSql($fieldName, $requireValid, $website)
124
+ {
125
+ $attribute = $this->getAttributeObject();
126
+ $table = $attribute->getBackendTable();
127
+
128
+ $resource = $this->getResource();
129
+ $select = $resource->createSelect();
130
+ $select->from(array('main' => $table), array('entity_id'));
131
+
132
+ if ($attribute->getAttributeCode() == 'category_ids') {
133
+ $condition = $resource->createConditionSql(
134
+ 'cat.category_id', $this->getOperator(), explode(',', $this->getValue())
135
+ );
136
+ $categorySelect = $resource->createSelect();
137
+ $categorySelect->from(array('cat' => $resource->getTable('catalog/category_product')), 'product_id')
138
+ ->where($condition);
139
+ $condition = 'main.entity_id IN (' . $categorySelect . ')';
140
+ } elseif ($attribute->isStatic()) {
141
+ $condition = $this->getResource()->createConditionSql(
142
+ "main.{$attribute->getAttributeCode()}", $this->getOperator(), $this->getValue()
143
+ );
144
+ } else {
145
+ $select->where('main.attribute_id = ?', $attribute->getId());
146
+ $select->join(
147
+ array('store' => $this->getResource()->getTable('core/store')),
148
+ 'main.store_id=store.store_id',
149
+ array())
150
+ ->where('store.website_id IN(?)', array(0, $website));
151
+ $condition = $this->getResource()->createConditionSql(
152
+ 'main.value', $this->getOperator(), $this->getValue()
153
+ );
154
+ }
155
+ $select->where($condition);
156
+ $inOperator = ($requireValid ? 'IN' : 'NOT IN');
157
+ return sprintf("%s %s (%s)", $fieldName, $inOperator, $select);
158
+ }
159
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Combine.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Wishlist_Combine extends Bronto_Reminder_Model_Condition_Combine_Abstract
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_wishlist_combine');
14
+ }
15
+
16
+ /**
17
+ * Get inherited conditions selectors
18
+ *
19
+ * @return array
20
+ */
21
+ public function getNewChildSelectOptions()
22
+ {
23
+ $prefix = 'bronto_reminder/rule_condition_wishlist_';
24
+
25
+ return array_merge_recursive(
26
+ parent::getNewChildSelectOptions(), array(
27
+ $this->_getRecursiveChildSelectOption(),
28
+ Mage::getModel("{$prefix}sharing")->getNewChildSelectOptions(),
29
+ Mage::getModel("{$prefix}quantity")->getNewChildSelectOptions(),
30
+ array( // subselection combo
31
+ 'value' => 'bronto_reminder/rule_condition_wishlist_subselection',
32
+ 'label' => Mage::helper('bronto_reminder')->__('Items Subselection')
33
+ )
34
+ )
35
+ );
36
+ }
37
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Quantity.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Wishlist_Quantity extends Bronto_Reminder_Model_Condition_Abstract
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_inputType = 'numeric';
14
+
15
+ public function __construct()
16
+ {
17
+ parent::__construct();
18
+ $this->setType('bronto_reminder/rule_condition_wishlist_quantity');
19
+ $this->setValue(null);
20
+ }
21
+
22
+ /**
23
+ * Get inherited conditions selectors
24
+ *
25
+ * @return array
26
+ */
27
+ public function getNewChildSelectOptions()
28
+ {
29
+ return array('value' => $this->getType(),
30
+ 'label' => Mage::helper('bronto_reminder')->__('Number of Items'));
31
+ }
32
+
33
+ /**
34
+ * Get HTML of condition string
35
+ *
36
+ * @return string
37
+ */
38
+ public function asHtml()
39
+ {
40
+ return $this->getTypeElementHtml()
41
+ . Mage::helper('bronto_reminder')->__('Number of wishlist items %s %s ',
42
+ $this->getOperatorElementHtml(), $this->getValueElementHtml())
43
+ . $this->getRemoveLinkHtml();
44
+ }
45
+
46
+ /**
47
+ * Get SQL select
48
+ *
49
+ * @param $customer
50
+ * @param int | Zend_Db_Expr $website
51
+ * @return Varien_Db_Select
52
+ */
53
+ public function getConditionsSql($customer, $website)
54
+ {
55
+ $wishlistTable = $this->getResource()->getTable('wishlist/wishlist');
56
+ $wishlistItemTable = $this->getResource()->getTable('wishlist/item');
57
+ $operator = $this->getResource()->getSqlOperator($this->getOperator());
58
+ $result = "IF (COUNT(*) {$operator} {$this->getValue()}, 1, 0)";
59
+
60
+ $select = $this->getResource()->createSelect();
61
+ $select->from(array('item' => $wishlistItemTable), array(new Zend_Db_Expr($result)));
62
+
63
+ $select->joinInner(
64
+ array('list' => $wishlistTable),
65
+ 'item.wishlist_id = list.wishlist_id',
66
+ array()
67
+ );
68
+
69
+ $this->_limitByStoreWebsite($select, $website, 'item.store_id');
70
+ $select->where($this->_createCustomerFilter($customer, 'list.customer_id'));
71
+ return $select;
72
+ }
73
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Sharing.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Wishlist_Sharing extends Bronto_Reminder_Model_Condition_Abstract
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_wishlist_sharing');
14
+ $this->setValue(1);
15
+ }
16
+
17
+ /**
18
+ * Get inherited conditions selectors
19
+ *
20
+ * @return array
21
+ */
22
+ public function getNewChildSelectOptions()
23
+ {
24
+ return array('value' => $this->getType(),
25
+ 'label' => Mage::helper('bronto_reminder')->__('Sharing'));
26
+ }
27
+
28
+ /**
29
+ * Get HTML of condition string
30
+ *
31
+ * @return string
32
+ */
33
+ public function asHtml()
34
+ {
35
+ return $this->getTypeElementHtml()
36
+ . Mage::helper('bronto_reminder')->__('Wishlist %s shared',
37
+ $this->getValueElementHtml())
38
+ . $this->getRemoveLinkHtml();
39
+ }
40
+
41
+ /**
42
+ * Get element type for value select
43
+ *
44
+ * @return string
45
+ */
46
+ public function getValueElementType()
47
+ {
48
+ return 'select';
49
+ }
50
+
51
+ /**
52
+ * Init list of available values
53
+ *
54
+ * @return Bronto_Reminder_Model_Rule_Condition_Wishlist_Sharing
55
+ */
56
+ public function loadValueOptions()
57
+ {
58
+ $this->setValueOption(array(
59
+ '1' => Mage::helper('bronto_reminder')->__('is'),
60
+ '0' => Mage::helper('bronto_reminder')->__('is not'),
61
+ ));
62
+ return $this;
63
+ }
64
+
65
+ /**
66
+ * Get SQL select
67
+ *
68
+ * @param $customer
69
+ * @param int | Zend_Db_Expr $website
70
+ * @return Varien_Db_Select
71
+ */
72
+ public function getConditionsSql($customer, $website)
73
+ {
74
+ $table = $this->getResource()->getTable('wishlist/wishlist');
75
+
76
+ $select = $this->getResource()->createSelect();
77
+ $select->from(array('list' => $table), array(new Zend_Db_Expr(1)));
78
+ $select->where("list.shared = ?", $this->getValue());
79
+ $select->where($this->_createCustomerFilter($customer, 'list.customer_id'));
80
+ $select->limit(1);
81
+
82
+ return $select;
83
+ }
84
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Storeview.php ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Wishlist_Storeview extends Bronto_Reminder_Model_Condition_Abstract
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_wishlist_storeview');
14
+ $this->setValue(null);
15
+ }
16
+
17
+ /**
18
+ * Get inherited conditions selectors
19
+ *
20
+ * @return array
21
+ */
22
+ public function getNewChildSelectOptions()
23
+ {
24
+ return array('value' => $this->getType(),
25
+ 'label' => Mage::helper('bronto_reminder')->__('Store View'));
26
+ }
27
+
28
+ /**
29
+ * Get HTML of condition string
30
+ *
31
+ * @return string
32
+ */
33
+ public function asHtml()
34
+ {
35
+ return $this->getTypeElementHtml()
36
+ . Mage::helper('bronto_reminder')->__('Item was added to wishlist %s store view %s',
37
+ $this->getOperatorElementHtml(), $this->getValueElementHtml())
38
+ . $this->getRemoveLinkHtml();
39
+ }
40
+
41
+ /**
42
+ * Initialize value select options
43
+ *
44
+ * @return Bronto_Reminder_Model_Rule_Condition_Wishlist_Storeview
45
+ */
46
+ public function loadValueOptions()
47
+ {
48
+ $this->setValueOption(Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm());
49
+ return $this;
50
+ }
51
+
52
+ /**
53
+ * Get select options
54
+ *
55
+ * @return array
56
+ */
57
+ public function getValueSelectOptions()
58
+ {
59
+ return $this->getValueOption();
60
+ }
61
+
62
+ /**
63
+ * Get input type for attribute value.
64
+ *
65
+ * @return string
66
+ */
67
+ public function getValueElementType()
68
+ {
69
+ return 'select';
70
+ }
71
+
72
+ /**
73
+ * Prepare operator select options
74
+ *
75
+ * @return Bronto_Reminder_Model_Rule_Condition_Wishlist_Storeview
76
+ */
77
+ public function loadOperatorOptions()
78
+ {
79
+ parent::loadOperatorOptions();
80
+ $this->setOperatorOption(array(
81
+ '==' => Mage::helper('rule')->__('from'),
82
+ '!=' => Mage::helper('rule')->__('not from')
83
+ ));
84
+ return $this;
85
+ }
86
+
87
+ /**
88
+ * Get SQL select
89
+ *
90
+ * @param $customer
91
+ * @param int | Zend_Db_Expr $website
92
+ * @return Varien_Db_Select
93
+ */
94
+ public function getConditionsSql($customer, $website)
95
+ {
96
+ $wishlistTable = $this->getResource()->getTable('wishlist/wishlist');
97
+ $wishlistItemTable = $this->getResource()->getTable('wishlist/item');
98
+ $operator = $this->getResource()->getSqlOperator($this->getOperator());
99
+
100
+ $select = $this->getResource()->createSelect();
101
+ $select->from(array('item' => $wishlistItemTable), array(new Zend_Db_Expr(1)));
102
+
103
+ $select->joinInner(
104
+ array('list' => $wishlistTable),
105
+ 'item.wishlist_id = list.wishlist_id',
106
+ array()
107
+ );
108
+
109
+ $this->_limitByStoreWebsite($select, $website, 'item.store_id');
110
+ $select->where("item.store_id {$operator} ?", $this->getValue());
111
+ $select->where($this->_createCustomerFilter($customer, 'list.customer_id'));
112
+ $select->limit(1);
113
+
114
+ return $select;
115
+ }
116
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Subcombine.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Wishlist_Subcombine extends Bronto_Reminder_Model_Condition_Combine_Abstract
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_wishlist_subcombine');
14
+ }
15
+
16
+ /**
17
+ * Get inherited conditions selectors
18
+ *
19
+ * @return array
20
+ */
21
+ public function getNewChildSelectOptions()
22
+ {
23
+ $prefix = 'bronto_reminder/rule_condition_wishlist_';
24
+
25
+ return array_merge_recursive(
26
+ parent::getNewChildSelectOptions(), array(
27
+ $this->_getRecursiveChildSelectOption(),
28
+ Mage::getModel("{$prefix}storeview")->getNewChildSelectOptions(),
29
+ Mage::getModel("{$prefix}attributes")->getNewChildSelectOptions()
30
+ )
31
+ );
32
+ }
33
+ }
app/code/community/Bronto/Reminder/Model/Rule/Condition/Wishlist/Subselection.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_Rule_Condition_Wishlist_Subselection extends Bronto_Reminder_Model_Condition_Combine_Abstract
9
+ {
10
+ public function __construct()
11
+ {
12
+ parent::__construct();
13
+ $this->setType('bronto_reminder/rule_condition_wishlist_subselection');
14
+ }
15
+
16
+ /**
17
+ * Get inherited conditions selectors
18
+ *
19
+ * @return array
20
+ */
21
+ public function getNewChildSelectOptions()
22
+ {
23
+ return Mage::getModel('bronto_reminder/rule_condition_wishlist_subcombine')->getNewChildSelectOptions();
24
+ }
25
+
26
+ /**
27
+ * Get element type for value select
28
+ *
29
+ * @return string
30
+ */
31
+ public function getValueElementType()
32
+ {
33
+ return 'select';
34
+ }
35
+
36
+ /**
37
+ * Prepare operator select options
38
+ *
39
+ * @return Bronto_Reminder_Model_Rule_Condition_Wishlist_Subselection
40
+ */
41
+ public function loadOperatorOptions()
42
+ {
43
+ parent::loadOperatorOptions();
44
+ $this->setOperatorOption(array(
45
+ '==' => Mage::helper('bronto_reminder')->__('found'),
46
+ '!=' => Mage::helper('bronto_reminder')->__('not found')
47
+ ));
48
+ return $this;
49
+ }
50
+
51
+ /**
52
+ * Get HTML of condition string
53
+ *
54
+ * @return string
55
+ */
56
+ public function asHtml()
57
+ {
58
+ return $this->getTypeElementHtml()
59
+ . Mage::helper('bronto_reminder')->__('If an item is %s in the wishlist with %s of these conditions match:',
60
+ $this->getOperatorElementHtml(),
61
+ $this->getAggregatorElement()->getHtml())
62
+ . $this->getRemoveLinkHtml();
63
+ }
64
+
65
+ /**
66
+ * Build query for matching wishlist items
67
+ *
68
+ * @param $customer
69
+ * @param int | Zend_Db_Expr $website
70
+ * @return Varien_Db_Select
71
+ */
72
+ protected function _prepareConditionsSql($customer, $website)
73
+ {
74
+ $wishlistTable = $this->getResource()->getTable('wishlist/wishlist');
75
+ $wishlistItemTable = $this->getResource()->getTable('wishlist/item');
76
+
77
+ $select = $this->getResource()->createSelect();
78
+ $select->from(array('item' => $wishlistItemTable), array(new Zend_Db_Expr(1)));
79
+
80
+ $select->joinInner(
81
+ array('list' => $wishlistTable),
82
+ 'item.wishlist_id = list.wishlist_id',
83
+ array()
84
+ );
85
+
86
+ $this->_limitByStoreWebsite($select, $website, 'item.store_id');
87
+ $select->where($this->_createCustomerFilter($customer, 'list.customer_id'));
88
+ $select->limit(1);
89
+
90
+ return $select;
91
+ }
92
+
93
+ /**
94
+ * Check if validation should be strict
95
+ *
96
+ * @return bool
97
+ */
98
+ protected function _getRequiredValidation()
99
+ {
100
+ return ($this->getOperator() == '==');
101
+ }
102
+
103
+ /**
104
+ * Get field names map for subfilter conditions
105
+ *
106
+ * @return array
107
+ */
108
+ protected function _getSubfilterMap()
109
+ {
110
+ return array(
111
+ 'product' => 'item.product_id'
112
+ );
113
+ }
114
+ }
app/code/community/Bronto/Reminder/Model/System/Config/Backend/Cron.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Model_System_Config_Backend_Cron extends Bronto_Common_Model_System_Config_Backend_Cron
9
+ {
10
+ /**
11
+ * @var string
12
+ */
13
+ protected $_cron_string_path = 'crontab/jobs/bronto_reminder_send_notification/schedule/cron_expr';
14
+
15
+ /**
16
+ * @var string
17
+ */
18
+ protected $_cron_model_path = 'crontab/jobs/bronto_reminder_send_notification/run/model';
19
+ }
app/code/community/Bronto/Reminder/Test/Config/Config.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_Reminder_Test_Config_Config
3
+ extends EcomDev_PHPUnit_Test_Case_Config
4
+ {
5
+ public function blocksProvider()
6
+ {
7
+ return array();
8
+ }
9
+
10
+ public function modelsProvider()
11
+ {
12
+ return array(
13
+ array('bronto_reminder/rule', 'Bronto_Reminder_Model_Rule'),
14
+ array('bronto_reminder/email_message', 'Bronto_Reminder_Model_Email_Message'),
15
+ array('bronto_reminder/rule_mysql4', 'Bronto_Reminder_Model_Mysql4_rule'),
16
+ );
17
+ }
18
+
19
+ public function helpersProvider()
20
+ {
21
+ return array(
22
+ array('bronto_reminder/data', 'Bronto_Reminder_Helper_Data'),
23
+ array('bronto_reminder/message', 'Bronto_Reminder_Helper_Message'),
24
+ array('bronto_reminder/contact', 'Bronto_Reminder_Helper_Contact'),
25
+ );
26
+ }
27
+
28
+ public function observersProvider()
29
+ {
30
+ return array(
31
+ array('adminhtml', 'controller_action_predispatch', 'bronto_reminder/observer', 'checkBrontoRequirements'),
32
+ array('global', 'salesrule_rule_get_coupon_types', 'bronto_reminder/observer', 'getCouponTypes'),
33
+ array('global', 'checkout_allow_guest', 'bronto_reminder/observer', 'storeGuestEmailCheckout'),
34
+ array('global', 'adminhtml_promo_quote_edit_tab_main_prepare_form', 'bronto_reminder/observer', 'updatePromoQuoteTabMainForm'),
35
+ array('frontend', 'sales_quote_save_before', 'bronto_reminder/observer', 'storeGuestEmailCheckout'),
36
+ );
37
+ }
38
+
39
+ public function dependsProvider()
40
+ {
41
+ return array(
42
+ array('Bronto_Common'),
43
+ array('Mage_Wishlist'),
44
+ array('Mage_SalesRule'),
45
+ );
46
+ }
47
+
48
+
49
+ public function definedLayoutFilesProvider()
50
+ {
51
+ return array(
52
+ array('adminhtml', 'bronto/reminder.xml'),
53
+ );
54
+ }
55
+
56
+ public function themeLayoutFilesExistProvider()
57
+ {
58
+ return array(
59
+ array('adminhtml', 'bronto/reminder.xml', 'default', 'default'),
60
+ );
61
+ }
62
+
63
+ /**
64
+ * @test
65
+ * @group amd
66
+ * @group config
67
+ */
68
+ public function assertReminderModuleVersionGreaterThanOrEquals()
69
+ {
70
+ $this->assertModuleVersionGreaterThanOrEquals('1.4.10');
71
+ }
72
+
73
+ /**
74
+ * @test
75
+ * @group amd
76
+ * @group config
77
+ */
78
+ public function assertReminderModuleInCommunityCodePool()
79
+ {
80
+ $this->assertModuleCodePool('community');
81
+ }
82
+
83
+ /**
84
+ * @test
85
+ * @group amd
86
+ * @group config
87
+ * @dataProvider dependsProvider
88
+ */
89
+ public function assertReminderModuleDepends(
90
+ $requiredModuleName
91
+ ) {
92
+ $this->assertModuleDepends($requiredModuleName);
93
+ }
94
+
95
+ /**
96
+ * test
97
+ * @group amd
98
+ * @group config
99
+ * @dataProvider modelsProvider
100
+ */
101
+ public function assertReminderModelAliases(
102
+ $classAlias,
103
+ $expectedClassName
104
+ ) {
105
+ $this->assertModelAlias($classAlias, $expectedClassName);
106
+ }
107
+
108
+ /**
109
+ * test
110
+ * @group amd
111
+ * @group config
112
+ * @dataProvider blocksProvider
113
+ */
114
+ public function assertReminderBlockAliases(
115
+ $classAlias,
116
+ $expectedClassName
117
+ ) {
118
+ $this->assertBlockAlias($classAlias, $expectedClassName);
119
+ }
120
+
121
+ /**
122
+ * @test
123
+ * @group amd
124
+ * @group config
125
+ * @dataProvider helpersProvider
126
+ */
127
+ public function assertReminderHelperAliases(
128
+ $classAlias,
129
+ $expectedClassName
130
+ ) {
131
+ $this->assertHelperAlias($classAlias, $expectedClassName);
132
+ }
133
+
134
+ /**
135
+ * @test
136
+ * @group amd
137
+ * @group config
138
+ * @dataProvider observersProvider
139
+ */
140
+ function assertReminderEventObserversDefined (
141
+ $area,
142
+ $eventName,
143
+ $observerClassAlias,
144
+ $observerMethod
145
+ ) {
146
+ $this->assertEventObserverDefined(
147
+ $area,
148
+ $eventName,
149
+ $observerClassAlias,
150
+ $observerMethod
151
+ );
152
+ }
153
+
154
+ /**
155
+ * @test
156
+ * @group amd
157
+ * @group config
158
+ * @dataProvider definedLayoutFilesProvider
159
+ */
160
+ public function assertReminderLayoutFileDefined (
161
+ $area,
162
+ $expectedFileName
163
+ ) {
164
+ $this->assertLayoutFileDefined($area, $expectedFileName);
165
+ }
166
+
167
+ /**
168
+ * @test
169
+ * @group amd
170
+ * @group config
171
+ * @dataProvider themeLayoutFilesExistProvider
172
+ */
173
+ public function assertReminderLayoutFileExistsInTheme (
174
+ $area,
175
+ $filename,
176
+ $theme,
177
+ $designPackage
178
+ ) {
179
+ $this->assertLayoutFileExistsInTheme(
180
+ $area,
181
+ $filename,
182
+ $theme,
183
+ $designPackage
184
+ );
185
+ }
186
+
187
+ }
app/code/community/Bronto/Reminder/Test/Helper/Contact.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_Reminder_Test_Helper_Contact
3
+ extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+ private $_helper;
6
+
7
+ protected function setUp()
8
+ {
9
+ $this->_helper = Mage::helper('bronto_reminder/contact');
10
+ }
11
+
12
+ /**
13
+ * @test
14
+ * @group amd
15
+ * @group helper
16
+ */
17
+ public function helperShouldProvideCorrectClass()
18
+ {
19
+ $this->assertInstanceOf('Bronto_Reminder_Helper_Contact', $this->_helper);
20
+ }
21
+
22
+ /**
23
+ * @test
24
+ * @group amd
25
+ * @group helper
26
+ */
27
+ public function getContactByEmail_ShouldReturnBrontoApiContactRow()
28
+ {
29
+ $this->assertInstanceOf('Bronto_Api_Contact_Row', $this->_helper->getContactByEmail('email@domain.com'));
30
+ }
31
+ }
app/code/community/Bronto/Reminder/Test/Helper/Data.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_Reminder_Test_Helper_Data
3
+ extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+ private $_helper;
6
+
7
+ protected function setUp()
8
+ {
9
+ $this->_helper = Mage::helper('bronto_reminder/data');
10
+ }
11
+
12
+ /**
13
+ * @test
14
+ * @group amd
15
+ * @group helper
16
+ */
17
+ public function mageHelperShouldProvideCorrectClass()
18
+ {
19
+ $this->assertInstanceOf('Bronto_Reminder_Helper_Data', $this->_helper);
20
+ }
21
+
22
+ /**
23
+ * @test
24
+ * @group amd
25
+ * @group helper
26
+ */
27
+ public function isEnabled_ShouldReturnBool()
28
+ {
29
+ $isEnabled = $this->_helper->isEnabled();
30
+ $this->assertInternalType('bool', $isEnabled);
31
+ }
32
+
33
+ /**
34
+ * @test
35
+ * @group amd
36
+ * @group helper
37
+ */
38
+ public function isEnabled_ShouldReturnTrue()
39
+ {
40
+ Mage::getConfig()->saveConfig('bronto_reminder/settings/enabled', 1);
41
+ Mage::getConfig()->reinit();
42
+ Mage::app()->reinitStores();
43
+ $this->assertTrue($this->_helper->isEnabled());
44
+ }
45
+
46
+ /**
47
+ * @test
48
+ * @group amd
49
+ * @group helper
50
+ */
51
+ public function disableModule_ShouldDisableModule()
52
+ {
53
+ $this->_helper->disableModule();
54
+ Mage::getConfig()->reinit();
55
+ Mage::app()->reinitStores();
56
+ $this->assertFalse($this->_helper->isEnabled());
57
+ }
58
+
59
+ /**
60
+ * @test
61
+ * @group amd
62
+ * @group helper
63
+ */
64
+ public function getCronInterval_ShouldReturnInt()
65
+ {
66
+ $this->assertInternalType('int', $this->_helper->getCronInterval());
67
+ }
68
+
69
+ /**
70
+ * @test
71
+ * @group amd
72
+ * @group helper
73
+ */
74
+ public function getOneRunLimit_ShouldReturnInt()
75
+ {
76
+ $this->assertInternalType('int', $this->_helper->getOneRunLimit());
77
+ }
78
+
79
+ /**
80
+ * @test
81
+ * @group amd
82
+ * @group helper
83
+ */
84
+ public function getEmailIdentity_ShouldReturnString()
85
+ {
86
+ $this->assertInternalType('string', $this->_helper->getEmailIdentity());
87
+ }
88
+
89
+ /**
90
+ * @test
91
+ * @group amd
92
+ * @group helper
93
+ */
94
+ public function getSendFailureThreshold_ShouldReturnInt()
95
+ {
96
+ $this->assertInternalType('int', $this->_helper->getSendFailureThreshold());
97
+ }
98
+ }
app/code/community/Bronto/Reminder/Test/Helper/Message.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_Reminder_Test_Helper_Message
3
+ extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+ private $_helper;
6
+
7
+ protected function setUp()
8
+ {
9
+ $this->_helper = Mage::helper('bronto_reminder/message');
10
+ }
11
+
12
+ /**
13
+ * @test
14
+ * @group amd
15
+ * @group helper
16
+ */
17
+ public function mageHelperShouldProvideCorrectClass()
18
+ {
19
+ $this->assertInstanceOf('Bronto_Reminder_Helper_Message', $this->_helper);
20
+ }
21
+ }
app/code/community/Bronto/Reminder/Test/Model/Observer.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_Reminder_Test_Model_Observer
3
+ extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+ private $_model;
6
+
7
+ protected function setUp()
8
+ {
9
+ $this->_model = Mage::getModel('bronto_reminder/observer');
10
+ }
11
+
12
+ /**
13
+ * @test
14
+ * @group amd
15
+ * @group model
16
+ */
17
+ public function checkBrontoRequirements_ShouldReturnNull()
18
+ {
19
+ $this->assertNull($this->_model->checkBrontoRequirements(new Varien_Event_Observer()));
20
+ }
21
+
22
+ /**
23
+ * test
24
+ * @group amd
25
+ * @group model
26
+ */
27
+ public function getCouponTypes_ShouldReturnSelf()
28
+ {
29
+ $this->assertInstanceOf('Bronto_Reminder_Model_Observer', $this->_model->getCouponTypes());
30
+ }
31
+
32
+ public function getCouponTypes_ShouldSetTransport()
33
+ {
34
+ $this->markTestSkipped();
35
+ }
36
+ }
app/code/community/Bronto/Reminder/Test/Model/Rule.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_Reminder_Test_Model_Rule
3
+ extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+ private $_fixture;
6
+
7
+ public function setUp()
8
+ {
9
+ $this->_fixture = Mage::getModel('bronto_reminder/rule');
10
+ }
11
+
12
+ /**
13
+ * @test
14
+ * @group amd
15
+ * @group model
16
+ */
17
+ public function getConditionsInstance_shouldReturnObject()
18
+ {
19
+ $instance = $this->_fixture->getConditionsInstance();
20
+
21
+ $this->assertInstanceOf('Bronto_Reminder_Model_Rule_Condition_Combine_Root', $instance);
22
+ }
23
+
24
+ /**
25
+ * @test
26
+ * @group amd
27
+ * @group model
28
+ */
29
+ public function getWebsiteIds_shouldReturnArrayOfIds()
30
+ {
31
+ $websiteIds = $this->_fixture->getWebsiteIds();
32
+
33
+ $this->assertInternalType('array', $websiteIds);
34
+ }
35
+
36
+ /**
37
+ * @test
38
+ * @group amd
39
+ * @group model
40
+ */
41
+ public function sendReminderEmails_withDontSendReturnsObject()
42
+ {
43
+ $rule = $this->_fixture->sendReminderEmails(true);
44
+
45
+ $this->assertInstanceOf('Bronto_Reminder_Model_Rule', $rule);
46
+ }
47
+ }
app/code/community/Bronto/Reminder/controllers/Adminhtml/RemindersController.php ADDED
@@ -0,0 +1,396 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_Adminhtml_RemindersController extends Mage_Adminhtml_Controller_Action
9
+ {
10
+ /**
11
+ * Initialize module page
12
+ *
13
+ * @return Bronto_Reminder_Adminhtml_RemindersController
14
+ */
15
+ protected function _initAction()
16
+ {
17
+ $this->loadLayout()
18
+ ->_setActiveMenu('promo/bronto_reminder')
19
+ ->_addBreadcrumb(
20
+ Mage::helper('bronto_reminder')->__('Reminder Rules'),
21
+ Mage::helper('bronto_reminder')->__('Reminder Rules')
22
+ );
23
+ return $this;
24
+ }
25
+
26
+ /**
27
+ * Initialize proper rule model
28
+ *
29
+ * @param string $requestParam
30
+ *
31
+ * @return Bronto_Reminder_Model_Rule
32
+ */
33
+ protected function _initRule($requestParam = 'id')
34
+ {
35
+ $ruleId = $this->getRequest()->getParam($requestParam, 0);
36
+ $rule = Mage::getModel('bronto_reminder/rule');
37
+ if ($ruleId) {
38
+ $rule->load($ruleId);
39
+ if (!$rule->getId()) {
40
+ Mage::throwException($this->__('Wrong reminder rule requested.'));
41
+ }
42
+ }
43
+ Mage::register('current_reminder_rule', $rule);
44
+ return $rule;
45
+ }
46
+
47
+ /**
48
+ * Index Action
49
+ *
50
+ * @return void
51
+ */
52
+ public function indexAction()
53
+ {
54
+ $this->_title($this->__('Promotions'))->_title($this->__('Reminder Rules'));
55
+ $this->_initAction()
56
+ ->_addContent($this->getLayout()->createBlock('bronto_reminder/adminhtml_reminder'))
57
+ ->renderLayout();
58
+ }
59
+
60
+ /**
61
+ * Create new rule
62
+ */
63
+ public function newAction()
64
+ {
65
+ $this->_forward('edit');
66
+ }
67
+
68
+ /**
69
+ * Edit reminder rule
70
+ */
71
+ public function editAction()
72
+ {
73
+ $this->_title($this->__('Promotions'))->_title($this->__('Bronto Email Reminder Rules'));
74
+
75
+ try {
76
+ /* @var $model Bronto_Reminder_Model_Rule */
77
+ $model = $this->_initRule();
78
+ } catch (Mage_Core_Exception $e) {
79
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
80
+ return $this->_redirect('*/*/');
81
+ }
82
+
83
+ $this->_title($model->getId() ? $model->getName() : $this->__('New Rule'));
84
+
85
+ // set entered data if was error when we do save
86
+ $data = Mage::getSingleton('adminhtml/session')->getPageData(true);
87
+ if (!empty($data)) {
88
+ $model->addData($data);
89
+ }
90
+
91
+ $model->getConditions()->setJsFormObject('rule_conditions_fieldset');
92
+
93
+ $block = $this->getLayout()->createBlock('bronto_reminder/adminhtml_reminder_edit')
94
+ ->setData('form_action_url', $this->getUrl('*/*/save'));
95
+
96
+ $this->_initAction();
97
+
98
+ $this->getLayout()->getBlock('head')
99
+ ->setCanLoadExtJs(true)
100
+ ->setCanLoadRulesJs(true)
101
+ ->addJs('mage/adminhtml/wysiwyg/widget.js')
102
+ ->addItem('js_css', 'prototype/windows/themes/default.css')
103
+ ->addItem('js_css', 'prototype/windows/themes/magento.css');
104
+
105
+ $this->_addBreadcrumb(
106
+ $model->getId() ? $this->__('Edit Rule') : $this->__('New Rule'),
107
+ $model->getId() ? $this->__('Edit Rule') : $this->__('New Rule'))
108
+ ->_addContent($block)
109
+ ->_addLeft($this->getLayout()->createBlock('bronto_reminder/adminhtml_reminder_edit_tabs'))
110
+ ->renderLayout();
111
+ }
112
+
113
+ /**
114
+ * Add new condition
115
+ *
116
+ * @return void
117
+ */
118
+ public function newConditionHtmlAction()
119
+ {
120
+ $id = $this->getRequest()->getParam('id');
121
+ $typeArr = explode('|', str_replace('-', '/', $this->getRequest()->getParam('type')));
122
+ $type = $typeArr[0];
123
+
124
+ $model = Mage::getModel($type)
125
+ ->setId($id)
126
+ ->setType($type)
127
+ ->setRule(Mage::getModel('bronto_reminder/rule'))
128
+ ->setPrefix('conditions');
129
+ if (!empty($typeArr[1])) {
130
+ $model->setAttribute($typeArr[1]);
131
+ }
132
+
133
+ if ($model instanceof Mage_Rule_Model_Condition_Abstract) {
134
+ $model->setJsFormObject($this->getRequest()->getParam('form'));
135
+ $html = $model->asHtmlRecursive();
136
+ } else {
137
+ $html = '';
138
+ }
139
+ $this->getResponse()->setBody($html);
140
+ }
141
+
142
+ /**
143
+ * Save reminder rule
144
+ *
145
+ * @return void
146
+ */
147
+ public function saveAction()
148
+ {
149
+ if ($data = $this->getRequest()->getPost()) {
150
+ try {
151
+ $redirectBack = $this->getRequest()->getParam('back', false);
152
+
153
+ $model = $this->_initRule('rule_id');
154
+ $data['conditions'] = $data['rule']['conditions'];
155
+
156
+ unset($data['rule']);
157
+
158
+ if (!isset($data['website_ids'])) {
159
+ $data['website_ids'] = array(Mage::app()->getStore(true)->getWebsiteId());
160
+ }
161
+
162
+ $data = $this->_filterDates($data, array('active_from', 'active_to'));
163
+ $model->loadPost($data);
164
+ Mage::getSingleton('adminhtml/session')->setPageData($model->getData());
165
+ $model->save();
166
+
167
+ Mage::getSingleton('adminhtml/session')->addSuccess($this->__('The reminder rule has been saved.'));
168
+ Mage::getSingleton('adminhtml/session')->setPageData(false);
169
+
170
+ if ($redirectBack) {
171
+ return $this->_redirect(
172
+ '*/*/edit',
173
+ array(
174
+ 'id' => $model->getId(),
175
+ '_current' => true,
176
+ )
177
+ );
178
+ }
179
+
180
+ } catch (Mage_Core_Exception $e) {
181
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
182
+ Mage::getSingleton('adminhtml/session')->setPageData($data);
183
+ return $this->_redirect('*/*/edit', array('id' => $model->getId()));
184
+ } catch (Exception $e) {
185
+ Mage::getSingleton('adminhtml/session')->addError($this->__('Failed to save reminder rule.'));
186
+ Mage::helper('bronto_reminder')->writeError($e);
187
+ }
188
+ }
189
+ $this->_redirect('*/*/');
190
+ }
191
+
192
+ /**
193
+ * Delete reminder rule
194
+ *
195
+ * @return void
196
+ */
197
+ public function deleteAction()
198
+ {
199
+ try {
200
+ $model = $this->_initRule();
201
+ $model->delete();
202
+ Mage::getSingleton('adminhtml/session')->addSuccess($this->__('The reminder rule has been deleted.'));
203
+ } catch (Mage_Core_Exception $e) {
204
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
205
+ $this->_redirect('*/*/edit', array('id' => $model->getId()));
206
+ return;
207
+ } catch (Exception $e) {
208
+ Mage::getSingleton('adminhtml/session')->addError($this->__('Failed to delete reminder rule.'));
209
+ Mage::helper('bronto_reminder')->writeError($e);
210
+ }
211
+ $this->_redirect('*/*/');
212
+ }
213
+
214
+ /**
215
+ * Match reminder rule and send emails for matched customers
216
+ *
217
+ * @return void
218
+ */
219
+ public function runAction()
220
+ {
221
+ try {
222
+ Mage::helper('bronto_reminder')->writeDebug("Admin pressed 'Run Now'...");
223
+ $model = $this->_initRule();
224
+ $result = $model->sendReminderEmails();
225
+ if ($result) {
226
+ $total = $result['total'];
227
+ $success = $result['success'];
228
+ $error = $result['error'];
229
+ Mage::getSingleton('adminhtml/session')->addSuccess(sprintf("Processed %d Customers (%d Error / %d Success)", $total, $error, $success));
230
+ } else {
231
+ Mage::getSingleton('adminhtml/session')->addError('Reminder rule sending failed.');
232
+ }
233
+ } catch (Mage_Core_Exception $e) {
234
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
235
+ Mage::helper('bronto_reminder')->writeError($e);
236
+ } catch (Exception $e) {
237
+ Mage::getSingleton('adminhtml/session')->addException($e, $this->__('Reminder rule matching error.'));
238
+ Mage::helper('bronto_reminder')->writeError($e);
239
+ }
240
+ $this->_redirect('*/*/edit', array('id' => $model->getId(), 'active_tab' => 'matched_customers'));
241
+ }
242
+
243
+ /**
244
+ * Match reminder rule
245
+ *
246
+ * @return voice
247
+ */
248
+ public function matchAction()
249
+ {
250
+ try {
251
+ Mage::helper('bronto_reminder')->writeDebug("Admin pressed 'Match Now'...");
252
+ $model = $this->_initRule();
253
+ $model->sendReminderEmails(true);
254
+ Mage::getSingleton('adminhtml/session')->addSuccess($this->__('The reminder rule has been matched.'));
255
+ } catch (Mage_Core_Exception $e) {
256
+ Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
257
+ Mage::helper('bronto_reminder')->writeError($e);
258
+ } catch (Exception $e) {
259
+ Mage::getSingleton('adminhtml/session')->addException($e, $this->__('Reminder rule matching error.'));
260
+ Mage::helper('bronto_reminder')->writeError($e);
261
+ }
262
+ $this->_redirect('*/*/edit', array('id' => $model->getId(), 'active_tab' => 'matched_customers'));
263
+ }
264
+
265
+ /**
266
+ * Customer grid ajax action
267
+ *
268
+ * @return void
269
+ */
270
+ public function customerGridAction()
271
+ {
272
+ if ($this->_initRule('rule_id')) {
273
+ $block = $this->getLayout()->createBlock('bronto_reminder/adminhtml_reminder_edit_tab_customers');
274
+ $this->getResponse()->setBody($block->toHtml());
275
+ }
276
+ }
277
+
278
+ /**
279
+ * Convert dates in array from localized to internal format
280
+ *
281
+ * @param array $array
282
+ * @param array $dateFields
283
+ *
284
+ * @return array
285
+ */
286
+ protected function _filterDates($array, $dateFields)
287
+ {
288
+ if (method_exists('Mage_Core_Controller_Varien_Action', '_filterDates')) {
289
+ return parent::_filterDates($array, $dateFields);
290
+ }
291
+
292
+ if (empty($dateFields)) {
293
+ return $array;
294
+ }
295
+
296
+ $filterInput = new Zend_Filter_LocalizedToNormalized(array(
297
+ 'date_format' => Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT)
298
+ ));
299
+
300
+ $filterInternal = new Zend_Filter_NormalizedToLocalized(array(
301
+ 'date_format' => Varien_Date::DATE_INTERNAL_FORMAT
302
+ ));
303
+
304
+ foreach ($dateFields as $dateField) {
305
+ if (array_key_exists($dateField, $array) && !empty($dateField)) {
306
+ $array[$dateField] = $filterInput->filter($array[$dateField]);
307
+ $array[$dateField] = $filterInternal->filter($array[$dateField]);
308
+ }
309
+ }
310
+ return $array;
311
+ }
312
+
313
+ /**
314
+ * Add an extra title to the end or one from the end, or remove all
315
+ *
316
+ * Usage examples:
317
+ * $this->_title('foo')->_title('bar');
318
+ * => bar / foo / <default title>
319
+ *
320
+ * $this->_title()->_title('foo')->_title('bar');
321
+ * => bar / foo
322
+ *
323
+ * $this->_title('foo')->_title(false)->_title('bar');
324
+ * bar / <default title>
325
+ *
326
+ * @see self::_renderTitles()
327
+ * @param string|false|-1|null $text
328
+ * @return Mage_Core_Controller_Varien_Action
329
+ */
330
+ protected function _title($text = null, $resetIfExists = true)
331
+ {
332
+ if (method_exists('Mage_Adminhtml_Controller_Action', '_title')) {
333
+ return parent::_title($text, $resetIfExists);
334
+ }
335
+
336
+ if (is_string($text)) {
337
+ $this->_titles[] = $text;
338
+ } elseif (-1 === $text) {
339
+ if (empty($this->_titles)) {
340
+ $this->_removeDefaultTitle = true;
341
+ } else {
342
+ array_pop($this->_titles);
343
+ }
344
+ } elseif (empty($this->_titles) || $resetIfExists) {
345
+ if (false === $text) {
346
+ $this->_removeDefaultTitle = false;
347
+ $this->_titles = array();
348
+ } elseif (null === $text) {
349
+ $this->_removeDefaultTitle = true;
350
+ $this->_titles = array();
351
+ }
352
+ }
353
+ return $this;
354
+ }
355
+
356
+ /**
357
+ * Get if module is allowed
358
+ *
359
+ * @return bool
360
+ */
361
+ protected function _isAllowed()
362
+ {
363
+ return $this->_isSectionAllowed('bronto_reminder');
364
+ }
365
+
366
+ /**
367
+ * Check if specified section allowed in ACL
368
+ *
369
+ * Will forward to deniedAction(), if not allowed.
370
+ *
371
+ * @param string $section
372
+ * @return bool
373
+ */
374
+ protected function _isSectionAllowed($section)
375
+ {
376
+ try {
377
+ $session = Mage::getSingleton('admin/session');
378
+ $resourceLookup = "admin/system/config/{$section}";
379
+ if ($session->getData('acl') instanceof Mage_Admin_Model_Acl) {
380
+ $resourceId = $session->getData('acl')->get($resourceLookup)->getResourceId();
381
+ if (!$session->isAllowed($resourceId)) {
382
+ throw new Exception('');
383
+ }
384
+ return true;
385
+ }
386
+ } catch (Zend_Acl_Exception $e) {
387
+ $this->norouteAction();
388
+ $this->setFlag('', self::FLAG_NO_DISPATCH, true);
389
+ return false;
390
+ } catch (Exception $e) {
391
+ $this->deniedAction();
392
+ $this->setFlag('', self::FLAG_NO_DISPATCH, true);
393
+ return false;
394
+ }
395
+ }
396
+ }
app/code/community/Bronto/Reminder/controllers/LoadController.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Bronto\Reminder
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.5.0
7
+ */
8
+ class Bronto_Reminder_LoadController extends Mage_Core_Controller_Front_Action
9
+ {
10
+ /**
11
+ * Open quote by link
12
+ * Example: /reminder/load/index/id/1
13
+ */
14
+ public function indexAction()
15
+ {
16
+ $storeCode = $this->getRequest()->getParam('___store', 'default');
17
+ $store = $this->_getStoreByCode($storeCode);
18
+ $storeId = $store->getId();
19
+ Mage::app()->setCurrentStore($storeId);
20
+
21
+ $quote = false;
22
+ $quoteId = $this->getRequest()->getParam('id');
23
+ $ruleId = $this->getRequest()->getParam('rule_id', 0);
24
+ $messageId = $this->getRequest()->getParam('message_id', 0);
25
+
26
+ if (!empty($quoteId)){
27
+ $quoteId = Mage::helper('core')->decrypt(base64_decode(urldecode($quoteId)));
28
+
29
+ if (!empty($quoteId)) {
30
+ /* @var $quote Mage_Sales_Model_Quote */
31
+ $quote = Mage::getModel('sales/quote')
32
+ ->setStoreId($storeId)
33
+ ->load($quoteId);
34
+
35
+ if ($quote->getId() && $quote->getIsActive()){
36
+ Mage::getSingleton('checkout/session')->setQuoteId($quote->getId());
37
+ Mage::getSingleton('checkout/session')->resetCheckout();
38
+ }
39
+ }
40
+ }
41
+
42
+ if ($ruleId && $quote) {
43
+ $customerId = $quote->getCustomerId();
44
+ $customerId = ($customerId) ? $customerId : 0;
45
+ $log = Mage::getModel('bronto_reminder/rule')
46
+ ->getRuleLogItems($ruleId, $customerId, $messageId);
47
+
48
+ if (!empty($messageId)) {
49
+ Mage::getSingleton('checkout/session')->setBrontoMessageId($messageId);
50
+ }
51
+
52
+ if (isset($log['bronto_delivery_id']) && !empty($log['bronto_delivery_id'])) {
53
+ Mage::getSingleton('checkout/session')->setBrontoDeliveryId($log['bronto_delivery_id']);
54
+ }
55
+ }
56
+
57
+ $redirectUrl = Mage::app()->getStore()->getUrl('checkout/cart');
58
+
59
+ if (isset($_SERVER['QUERY_STRING']) && !empty($_SERVER['QUERY_STRING'])){
60
+ $redirectUrl .= '?' . $_SERVER['QUERY_STRING'];
61
+ }
62
+
63
+ $this->_redirectUrl($redirectUrl);
64
+ }
65
+
66
+ protected function _getStoreByCode($storeCode)
67
+ {
68
+ $stores = array_keys(Mage::app()->getStores());
69
+ foreach($stores as $id){
70
+ $store = Mage::app()->getStore($id);
71
+ if($store->getCode()==$storeCode) {
72
+ return $store;
73
+ }
74
+ }
75
+ return false;
76
+ }
77
+ }
app/code/community/Bronto/Reminder/etc/adminhtml.xml ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <admin>
6
+ <children>
7
+ <promo>
8
+ <children>
9
+ <bronto_reminder module="bronto_reminder">
10
+ <title>Bronto Reminder Emails</title>
11
+ <sort_order>20</sort_order>
12
+ </bronto_reminder>
13
+ </children>
14
+ </promo>
15
+ <system>
16
+ <children>
17
+ <config>
18
+ <children>
19
+ <bronto_reminder module="bronto_reminder">
20
+ <title>Bronto Reminder Emails Section</title>
21
+ </bronto_reminder>
22
+ </children>
23
+ </config>
24
+ </children>
25
+ </system>
26
+ </children>
27
+ </admin>
28
+ </resources>
29
+ </acl>
30
+ <menu>
31
+ <promo>
32
+ <children>
33
+ <bronto_reminder module="bronto_reminder">
34
+ <title>Bronto Reminder Emails</title>
35
+ <action>adminhtml/reminders</action>
36
+ <sort_order>20</sort_order>
37
+ <depends>
38
+ <module>Bronto_Reminder</module>
39
+ <config>bronto_reminder/settings/enabled</config>
40
+ </depends>
41
+ <resource>bronto_reminder/settings</resource>
42
+ </bronto_reminder>
43
+ </children>
44
+ </promo>
45
+ </menu>
46
+ </config>
app/code/community/Bronto/Reminder/etc/config.xml ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Bronto_Reminder>
5
+ <version>1.4.11</version>
6
+ </Bronto_Reminder>
7
+ </modules>
8
+ <global>
9
+ <helpers>
10
+ <bronto_reminder>
11
+ <class>Bronto_Reminder_Helper</class>
12
+ </bronto_reminder>
13
+ </helpers>
14
+ <blocks>
15
+ <bronto_reminder>
16
+ <class>Bronto_Reminder_Block</class>
17
+ </bronto_reminder>
18
+ </blocks>
19
+ <models>
20
+ <bronto_reminder>
21
+ <class>Bronto_Reminder_Model</class>
22
+ <resourceModel>bronto_reminder_mysql4</resourceModel>
23
+ </bronto_reminder>
24
+ <bronto_reminder_mysql4>
25
+ <class>Bronto_Reminder_Model_Mysql4</class>
26
+ <entities>
27
+ <rule><table>bronto_reminder_rule</table></rule>
28
+ <website><table>bronto_reminder_rule_website</table></website>
29
+ <message><table>bronto_reminder_message</table></message>
30
+ <coupon><table>bronto_reminder_rule_coupon</table></coupon>
31
+ <log><table>bronto_reminder_rule_log</table></log>
32
+ <guest><table>bronto_guest_emails</table></guest>
33
+ </entities>
34
+ </bronto_reminder_mysql4>
35
+ </models>
36
+ <resources>
37
+ <bronto_reminder_setup>
38
+ <setup>
39
+ <module>Bronto_Reminder</module>
40
+ </setup>
41
+ </bronto_reminder_setup>
42
+ </resources>
43
+ <events>
44
+ <salesrule_rule_get_coupon_types>
45
+ <observers>
46
+ <bronto_reminder>
47
+ <class>bronto_reminder/observer</class>
48
+ <method>getCouponTypes</method>
49
+ </bronto_reminder>
50
+ </observers>
51
+ </salesrule_rule_get_coupon_types>
52
+ <adminhtml_promo_quote_edit_tab_main_prepare_form>
53
+ <observers>
54
+ <bronto_reminder>
55
+ <class>bronto_reminder/observer</class>
56
+ <method>updatePromoQuoteTabMainForm</method>
57
+ </bronto_reminder>
58
+ </observers>
59
+ </adminhtml_promo_quote_edit_tab_main_prepare_form>
60
+ </events>
61
+ <template>
62
+ <email>
63
+ <bronto_reminder_template module="bronto_reminder">
64
+ <label>Reminder Template</label>
65
+ <file>bronto/abandoned_cart.html</file>
66
+ <type>html</type>
67
+ </bronto_reminder_template>
68
+ </email>
69
+ </template>
70
+ </global>
71
+ <default>
72
+ <bronto_reminder>
73
+ <settings>
74
+ <enabled>0</enabled>
75
+ <frequency>I</frequency>
76
+ <interval>15</interval>
77
+ <minutes>0</minutes>
78
+ <limit>100</limit>
79
+ <threshold>5</threshold>
80
+ <identity>general</identity>
81
+ </settings>
82
+ </bronto_reminder>
83
+ </default>
84
+ <frontend>
85
+ <routers>
86
+ <bronto_reminder>
87
+ <use>standard</use>
88
+ <args>
89
+ <module>Bronto_Reminder</module>
90
+ <frontName>reminder</frontName>
91
+ </args>
92
+ </bronto_reminder>
93
+ </routers>
94
+ <events>
95
+ <sales_quote_save_before>
96
+ <observers>
97
+ <bronto_reminder_capture_guest_email_on_checkout>
98
+ <class>bronto_reminder/observer</class>
99
+ <method>storeGuestEmailCheckout</method>
100
+ </bronto_reminder_capture_guest_email_on_checkout>
101
+ </observers>
102
+ </sales_quote_save_before>
103
+ </events>
104
+ </frontend>
105
+ <admin>
106
+ <routers>
107
+ <adminhtml>
108
+ <args>
109
+ <modules>
110
+ <bronto_reminder before="Mage_Adminhtml">Bronto_Reminder_Adminhtml</bronto_reminder>
111
+ </modules>
112
+ </args>
113
+ </adminhtml>
114
+ </routers>
115
+ </admin>
116
+ <adminhtml>
117
+ <events>
118
+ <controller_action_predispatch>
119
+ <observers>
120
+ <bronto_reminder_controller_action_predispatch>
121
+ <class>bronto_reminder/observer</class>
122
+ <method>checkBrontoRequirements</method>
123
+ </bronto_reminder_controller_action_predispatch>
124
+ </observers>
125
+ </controller_action_predispatch>
126
+ </events>
127
+ <layout>
128
+ <updates>
129
+ <bronto_reminder>
130
+ <file>bronto/reminder.xml</file>
131
+ </bronto_reminder>
132
+ </updates>
133
+ </layout>
134
+ <acl>
135
+ <resources>
136
+ <admin>
137
+ <children>
138
+ <promo>
139
+ <children>
140
+ <bronto_reminder module="bronto_reminder">
141
+ <title>Bronto Reminder Emails</title>
142
+ <sort_order>20</sort_order>
143
+ </bronto_reminder>
144
+ </children>
145
+ </promo>
146
+ <system>
147
+ <children>
148
+ <config>
149
+ <children>
150
+ <bronto_reminder module="bronto_reminder">
151
+ <title>Bronto Reminder Emails Section</title>
152
+ </bronto_reminder>
153
+ </children>
154
+ </config>
155
+ </children>
156
+ </system>
157
+ </children>
158
+ </admin>
159
+ </resources>
160
+ </acl>
161
+ <menu>
162
+ <promo>
163
+ <children>
164
+ <bronto_reminder module="bronto_reminder">
165
+ <title>Bronto Reminder Emails</title>
166
+ <action>adminhtml/reminders</action>
167
+ <sort_order>20</sort_order>
168
+ <depends>
169
+ <module>Bronto_Reminder</module>
170
+ <config>bronto_reminder/settings/enabled</config>
171
+ </depends>
172
+ <resource>bronto_reminder/settings</resource>
173
+ </bronto_reminder>
174
+ </children>
175
+ </promo>
176
+ </menu>
177
+ </adminhtml>
178
+ <crontab>
179
+ <jobs>
180
+ <bronto_reminder_send_notification>
181
+ <schedule><cron_expr>*/15 * * * *</cron_expr></schedule>
182
+ <run><model>bronto_reminder/observer::scheduledNotification</model></run>
183
+ </bronto_reminder_send_notification>
184
+ </jobs>
185
+ </crontab>
186
+
187
+ <phpunit>
188
+ <suite>
189
+ <modules>
190
+ <Bronto_Reminder />
191
+ </modules>
192
+ </suite>
193
+ </phpunit>
194
+ </config>
app/code/community/Bronto/Reminder/etc/system.xml ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <bronto_reminder translate="label" module="bronto_reminder">
5
+ <label>Reminder Emails</label>
6
+ <tab>bronto</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>1</show_in_website>
11
+ <show_in_store>1</show_in_store>
12
+ <groups>
13
+ <about>
14
+ <frontend_type>text</frontend_type>
15
+ <frontend_model>bronto_reminder/adminhtml_system_config_about</frontend_model>
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
+ </about>
21
+ <settings translate="label">
22
+ <label>Settings</label>
23
+ <frontend_type>text</frontend_type>
24
+ <sort_order>1</sort_order>
25
+ <show_in_default>1</show_in_default>
26
+ <show_in_website>1</show_in_website>
27
+ <show_in_store>1</show_in_store>
28
+ <comment><![CDATA[Additional configuration located at: <strong>Promotions &rsaquo; <a href="/admin/reminders/">Bronto Reminder Emails</a></strong><br/><br/>]]></comment>
29
+ <fields>
30
+ <enabled translate="label">
31
+ <label>Enable Module</label>
32
+ <frontend_type>select</frontend_type>
33
+ <frontend_model>bronto_common/adminhtml_system_config_form_field</frontend_model>
34
+ <source_model>adminhtml/system_config_source_yesno</source_model>
35
+ <sort_order>1</sort_order>
36
+ <show_in_default>1</show_in_default>
37
+ <show_in_website>1</show_in_website>
38
+ <show_in_store>1</show_in_store>
39
+ </enabled>
40
+ <frequency translate="label">
41
+ <label>Frequency</label>
42
+ <depends><enabled>1</enabled></depends>
43
+ <frontend_type>select</frontend_type>
44
+ <source_model>bronto_common/system_config_source_cron_frequency</source_model>
45
+ <backend_model>bronto_reminder/system_config_backend_cron</backend_model>
46
+ <sort_order>2</sort_order>
47
+ <show_in_default>1</show_in_default>
48
+ <show_in_website>0</show_in_website>
49
+ <show_in_store>0</show_in_store>
50
+ </frequency>
51
+ <interval translate="label">
52
+ <label>Interval</label>
53
+ <depends><enabled>1</enabled></depends>
54
+ <depends><frequency>I</frequency></depends>
55
+ <frontend_type>select</frontend_type>
56
+ <source_model>bronto_common/system_config_source_cron_minutes</source_model>
57
+ <sort_order>3</sort_order>
58
+ <show_in_default>1</show_in_default>
59
+ <show_in_website>0</show_in_website>
60
+ <show_in_store>0</show_in_store>
61
+ <comment>Set this value larger than your cron.php launch period.</comment>
62
+ </interval>
63
+ <minutes translate="label">
64
+ <label>Minute of the Hour</label>
65
+ <depends><frequency>H</frequency></depends>
66
+ <frontend_type>text</frontend_type>
67
+ <sort_order>3</sort_order>
68
+ <show_in_default>1</show_in_default>
69
+ <show_in_website>0</show_in_website>
70
+ <show_in_store>0</show_in_store>
71
+ <comment>Valid range: 0-59 (default 0).</comment>
72
+ </minutes>
73
+ <time translate="label">
74
+ <label>Start Time</label>
75
+ <depends><enabled>1</enabled></depends>
76
+ <frontend_type>time</frontend_type>
77
+ <sort_order>4</sort_order>
78
+ <show_in_default>1</show_in_default>
79
+ <show_in_website>0</show_in_website>
80
+ <show_in_store>0</show_in_store>
81
+ </time>
82
+ <limit translate="label">
83
+ <label>Maximum Emails per Run</label>
84
+ <depends><enabled>1</enabled></depends>
85
+ <frontend_type>text</frontend_type>
86
+ <sort_order>5</sort_order>
87
+ <show_in_default>1</show_in_default>
88
+ <show_in_website>1</show_in_website>
89
+ <show_in_store>1</show_in_store>
90
+ </limit>
91
+ <threshold translate="label">
92
+ <label>Email Send Failure Threshold</label>
93
+ <depends><enabled>1</enabled></depends>
94
+ <frontend_type>text</frontend_type>
95
+ <sort_order>6</sort_order>
96
+ <show_in_default>1</show_in_default>
97
+ <show_in_website>1</show_in_website>
98
+ <show_in_store>1</show_in_store>
99
+ <comment>Empty value disables this limitation. If not limited, the emails may get stuck sending over and over.</comment>
100
+ </threshold>
101
+ <identity translate="label">
102
+ <label>Reminder Email Sender</label>
103
+ <depends><enabled>1</enabled></depends>
104
+ <frontend_type>select</frontend_type>
105
+ <source_model>adminhtml/system_config_source_email_identity</source_model>
106
+ <sort_order>10</sort_order>
107
+ <show_in_default>1</show_in_default>
108
+ <show_in_website>1</show_in_website>
109
+ <show_in_store>1</show_in_store>
110
+ </identity>
111
+ </fields>
112
+ </settings>
113
+ <cron_list>
114
+ <frontend_type>text</frontend_type>
115
+ <frontend_model>bronto_reminder/adminhtml_system_config_cron</frontend_model>
116
+ <sort_order>3</sort_order>
117
+ <show_in_default>1</show_in_default>
118
+ <show_in_website>1</show_in_website>
119
+ <show_in_store>1</show_in_store>
120
+ </cron_list>
121
+ </groups>
122
+ </bronto_reminder>
123
+ </sections>
124
+ </config>
app/code/community/Bronto/Reminder/sql/bronto_reminder_setup/mysql4-install-1.4.2.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ $installer->run("
9
+
10
+ CREATE TABLE `{$this->getTable('bronto_reminder/rule')}` (
11
+ `rule_id` int(10) unsigned NOT NULL auto_increment,
12
+ `name` varchar(255) NOT NULL default '',
13
+ `description` text NOT NULL,
14
+ `conditions_serialized` mediumtext NOT NULL,
15
+ `condition_sql` mediumtext,
16
+ `is_active` tinyint(1) unsigned NOT NULL default '0',
17
+ `salesrule_id` int(10) unsigned default NULL,
18
+ `schedule` varchar(255) NOT NULL DEFAULT '',
19
+ `default_label` varchar(255) NOT NULL default '',
20
+ `default_description` text NOT NULL,
21
+ `active_from` datetime default NULL,
22
+ `active_to` datetime default NULL,
23
+ PRIMARY KEY (`rule_id`),
24
+ KEY `IDX_BRONTO_REMINDER_SALESRULE` (`salesrule_id`)
25
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
26
+
27
+ CREATE TABLE `{$this->getTable('bronto_reminder/website')}` (
28
+ `rule_id` int(10) unsigned NOT NULL,
29
+ `website_id` smallint(5) unsigned NOT NULL,
30
+ PRIMARY KEY (`rule_id`,`website_id`),
31
+ KEY `IDX_BRONTO_REMINDER_WEBSITE` (`website_id`)
32
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
33
+
34
+ CREATE TABLE `{$this->getTable('bronto_reminder/message')}` (
35
+ `rule_id` int(10) unsigned NOT NULL,
36
+ `store_id` smallint(5) NOT NULL,
37
+ `message_id` varchar(255) NOT NULL default '',
38
+ `label` varchar(255) default NULL,
39
+ `description` text default NULL,
40
+ PRIMARY KEY (`rule_id`,`store_id`),
41
+ KEY `IDX_BRONTO_REMINDER_MESSAGE_RULE` (`rule_id`),
42
+ KEY `IDX_BRONTO_REMINDER_MESSAGE` (`message_id`)
43
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
44
+
45
+ CREATE TABLE `{$this->getTable('bronto_reminder/coupon')}` (
46
+ `rule_id` int(10) unsigned NOT NULL,
47
+ `coupon_id` int(10) unsigned DEFAULT NULL,
48
+ `customer_id` int(10) unsigned NOT NULL,
49
+ `associated_at` datetime NOT NULL,
50
+ `emails_failed` smallint(5) unsigned NOT NULL default '0',
51
+ `is_active` tinyint(1) unsigned NOT NULL default '1',
52
+ PRIMARY KEY (`rule_id`,`customer_id`),
53
+ KEY `IDX_BRONTO_REMINDER_RULE_COUPON` (`rule_id`)
54
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
55
+
56
+ CREATE TABLE `{$this->getTable('bronto_reminder/log')}` (
57
+ `log_id` int(10) unsigned NOT NULL auto_increment,
58
+ `rule_id` int(10) unsigned NOT NULL,
59
+ `customer_id` int(10) unsigned NOT NULL,
60
+ `sent_at` datetime NOT NULL,
61
+ `bronto_delivery_id` varchar(255) NULL DEFAULT NULL,
62
+ `bronto_message_id` varchar(255) NULL DEFAULT NULL,
63
+ PRIMARY KEY (`log_id`),
64
+ KEY `IDX_BRONTO_REMINDER_LOG_RULE` (`rule_id`),
65
+ KEY `IDX_BRONTO_REMINDER_LOG_CUSTOMER` (`customer_id`)
66
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
67
+
68
+ ");
69
+
70
+ $installer->getConnection()->addConstraint(
71
+ 'FK_BRONTO_REMINDER_RULE',
72
+ $this->getTable('bronto_reminder/website'),
73
+ 'rule_id',
74
+ $this->getTable('bronto_reminder/rule'),
75
+ 'rule_id'
76
+ );
77
+
78
+ $installer->getConnection()->addConstraint(
79
+ 'FK_BRONTO_REMINDER_SALESRULE',
80
+ $this->getTable('bronto_reminder/rule'),
81
+ 'salesrule_id',
82
+ $this->getTable('salesrule'),
83
+ 'rule_id',
84
+ 'SET NULL'
85
+ );
86
+
87
+ $installer->getConnection()->addConstraint(
88
+ 'FK_BRONTO_REMINDER_MESSAGE_RULE',
89
+ $this->getTable('bronto_reminder/message'),
90
+ 'rule_id',
91
+ $this->getTable('bronto_reminder/rule'),
92
+ 'rule_id'
93
+ );
94
+
95
+ $installer->getConnection()->addConstraint(
96
+ 'FK_BRONTO_REMINDER_RULE_COUPON',
97
+ $this->getTable('bronto_reminder/coupon'),
98
+ 'rule_id',
99
+ $this->getTable('bronto_reminder/rule'),
100
+ 'rule_id'
101
+ );
102
+
103
+ $installer->getConnection()->addConstraint(
104
+ 'FK_BRONTO_REMINDER_LOG_RULE',
105
+ $this->getTable('bronto_reminder/log'),
106
+ 'rule_id',
107
+ $this->getTable('bronto_reminder/rule'),
108
+ 'rule_id'
109
+ );
110
+
111
+ $installer->endSetup();
app/code/community/Bronto/Reminder/sql/bronto_reminder_setup/mysql4-upgrade-1.4.0-1.4.2.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ try {
9
+ $installer->run("
10
+
11
+ ALTER TABLE `{$installer->getTable('bronto_reminder/log')}`
12
+ ADD COLUMN `bronto_delivery_id` varchar(255) NULL DEFAULT NULL,
13
+ ADD COLUMN `bronto_message_id` varchar(255) NULL DEFAULT NULL;
14
+
15
+ ");
16
+ } catch (Exception $e) {
17
+ //
18
+ }
19
+
20
+ $installer->endSetup();
app/code/community/Bronto/Reminder/sql/bronto_reminder_setup/mysql4-upgrade-1.4.10-1.4.11.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * fall back to create table if existing modules already exists to support upgrade
4
+ */
5
+
6
+ $installer = $this;
7
+ /* @var $installer Mage_Core_Model_Resource_Setup */
8
+
9
+ $installer->startSetup();
10
+
11
+ try {
12
+ $installer->run("
13
+ CREATE TABLE IF NOT EXISTS `{$installer->getTable('bronto_reminder/guest')}` (
14
+ `guest_email_id` int(11) NOT NULL AUTO_INCREMENT,
15
+ `email_address` varchar(150) CHARACTER SET utf8 NOT NULL,
16
+ `email_sent` tinyint(3) unsigned NOT NULL DEFAULT '0',
17
+ `session_id` varchar(64) NOT NULL,
18
+ `first_name` varchar(50) CHARACTER SET utf8 NOT NULL,
19
+ `last_name` varchar(50) CHARACTER SET utf8 NOT NULL,
20
+ `store_id` int(11) NOT NULL,
21
+ `quote_id` int(11) NOT NULL,
22
+ PRIMARY KEY (`guest_email_id`)
23
+ ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;
24
+
25
+ ALTER TABLE `{$installer->getTable('bronto_reminder/guest')}`
26
+ CHANGE COLUMN `first_name` `firstname` varchar(50) CHARACTER SET utf8 NOT NULL,
27
+ CHANGE COLUMN `last_name` `lastname` varchar(50) CHARACTER SET utf8 NOT NULL;
28
+
29
+ ");
30
+ } catch (Exception $e) {
31
+ //
32
+ }
33
+
34
+ $installer->endSetup();
app/code/community/Bronto/Reminder/sql/bronto_reminder_setup/mysql4-upgrade-1.4.2-1.4.9.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ try {
9
+ $installer->run("
10
+
11
+ CREATE TABLE IF NOT EXISTS `{$installer->getTable('bronto_reminder/guest')}` (
12
+ `guest_email_id` int(11) NOT NULL AUTO_INCREMENT,
13
+ `email_address` varchar(150) CHARACTER SET utf8 NOT NULL,
14
+ `email_sent` tinyint(3) unsigned NOT NULL DEFAULT '0',
15
+ `session_id` varchar(64) NOT NULL,
16
+ `first_name` varchar(50) CHARACTER SET utf8 NOT NULL,
17
+ `last_name` varchar(50) CHARACTER SET utf8 NOT NULL,
18
+ `store_id` int(11) NOT NULL,
19
+ `quote_id` int(11) NOT NULL,
20
+ PRIMARY KEY (`guest_email_id`)
21
+ ) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=0 ;
22
+
23
+ ");
24
+ } catch (Exception $e) {
25
+ //
26
+ }
27
+
28
+ $installer->endSetup();
app/code/community/Bronto/Reminder/sql/bronto_reminder_setup/mysql4-upgrade-1.4.9-1.4.10.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ $installer = $this;
4
+ /* @var $installer Mage_Core_Model_Resource_Setup */
5
+
6
+ $installer->startSetup();
7
+
8
+ try {
9
+ $installer->run("
10
+
11
+ ALTER TABLE `{$installer->getTable('bronto_reminder/guest')}`
12
+ CHANGE COLUMN `first_name` `firstname` varchar(50) CHARACTER SET utf8 NOT NULL,
13
+ CHANGE COLUMN `last_name` `lastname` varchar(50) CHARACTER SET utf8 NOT NULL;
14
+
15
+ ");
16
+ } catch (Exception $e) {
17
+ //
18
+ }
19
+
20
+ $installer->endSetup();
app/code/community/Bronto/Reminder/sql/reference/saveMatchedCustomers.sql ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ SET @ruleId = 1;
2
+
3
+ SELECT `root`.`entity_id`, `c`.`coupon_id`
4
+ FROM `customer_entity` AS `root`
5
+ LEFT JOIN `bronto_reminder_rule_coupon` AS `c`
6
+ ON c.customer_id = root.entity_id
7
+ AND c.rule_id = @ruleId
8
+ WHERE (website_id='1')
9
+ AND ((
10
+ IFNULL((SELECT 1 FROM `sales_flat_quote` AS `quote`
11
+ INNER JOIN `core_store` AS `store`
12
+ ON quote.store_id = store.store_id
13
+ WHERE (store.website_id='1')
14
+ AND (UNIX_TIMESTAMP('2012-01-20 21:13:09' - INTERVAL 2 HOUR) < UNIX_TIMESTAMP(quote.updated_at))
15
+ AND (UNIX_TIMESTAMP('2012-01-20 21:13:09' - INTERVAL 1 HOUR) > UNIX_TIMESTAMP(quote.updated_at))
16
+ AND (quote.is_active = 1)
17
+ AND (quote.items_count > 0)
18
+ AND (quote.customer_id = root.entity_id)
19
+ LIMIT 1),
20
+ 0) = 1))
21
+ AND (c.emails_failed IS NULL OR c.emails_failed < 1 );
app/code/community/Bronto/Roundtrip/Block/Adminhtml/System/Config/About.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Roundtrip
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Roundtrip_Block_Adminhtml_System_Config_About extends Bronto_Common_Block_Adminhtml_System_Config_About
9
+ {
10
+
11
+ /**
12
+ * Description for protected
13
+ * @var string
14
+ * @access protected
15
+ */
16
+ protected $_module = 'bronto_roundtrip';
17
+
18
+ /**
19
+ * Description for protected
20
+ * @var string
21
+ * @access protected
22
+ */
23
+ protected $_name = 'Bronto Roundtrip Install verification for Magento';
24
+ }
app/code/community/Bronto/Roundtrip/Block/Adminhtml/System/Config/Status.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Roundtrip
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Roundtrip_Block_Adminhtml_System_Config_Status
9
+ extends Mage_Adminhtml_Block_System_Config_Form_Fieldset
10
+ {
11
+
12
+ /**
13
+ * Description for protected
14
+ * @var string
15
+ * @access protected
16
+ */
17
+ protected $_module = 'bronto_roundtrip';
18
+
19
+ /**
20
+ * Description for protected
21
+ * @var string
22
+ * @access protected
23
+ */
24
+ protected $_name = 'Bronto Roundtrip Install Verification';
25
+
26
+ /**
27
+ * Short description for function
28
+ *
29
+ * Long description (if any) ...
30
+ *
31
+ * @return void
32
+ * @access public
33
+ */
34
+ public function _construct()
35
+ {
36
+ parent::_construct();
37
+ $this->setTemplate('bronto/roundtrip/status.phtml');
38
+ }
39
+
40
+ /**
41
+ * @param Varien_Data_Form_Element_Abstract $element
42
+ * @return string
43
+ */
44
+ public function render(Varien_Data_Form_Element_Abstract $element)
45
+ {
46
+ return $this->toHtml();
47
+ }
48
+
49
+ /**
50
+ * @return string
51
+ */
52
+ public function getModuleName()
53
+ {
54
+ return $this->_name;
55
+ }
56
+
57
+ /**
58
+ * @return string
59
+ */
60
+ public function getRoundtripStatus()
61
+ {
62
+ return Mage::helper($this->_module)->getRoundtripStatusText();
63
+ }
64
+
65
+ /**
66
+ * Short description for function
67
+ *
68
+ * Long description (if any) ...
69
+ *
70
+ * @return string Return description (if any) ...
71
+ * @access public
72
+ */
73
+ public function getRoundtripButton()
74
+ {
75
+ $html = null;
76
+
77
+ $html = $this->getLayout()->createBlock('bronto_roundtrip/adminhtml_widget_button_run')->toHtml();
78
+
79
+ $html = "<p class=\"form-buttons\">{$html}</p>";
80
+
81
+ return $html;
82
+ }
83
+
84
+ /**
85
+ * @return string
86
+ */
87
+ public function getAppendedScripts()
88
+ {
89
+ return null;
90
+ }
91
+ }
app/code/community/Bronto/Roundtrip/Block/Adminhtml/Widget/Button/Run.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @package Roundtrip
5
+ * @copyright 2011-2012 Bronto Software, Inc.
6
+ * @version 1.1.5
7
+ */
8
+ class Bronto_Roundtrip_Block_Adminhtml_Widget_Button_Run extends Mage_Adminhtml_Block_Widget_Button
9
+ {
10
+ /**
11
+ * Internal constructor not depended on params. Can be used for object initialization
12
+ */
13
+ protected function _construct()
14
+ {
15
+ $this->setLabel('Verify Now');
16
+ $this->setOnClick("setLocation('" . Mage::helper('adminhtml')->getUrl('*/roundtrip/run') . "'); return false;");
17
+ }
18
+ }
app/code/community/Bronto/Roundtrip/Helper/Data.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Roundtrip helper
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package Roundtrip
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2011-2012 Bronto Software, Inc.
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version 1.6.7
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+
21
+ /**
22
+ * Roundtrip helper
23
+ *
24
+ * @category Bronto
25
+ * @package Roundtrip
26
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
27
+ * @copyright 2011-2012 Bronto Software, Inc.
28
+ * @license http://www.atlanticbt.com/ Atlantic BT
29
+ * @version 1.6.7
30
+ * @link <>
31
+ * @see References to other sections (if any)...
32
+ */
33
+ class Bronto_Roundtrip_Helper_Data
34
+ extends Bronto_Common_Helper_Data
35
+ {
36
+ // {{{ properties
37
+
38
+ /**
39
+ * Description for const
40
+ */
41
+ const XML_PATH_ROUNDTRIP_ROOT = 'bronto_roundtrip/settings/';
42
+
43
+ /**
44
+ * Description for private
45
+ * @var integer
46
+ * @access private
47
+ */
48
+ private $_status = 0;
49
+
50
+ // }}}
51
+ // {{{ __construct()
52
+
53
+ /**
54
+ * Short description for function
55
+ *
56
+ * Long description (if any) ...
57
+ *
58
+ * @return void
59
+ * @access public
60
+ */
61
+ public function __construct()
62
+ {
63
+ $this->_status = Mage::getStoreConfig(self::XML_PATH_ROUNDTRIP_ROOT . 'status');
64
+ }
65
+
66
+ // }}}
67
+ // {{{ getRoundtripStatus()
68
+
69
+ /**
70
+ * Get the overall status of the roundtrip verification
71
+ *
72
+ * @return string
73
+ * @access public
74
+ */
75
+ public function getRoundtripStatus()
76
+ {
77
+ return $this->_status;
78
+ }
79
+
80
+ // }}}
81
+ // {{{ getRoundtripStatusText()
82
+
83
+ /**
84
+ * Get a formatted version of the status text
85
+ *
86
+ * @return string
87
+ * @access public
88
+ */
89
+ public function getRoundtripStatusText()
90
+ {
91
+ switch ($this->_status) {
92
+ case 1:
93
+ return '<span style="color:green; font-weight:bold;">Passed Verification</span>';
94
+ break;
95
+ case 0:
96
+ return '<span style="color:red; font-weight:bold;">Failed Verification</span>';
97
+ break;
98
+ default:
99
+ return '<span style="color:grey; font-weight:bold;">Needs Verification</span>';
100
+ break;
101
+ }
102
+ }
103
+
104
+ // }}}
105
+ // {{{ setRoundtripStatus()
106
+
107
+ /**
108
+ * Set the value of a setting
109
+ *
110
+ * @param string $path The setting path to set the value for
111
+ * @param string $value
112
+ *
113
+ * @return Mage_Core_Model_Config
114
+ * @access public
115
+ */
116
+ public function setRoundtripStatus($path, $value)
117
+ {
118
+ return Mage::getSingleton('core/config')
119
+ ->saveConfig($path, $value);
120
+ }
121
+
122
+ // }}}
123
+ // {{{ getPath()
124
+
125
+ /**
126
+ * Get the full path from path ending
127
+ *
128
+ * @param string $pathend The setting to get the path for
129
+ *
130
+ * @return string
131
+ * @access public
132
+ */
133
+ public function getPath($pathend)
134
+ {
135
+ return self::XML_PATH_ROUNDTRIP_ROOT . $pathend;
136
+ }
137
+
138
+ // }}}
139
+ }
app/code/community/Bronto/Roundtrip/Model/Contact/Builder.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Roundtrip contact creator
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package Roundtrip
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Roundtrip contact creator
22
+ *
23
+ * @category Bronto
24
+ * @package Roundtrip
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_Roundtrip_Model_Contact_Builder
33
+ {
34
+ // {{{ properties
35
+
36
+ const EMAIL = 'ps-eng@bronto.com';
37
+
38
+ protected $_api;
39
+
40
+ // }}}
41
+ // {{{ __construct()
42
+
43
+ public function __construct(Bronto_Common_Model_Api $api)
44
+ {
45
+ $this->_api = $api;
46
+ }
47
+
48
+ // }}}
49
+ // {{{ _buildContact()
50
+
51
+ protected function _buildContact()
52
+ {
53
+ $contactObject = $this->_api->getContactObject();
54
+ $contact = $contactObject->createRow();
55
+ $contact->email = self::EMAIL;
56
+
57
+ // Get Contact Info
58
+ try {
59
+ $contact->read();
60
+ } catch (Exception $e) {
61
+ $contact->customSource = 'Api';
62
+ }
63
+
64
+ // If Test contact exists, remove it and create a new one
65
+ if ($contact->id) {
66
+ $contact->delete($contact->id);
67
+
68
+ $contactObject = $this->_api->getContactObject();
69
+ $contact = $contactObject->createRow();
70
+ $contact->email = self::EMAIL;
71
+ }
72
+
73
+ return $contact;
74
+ }
75
+
76
+ // }}}
77
+ // {{{ getContact()
78
+
79
+ /**
80
+ * Create a Contact in bronto
81
+ *
82
+ * @return boolean|Bronto_Api_Contact_Row
83
+ * @access public
84
+ */
85
+ public function getContact()
86
+ {
87
+ // Load Contact
88
+ $contact = $this->_buildContact();
89
+
90
+ $helper = Mage::helper('bronto_roundtrip');
91
+
92
+ // Try to save with new info
93
+ if (!Mage::helper('bronto_common/contact')->saveContact($contact)) {
94
+ $helper->writeDebug('could not save contact');
95
+ return false;
96
+ }
97
+
98
+ $helper->writeDebug('Added Contact');
99
+ return $contact;
100
+ }
101
+
102
+ // }}}
103
+
104
+ public function deleteContact()
105
+ {
106
+ }
107
+ }
app/code/community/Bronto/Roundtrip/Model/Roundtrip.php ADDED
@@ -0,0 +1,378 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Short description for file
5
+ *
6
+ * Long description (if any) ...
7
+ *
8
+ * PHP version 5
9
+ *
10
+ * The license text...
11
+ *
12
+ * @category Bronto
13
+ * @package Roundtrip
14
+ * @author Adam Daniels <adam.daniels@atlanticbt.com>
15
+ * @copyright 2012 Atlantic BT
16
+ * @license http://www.atlanticbt.com/ Atlantic BT
17
+ * @version CVS: $Id:$
18
+ * @link <>
19
+ * @see References to other sections (if any)...
20
+ */
21
+
22
+ /**
23
+ * Short description for class
24
+ *
25
+ * Long description (if any) ...
26
+ *
27
+ * @category Bronto
28
+ * @package Roundtrip
29
+ * @author Adam Daniels <adam.daniels@atlanticbt.com>
30
+ * @copyright 2012 Atlantic BT
31
+ * @license http://www.atlanticbt.com/ Atlantic BT
32
+ * @version Release: @package_version@
33
+ * @link <>
34
+ * @see References to other sections (if any)...
35
+ */
36
+ class Bronto_Roundtrip_Model_Roundtrip
37
+ {
38
+ // {{{ properties
39
+
40
+ /**
41
+ * Description for const
42
+ */
43
+ const NOTICE_IDENTIFER = 'bronto_roundtrip';
44
+
45
+ /**
46
+ * Description for private
47
+ * @var string
48
+ * @access private
49
+ */
50
+ private $_sandboxApiToken = '077E2083-BBED-4B16-A3AB-E1095EAA2E58';
51
+ // private $_sandboxApiToken = 'A02B75E2-D624-4404-AA28-44A306C08ECF';
52
+ // private $_sandboxApiToken = '53873730-F77B-4B0D-9840-43F21846F991';
53
+
54
+
55
+ /**
56
+ * Description for private
57
+ * @var string
58
+ * @access private
59
+ */
60
+ // private $_sandboxEmail = 'adam.daniels+sandbox@atlanticbt.com';
61
+ private $_sandboxEmail = 'ps-eng@bronto.com';
62
+ // private $_sandboxEmail = 'chris.duffy@atlanticbt.com';
63
+
64
+ // }}}
65
+ // {{{ processRoundtrip()
66
+
67
+ /**
68
+ * @return array
69
+ * @access public
70
+ */
71
+ public function processRoundtrip()
72
+ {
73
+ $status = true;
74
+ $helper = Mage::helper(self::NOTICE_IDENTIFER);
75
+
76
+ // Run through all API's ups to ensure valid API tokens
77
+ //
78
+ // keep the '/data' on the helper alias else EcomDev_PHPUnit will
79
+ // not properly replace the correct registry key for unit test which
80
+ // exerts test for gracefull failure recovery
81
+ if (!Mage::helper('bronto_common/data')->validApiTokens()) {
82
+ $helper->setRoundtripStatus($helper->getPath('sandbox_connect'), '0');
83
+ return false;
84
+ }
85
+
86
+ // Try Connecting to Sandbox Account
87
+ $api = $this->_testSandboxConnect();
88
+ if ($api) {
89
+ $helper->setRoundtripStatus($helper->getPath('sandbox_connect'), '1');
90
+ } else {
91
+ // if we can't get the api, we cant do anything else
92
+ $helper->setRoundtripStatus($helper->getPath('sandbox_connect'), '0');
93
+ return false;
94
+ }
95
+
96
+ // Try Creating Transactional Contact
97
+ $contact = $this->_testCreateContact($api);
98
+ if ($contact) {
99
+ $helper->setRoundtripStatus($helper->getPath('sandbox_create_contact'), '1');
100
+ } else {
101
+ $helper->setRoundtripStatus($helper->getPath('sandbox_create_contact'), '0');
102
+ $status = false;
103
+ }
104
+
105
+ // Try Creating Onboarding Contact
106
+ if ($this->_testAddContactToList($api, $contact)) {
107
+ $helper->setRoundtripStatus($helper->getPath('sandbox_change_contact'), '1');
108
+ } else {
109
+ $helper->setRoundtripStatus($helper->getPath('sandbox_change_contact'), '0');
110
+ $status = false;
111
+ }
112
+
113
+ // Try to Import order for Contact
114
+ if ($this->_testProcessOrder($api, $contact)) {
115
+ $helper->setRoundtripStatus($helper->getPath('sandbox_import_order'), '1');
116
+ } else {
117
+ $helper->setRoundtripStatus($helper->getPath('sandbox_import_order'), '0');
118
+ $status = false;
119
+ }
120
+
121
+ // Set setting and return results
122
+ if ($status) {
123
+ $helper->setRoundtripStatus($helper->getPath('status'), '1');
124
+ } else {
125
+ $helper->setRoundtripStatus($helper->getPath('status'), '0');
126
+ }
127
+
128
+ return $status;
129
+ }
130
+
131
+ // }}}
132
+ // {{{ _assertContactAttribute()
133
+
134
+ /**
135
+ * Function to assert a value matches a contact attribute
136
+ *
137
+ * @param Bronto_Common_Model_Api $api
138
+ * @param string $email
139
+ * @param string $attribute
140
+ * @param string $value
141
+ *
142
+ * @return boolean
143
+ * @access private
144
+ */
145
+ private function _assertContactAttribute(
146
+ Bronto_Common_Model_Api $api,
147
+ $email,
148
+ $attribute,
149
+ $value
150
+ ) {
151
+ $contactObject = $api->getContactObject();
152
+
153
+ // Load Contact
154
+ $contact = $contactObject->createRow();
155
+ $contact->email = $email;
156
+
157
+ try {
158
+ $contact->read();
159
+ } catch (Exception $e) {
160
+ // Contact doesn't exist
161
+ Mage::helper('bronto_roundtrip')->writeDebug('could not read contact');
162
+ return false;
163
+ }
164
+
165
+ if (!$contact->id) {
166
+ Mage::helper('bronto_roundtrip')->writeDebug('could not find contact');
167
+ return false;
168
+ }
169
+
170
+ if (!$contact->{$attribute} == $value) {
171
+ Mage::helper('bronto_roundtrip')->writeDebug('could not assert that contact ' . $attribute . ': ' . $contact->{$attribute} . ' == ' . $value);
172
+ return false;
173
+ }
174
+
175
+ Mage::helper('bronto_roundtrip')->writeDebug('Asserted that contact ' . $attribute . ': ' . $contact->{$attribute} . ' == ' . $value);
176
+ return true;
177
+ }
178
+
179
+ // }}}
180
+ // {{{ _testSandboxConnect()
181
+
182
+ /**
183
+ * Create api instance and attempt to log in
184
+ *
185
+ * @return boolean|Ambigous <Bronto_Common_Model_Api, multitype:>
186
+ * @access protected
187
+ */
188
+ protected function _testSandboxConnect()
189
+ {
190
+ $api = Bronto_Common_Model_Api::getInstance($this->_sandboxApiToken);
191
+
192
+ if (!$api->login()) {
193
+ return false;
194
+ }
195
+
196
+ return $api;
197
+ }
198
+
199
+ // }}}
200
+ // {{{ _testCreateContact()
201
+
202
+ /**
203
+ * Create a test Contact
204
+ *
205
+ * @param Bronto_Common_Model_Api $api
206
+ *
207
+ * @return boolean|Bronto_Api_Contact_Row
208
+ * @access protected
209
+ */
210
+ protected function _testCreateContact(Bronto_Common_Model_Api $api)
211
+ {
212
+ $commonHelper = Mage::helper('bronto_common/contact');
213
+
214
+ // Load Contact
215
+ $contactObject = $api->getContactObject();
216
+ $contact = $contactObject->createRow();
217
+ $contact->email = $this->_sandboxEmail;
218
+
219
+ // Get Contact Info
220
+ try {
221
+ $contact->read();
222
+ } catch (Exception $e) {
223
+ $contact->customSource = 'Api';
224
+ }
225
+
226
+ // If Test contact exists, remove it and create a new one
227
+ if ($contact->id) {
228
+ $contact->delete($contact->id);
229
+
230
+ $contactObject = $api->getContactObject();
231
+ $contact = $contactObject->createRow();
232
+ $contact->email = $this->_sandboxEmail;
233
+ }
234
+
235
+ // Try to save with new info
236
+ if (!$commonHelper->saveContact($contact)) {
237
+ Mage::helper('bronto_roundtrip')->writeDebug('could not save contact');
238
+ return false;
239
+ }
240
+
241
+ Mage::helper('bronto_roundtrip')->writeDebug('Added Contact');
242
+ return $contact;
243
+ }
244
+
245
+ // }}}
246
+ // {{{ _testAddContactToList()
247
+
248
+ /**
249
+ * Test adding contact to list
250
+ *
251
+ * @param Bronto_Common_Model_Api $api
252
+ * @param Bronto_Api_Contact_Row $contact
253
+ *
254
+ * @return boolean|Bronto_Api_Contact_Row
255
+ * @access protected
256
+ */
257
+ protected function _testAddContactToList(
258
+ Bronto_Common_Model_Api $api,
259
+ Bronto_Api_Contact_Row $contact
260
+ ) {
261
+ // Set Status to Transactional
262
+ $contact->status = Bronto_Api_Contact::STATUS_TRANSACTIONAL;
263
+
264
+ if (!Mage::helper('bronto_common/contact')->saveContact($contact)) {
265
+ Mage::helper('bronto_roundtrip')->writeDebug('could not save contact');
266
+ return false;
267
+ }
268
+
269
+ if (!$this->_assertContactAttribute($api, $contact->email, 'status', Bronto_Api_Contact::STATUS_TRANSACTIONAL)) {
270
+ return false;
271
+ }
272
+
273
+ // Get Lists
274
+ $listObject = $api->getListObject();
275
+ foreach ($listObject->readAll() as $list) {
276
+ $contact->addToList($list['id']);
277
+ }
278
+
279
+ $contact->status = Bronto_Api_Contact::STATUS_ONBOARDING;
280
+
281
+ if (!Mage::helper('bronto_common/contact')->saveContact($contact)) {
282
+ Mage::helper('bronto_roundtrip')->writeDebug('could not save contact');
283
+ return false;
284
+ }
285
+
286
+ if (!$this->_assertContactAttribute($api, $contact->email, 'status', Bronto_Api_Contact::STATUS_ONBOARDING)) {
287
+ return false;
288
+ }
289
+
290
+ Mage::helper('bronto_roundtrip')->writeDebug('Updated Contact with transactional status');
291
+ return $contact;
292
+ }
293
+
294
+ // }}}
295
+ // {{{ _testProcessOrder()
296
+
297
+ /**
298
+ * Spoof processing an order
299
+ *
300
+ * @param Bronto_Common_Model_Api $api
301
+ * @param Bronto_Api_Contact_Row $contact
302
+ *
303
+ * @return boolean
304
+ * @access protected
305
+ */
306
+ protected function _testProcessOrder(
307
+ Bronto_Common_Model_Api $api,
308
+ Bronto_Api_Contact_Row $contact
309
+ ) {
310
+ try {
311
+ /* @var $orderObject Bronto_Api_Order */
312
+ $orderObject = $api->getOrderObject();
313
+
314
+ /* @var $brontoOrder Bronto_Api_Order_Row */
315
+ $brontoOrder = $orderObject->createRow();
316
+ $brontoOrder->id = substr(rand(), 0, 4);
317
+
318
+ try {
319
+ $brontoOrder->read();
320
+ } catch (Exception $e) {
321
+ // do nothing
322
+ }
323
+
324
+ $brontoOrder->email = $contact->email;
325
+ $brontoOrder->orderDate = date('c', time());
326
+ $brontoOrder->tid = null;
327
+ $brontoOrderItems = array(
328
+ array(
329
+ 'id' => substr(rand(), 0, 4),
330
+ 'sku' => substr(rand(), 0, 10),
331
+ 'name' => 'sandbox sample product',
332
+ 'description' => 'this is a fake product for testing',
333
+ 'category' => '1',
334
+ 'image' => null,
335
+ 'url' => 'http://www.atlanticbt.com',
336
+ 'quantity' => (int) '2',
337
+ 'price' => (float) '2.40',
338
+ )
339
+ );
340
+
341
+ $brontoOrder->products = $brontoOrderItems;
342
+ $brontoOrder->persist();
343
+
344
+ $flushResult = $orderObject->flush();
345
+
346
+ $flushResultErrors = array();
347
+ foreach ($flushResult as $i => $flushResultRow) {
348
+ if ($flushResultRow->hasError()) {
349
+ $flushResultErrors[] = array(
350
+ 'errorCode' => $flushResultRow->getErrorCode(),
351
+ 'errorMessage' => $flushResultRow->getErrorMessage(),
352
+ );
353
+ }
354
+ }
355
+
356
+ if (count($flushResultErrors)) {
357
+ Mage::helper('bronto_roundtrip')->writeDebug(print_r($flushResultErrors, true));
358
+ Mage::log(print_r($orderObject, true), null, 'roundtrip_error.log');
359
+ return false;
360
+ }
361
+
362
+
363
+ // Cleanup
364
+ $brontoOrder->delete();
365
+
366
+ return true;
367
+ } catch (Exception $e) {
368
+ Mage::helper('bronto_roundtrip')->writeError($e->getMessage());
369
+ // what happens to the bronto order
370
+ if ($brontoOrder->id) {
371
+ $brontoOrder->delete();
372
+ }
373
+ return false;
374
+ }
375
+ }
376
+
377
+ // }}}
378
+ }
app/code/community/Bronto/Roundtrip/Model/Roundtrip/Test/Order.php ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Test the order request
5
+ *
6
+ * PHP version 5
7
+ *
8
+ * The license text...
9
+ *
10
+ * @category Bronto
11
+ * @package Roundtrip
12
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
13
+ * @copyright 2012 Atlantic BT
14
+ * @license http://www.atlanticbt.com/ Atlantic BT
15
+ * @version CVS: $Id:$
16
+ * @link <>
17
+ * @see References to other sections (if any)...
18
+ */
19
+
20
+ /**
21
+ * Test the order request
22
+ *
23
+ * @category Bronto
24
+ * @package Roundtrip
25
+ * @author Jamie Kahgee <jamie.kahgee@atlanticbt.com>
26
+ * @copyright 2012 Atlantic BT
27
+ * @license http://www.atlanticbt.com/ Atlantic BT
28
+ * @version Release: @package_version@
29
+ * @link <>
30
+ * @see References to other sections (if any)...
31
+ */
32
+ class Bronto_Roundtrip_Model_Roundtrip_Test_Order
33
+ {
34
+ // {{{ processOrder()
35
+
36
+ /**
37
+ * Process a stub order over to Bronto
38
+ *
39
+ * @param Bronto_Api_Order $order
40
+ * @param Bronto_Api_Contact_Row $contact contact to associate to order
41
+ *
42
+ * @return boolean
43
+ * @access public
44
+ */
45
+ public function processOrder(
46
+ Bronto_Api_Order $order,
47
+ Bronto_Api_Contact_Row $contact
48
+ ) {
49
+ try {
50
+ $helper = Mage::helper('bronto_roundtrip');
51
+ /* @var $row Bronto_Api_Order_Row */
52
+ $row = $order->createRow();
53
+ // Get new increment so we don't conflict w/ any existing
54
+ // increment id
55
+ $incrementId = Mage::getSingleton('eav/config')
56
+ ->getEntityType('order')
57
+ ->fetchNewIncrementId(1);
58
+
59
+ $row->email = $contact->email;
60
+ $row->contactId = $contact->id;
61
+ $row->id = $incrementId;
62
+ $row->orderDate = date('c', time());
63
+
64
+ $row->addProduct(
65
+ array(
66
+ 'id' => substr(rand(), 0, 4),
67
+ 'sku' => substr(rand(), 0, 10),
68
+ 'name' => 'Sandbox Sample Product',
69
+ 'description' => 'This is a fake product for testing',
70
+ 'category' => 1,
71
+ 'image' => NULL,
72
+ 'url' => 'http://www.atlanticbt.com/',
73
+ 'quantity' => 2,
74
+ 'price' => 2.40,
75
+ )
76
+ );
77
+
78
+ $row->persist();
79
+ $writeCache = $order->flush();
80
+
81
+ // flush out the write cache
82
+ $errors = array();
83
+ foreach ($writeCache as $row) {
84
+ if ($row->hasError()) {
85
+ $errors[] = array(
86
+ 'errorCode' => $row->getErrorCode(),
87
+ 'errorMessage' => $row->getErrorMessage(),
88
+ );
89
+ }
90
+ }
91
+
92
+ if (count($errors)) {
93
+ $helper->writeDebug(print_r($errors, true));
94
+ $helper->writeError(print_r($errors, true));
95
+ return false;
96
+ }
97
+
98
+ $order->delete();
99
+ return true;
100
+ } catch (Exception $e) {
101
+ $helper->writeError($e);
102
+ }
103
+ }
104
+
105
+ // }}}
106
+ }
app/code/community/Bronto/Roundtrip/Test/Config/Config.php ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_Roundtrip_Test_Config_Config
3
+ extends EcomDev_PHPUnit_Test_Case_Config
4
+ {
5
+ public function blocksProvider()
6
+ {
7
+ return array(
8
+ array('bronto_roundtrip/adminhtml_system_config_about', 'Bronto_Roundtrip_Block_Adminhtml_System_Config_About'),
9
+ array('bronto_roundtrip/adminhtml_system_config_status', 'Bronto_Roundtrip_Block_Adminhtml_System_Config_Status'),
10
+ array('bronto_roundtrip/adminhtml_widget_button_run', 'Bronto_Roundtrip_Block_Adminhtml_Widget_Button_Run'),
11
+ );
12
+ }
13
+
14
+ public function resourceModelProvider()
15
+ {
16
+ return array();
17
+ }
18
+
19
+ public function modelsProvider()
20
+ {
21
+ return array(
22
+ array('bronto_roundtrip/roundtrip', 'Bronto_Roundtrip_Model_Roundtrip'),
23
+ );
24
+ }
25
+
26
+ public function helpersProvider()
27
+ {
28
+ return array(
29
+ array('bronto_roundtrip/data', 'Bronto_Roundtrip_Helper_Data'),
30
+ );
31
+ }
32
+
33
+ public function observersProvider()
34
+ {
35
+ return array();
36
+ }
37
+
38
+ public function definedLayoutFilesProvider()
39
+ {
40
+ return array(
41
+ array('adminhtml', 'bronto/roundtrip.xml'),
42
+ );
43
+ }
44
+
45
+ public function themeLayoutFilesExistProvider()
46
+ {
47
+ return array(
48
+ array('adminhtml', 'bronto/roundtrip.xml', 'default', 'default'),
49
+ );
50
+ }
51
+
52
+ public function dependsProvider()
53
+ {
54
+ return array(
55
+ array('Bronto_Common'),
56
+ );
57
+ }
58
+
59
+ /**
60
+ * @test
61
+ * @group amd
62
+ * @group config
63
+ */
64
+ public function assertRoundtripModuleVersionGreaterThanOrEquals()
65
+ {
66
+ $this->assertModuleVersionGreaterThanOrEquals('0.1.0');
67
+ }
68
+
69
+ /**
70
+ * @test
71
+ * @group amd
72
+ * @group config
73
+ */
74
+ public function assertRoundtripModuleInCommunityCodePool()
75
+ {
76
+ $this->assertModuleCodePool('community');
77
+ }
78
+
79
+ /**
80
+ * @test
81
+ * @group amd
82
+ * @group config
83
+ * @dataProvider dependsProvider
84
+ */
85
+ public function assertRoundtripModuleDepends(
86
+ $requiredModuleName
87
+ ) {
88
+ $this->assertModuleDepends($requiredModuleName);
89
+ }
90
+
91
+ /**
92
+ * @test
93
+ * @group amd
94
+ * @group config
95
+ * @dataProvider modelsProvider
96
+ */
97
+ public function assertRoundtripModelAliases(
98
+ $classAlias,
99
+ $expectedClassName
100
+ ) {
101
+ $this->assertModelAlias($classAlias, $expectedClassName);
102
+ }
103
+
104
+ /**
105
+ * test
106
+ * @group amd
107
+ * @group config
108
+ * @dataProvider resourceModelProvider
109
+ */
110
+ public function assertRoundtripResourceModelAliases(
111
+ $classAlias,
112
+ $expectedClassName
113
+ ) {
114
+ $this->assertResourceModelAlias($classAlias, $expectedClassName);
115
+ }
116
+
117
+ /**
118
+ * @test
119
+ * @group amd
120
+ * @group config
121
+ * @dataProvider blocksProvider
122
+ */
123
+ public function assertRoundtripBlockAliases(
124
+ $classAlias,
125
+ $expectedClassName
126
+ ) {
127
+ $this->assertBlockAlias($classAlias, $expectedClassName);
128
+ }
129
+
130
+ /**
131
+ * @test
132
+ * @group amd
133
+ * @group config
134
+ * @dataProvider helpersProvider
135
+ */
136
+ public function assertRoundtripHelperAliases(
137
+ $classAlias,
138
+ $expectedClassName
139
+ ) {
140
+ $this->assertHelperAlias($classAlias, $expectedClassName);
141
+ }
142
+
143
+ /**
144
+ * test
145
+ * @group amd
146
+ * @group config
147
+ * @dataProvider observersProvider
148
+ */
149
+ public function assertRoundtripEventObserversDefined(
150
+ $area,
151
+ $eventName,
152
+ $observerClassAlias,
153
+ $observerMethod
154
+ ) {
155
+ $this->assertEventObserversDefined(
156
+ $area,
157
+ $eventName,
158
+ $observerClassAlias,
159
+ $observerMethod
160
+ );
161
+ }
162
+
163
+ /**
164
+ * @test
165
+ * @group amd
166
+ * @group config
167
+ * @dataProvider definedLayoutFilesProvider
168
+ */
169
+ public function assertRoundtripLayoutFileDefined(
170
+ $area,
171
+ $expectedFileName
172
+ ) {
173
+ $this->assertLayoutFileDefined($area, $expectedFileName);
174
+ }
175
+
176
+ /**
177
+ * @test
178
+ * @group amd
179
+ * @group config
180
+ * @dataProvider themeLayoutFilesExistProvider
181
+ */
182
+ public function assertRoundtripLayoutFileExistsInTheme (
183
+ $area,
184
+ $filename,
185
+ $theme,
186
+ $designPackage
187
+ ) {
188
+ $this->assertLayoutFileExistsInTheme(
189
+ $area,
190
+ $filename,
191
+ $theme,
192
+ $designPackage
193
+ );
194
+ }
195
+ }
196
+
app/code/community/Bronto/Roundtrip/Test/Model/Roundtrip.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Bronto_RoundTrip_Test_Model_Roundtrip
4
+ extends EcomDev_PHPUnit_Test_Case
5
+ {
6
+ // {{{ testProcessOrderShouldFailGracefully()
7
+
8
+ /**
9
+ * Test that if there is an exception, the bronto order is successfully
10
+ * cleaned up so the next test will be able to run.
11
+ *
12
+ * @test
13
+ * @group jmk
14
+ * @group model
15
+ */
16
+ public function testProcessOrderShouldFailGracefully()
17
+ {
18
+ // Create helper mock that will be used in logic
19
+ $helper = $this->getHelperMock('bronto_common', array('validApiTokens'));
20
+ $helper->expects($this->once())
21
+ ->method('validApiTokens')
22
+ ->will($this->returnValue(true));
23
+
24
+ // Inject helper object as item to be invoked when static
25
+ // method called to get helper
26
+ $this->replaceByMock('helper', 'bronto_common', $helper);
27
+
28
+ // Mock the roundtrip object so we can
29
+ // control how functionality is controlled
30
+ $roundTrip = $this->getModelMock(
31
+ 'bronto_roundtrip/roundtrip',
32
+ array(
33
+ '_testSandboxConnect',
34
+ '_testCreateContact',
35
+ '_testAddContactToList',
36
+ )
37
+ );
38
+
39
+ // This is the final object we need to verify
40
+ $orderRowMock = $this->getMock('Bronto_Api_Order_Row', array('persist', 'read', 'delete'));
41
+ $orderRowMock->expects($this->any())
42
+ ->method('read');
43
+ // Throw a random exception on this method to ensure we kick down
44
+ // into the outer catch stmt.
45
+ $orderRowMock->expects($this->any())
46
+ ->method('persist')
47
+ ->will($this->throwException(new RunTimeException('Unexpected Error.')));
48
+ // don't try to actually delete anything here, just ensure we hit it.
49
+ $orderRowMock->expects($this->any())
50
+ ->method('delete');
51
+
52
+ // Mock the order object used to the get order row
53
+ $orderObjectMock = $this->getMock('Bronto_Api_Order', array('createRow'));
54
+ $orderObjectMock->expects($this->any())
55
+ ->method('createRow')
56
+ ->will($this->returnValue($orderRowMock));
57
+
58
+ // Mock the API object passed into the _testProcessOrder method
59
+ $apiMock = $this->getMock('Bronto_Api', array('getOrderObject'));
60
+ $apiMock->expects($this->any())
61
+ ->method('getOrderObject')
62
+ ->will($this->returnValue($orderObjectMock));
63
+
64
+ // Don't care about any of the following methods - just need to be
65
+ // Mocked so they don't choke the system when testing.
66
+ $roundTrip->expects($this->any())
67
+ ->method('_testSandboxConnect')
68
+ ->will($this->returnValue($apiMock));
69
+
70
+ $roundTrip->expects($this->any())
71
+ ->method('_testCreateContact')
72
+ ->will($this->returnValue(true));
73
+
74
+ $roundTrip->expects($this->any())
75
+ ->method('_testAddContactToList')
76
+ ->will($this->returnValue(true));
77
+
78
+ $roundTrip->processRoundtrip();
79
+ }
80
+
81
+ // }}}
82
+ }
app/code/community/Bronto/Roundtrip/Test/Model/Roundtrip/Contact.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Bronto_RoundTrip_Test_Model_Roundtrip_Contact
3
+ extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+ const TOKEN = '53873730-F77B-4B0D-9840-43F21846F991';
6
+
7
+ // {{{ getContactShouldReturnContact()
8
+
9
+ /**
10
+ * @test
11
+ * @group jmk
12
+ * @group model
13
+ */
14
+ public function getContactShouldReturnContact()
15
+ {
16
+ $api = Bronto_Common_Model_Api::getInstance(self::TOKEN);
17
+ $builder = new Bronto_Roundtrip_Model_Contact_Builder($api);
18
+ $contact = $builder->getContact();
19
+
20
+ $this->assertInstanceOf('Bronto_Api_Contact_Row', $contact);
21
+ }
22
+
23
+ // }}}
24
+ }
app/code/community/Bronto/Roundtrip/Test/Model/Roundtrip/Test/Order.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Bronto_RoundTrip_Test_Model_Roundtrip_Test_Order
4
+ extends EcomDev_PHPUnit_Test_Case
5
+ {
6
+ // const TOKEN = '53873730-F77B-4B0D-9840-43F21846F991';
7
+ const TOKEN = '077E2083-BBED-4B16-A3AB-E1095EAA2E58';
8
+
9
+ // {{{ processOrdersShouldPlaceOrderWithApi()
10
+
11
+ /**
12
+ * Test that if there is an exception, the bronto order is successfully
13
+ * cleaned up so the next test will be able to run.
14
+ *
15
+ * @test
16
+ * @group jmk
17
+ * @group model
18
+ */
19
+ public function processOrdersShouldPlaceOrderWithApi()
20
+ {
21
+ // Mock the order object used to the get order row
22
+ $api = Bronto_Common_Model_Api::getInstance(self::TOKEN);
23
+ $builder = new Bronto_Roundtrip_Model_Contact_Builder($api);
24
+
25
+ $order = $api->getOrderObject();
26
+ $contact = $builder->getContact();
27
+
28
+ $testOrder = Mage::getModel('bronto_roundtrip/roundtrip_test_order');
29
+ $testOrder->processOrder($order, $contact);
30
+ }
31
+
32
+ // }}}
33
+ }
app/code/community/Bronto/Roundtrip/controllers/Adminhtml/RoundtripController.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @category Bronto
5
+ * @package Roundtrip
6
+ */
7
+ class Bronto_Roundtrip_Adminhtml_RoundtripController extends Mage_Adminhtml_Controller_Action
8
+ {
9
+ // {{{ runAction()
10
+
11
+ /**
12
+ * Run immediately
13
+ *
14
+ * @return void
15
+ * @access public
16
+ */
17
+ public function runAction()
18
+ {
19
+ try {
20
+ $model = Mage::getModel('bronto_roundtrip/roundtrip');
21
+
22
+ $result = $model->processRoundtrip();
23
+
24
+ if ($result) {
25
+ $this->_getSession()->addSuccess('Roundtrip Verification Passed');
26
+ } else {
27
+ $this->_getSession()->addError('Roundtrip Verification Failed');
28
+ }
29
+
30
+ } catch (Exception $e) {
31
+ $this->_getSession()->addError($e->getMessage());
32
+ Mage::helper('bronto_roundtrip')->writeError($e);
33
+ }
34
+
35
+ $this->_redirect('*/system_config/edit', array('section' => 'bronto_roundtrip'));
36
+ }
37
+
38
+ // }}}
39
+ // {{{ _isAllowed()
40
+
41
+ /**
42
+ * @return bool
43
+ * @access protected
44
+ */
45
+ protected function _isAllowed()
46
+ {
47
+ return $this->_isSectionAllowed('bronto_roundtrip');
48
+ }
49
+
50
+ // }}}
51
+ // {{{ _isSectionAllowed()
52
+
53
+ /**
54
+ * Check if specified section allowed in ACL
55
+ *
56
+ * Will forward to deniedAction(), if not allowed.
57
+ *
58
+ * @param string $section
59
+ *
60
+ * @return bool
61
+ * @access protected
62
+ */
63
+ protected function _isSectionAllowed($section)
64
+ {
65
+ try {
66
+ $session = Mage::getSingleton('admin/session');
67
+ $resourceLookup = "admin/system/config/{$section}";
68
+ if ($session->getData('acl') instanceof Mage_Admin_Model_Acl) {
69
+ $resourceId = $session->getData('acl')->get($resourceLookup)->getResourceId();
70
+ if (!$session->isAllowed($resourceId)) {
71
+ throw new Exception('');
72
+ }
73
+ return true;
74
+ }
75
+ } catch (Zend_Acl_Exception $e) {
76
+ $this->norouteAction();
77
+ $this->setFlag('', self::FLAG_NO_DISPATCH, true);
78
+ return false;
79
+ } catch (Exception $e) {
80
+ $this->deniedAction();
81
+ $this->setFlag('', self::FLAG_NO_DISPATCH, true);
82
+ return false;
83
+ }
84
+ }
85
+
86
+ // }}}
87
+ }
app/code/community/Bronto/Roundtrip/etc/adminhtml.xml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * @category Bronto
5
+ * @package Bronto_Roundtrip
6
+ * @author Adam Daniels <adam.daniels@atlanticbt.com>
7
+ * @copyright 2012 Adam Daniels
8
+ * @license http://www.atlanticbt.com/ Atlantic BT
9
+ */
10
+ -->
11
+ <config>
12
+ <acl>
13
+ <resources>
14
+ <admin>
15
+ <children>
16
+ <system>
17
+ <children>
18
+ <config>
19
+ <children>
20
+ <bronto_roundtrip module="bronto_roundtrip">
21
+ <title>Bronto Rountrip Verification</title>
22
+ </bronto_roundtrip>
23
+ </children>
24
+ </config>
25
+ </children>
26
+ </system>
27
+ </children>
28
+ </admin>
29
+ </resources>
30
+ </acl>
31
+ </config>
app/code/community/Bronto/Roundtrip/etc/config.xml ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /**
4
+ * @category Bronto
5
+ * @package Bronto_Roundtrip
6
+ * @author Adam Daniels <adam.daniels@atlanticbt.com>
7
+ * @copyright 2012 Adam Daniels
8
+ * @license http://www.atlanticbt.com/ Atlantic BT
9
+ */
10
+ -->
11
+ <config>
12
+ <modules>
13
+ <Bronto_Roundtrip>
14
+ <version>0.1.0</version>
15
+ </Bronto_Roundtrip>
16
+ </modules>
17
+ <global>
18
+ <blocks>
19
+ <bronto_roundtrip>
20
+ <class>Bronto_Roundtrip_Block</class>
21
+ </bronto_roundtrip>
22
+ </blocks>
23
+ <helpers>
24
+ <bronto_roundtrip>
25
+ <class>Bronto_Roundtrip_Helper</class>
26
+ </bronto_roundtrip>
27
+ </helpers>
28
+ <models>
29
+ <bronto_roundtrip>
30
+ <class>Bronto_Roundtrip_Model</class>
31
+ </bronto_roundtrip>
32
+ </models>
33
+ </global>
34
+ <admin>
35
+ <routers>
36
+ <adminhtml>
37
+ <args>
38
+ <modules>
39
+ <bronto_roundtrip before="Mage_Adminhtml">Bronto_Roundtrip_Adminhtml</bronto_roundtrip>
40
+ </modules>
41
+ </args>
42
+ </adminhtml>
43
+ </routers>
44
+ </admin>
45
+ <adminhtml>
46
+ <layout>
47
+ <updates>
48
+ <bronto_roundtrip>
49
+ <file>bronto/roundtrip.xml</file>
50
+ </bronto_roundtrip>
51
+ </updates>
52
+ </layout>
53
+ <acl>
54
+ <resources>
55
+ <admin>
56
+ <children>
57
+ <system>
58
+ <children>
59
+ <config>
60
+ <children>
61
+ <bronto_roundtrip translate="title" module="bronto_roundtrip">
62
+ <title>Bronto Roundtrip Verification</title>
63
+ <sort_order>900</sort_order>
64
+ </bronto_roundtrip>
65
+ </children>
66
+ </config>
67
+ </children>
68
+ </system>
69
+ </children>
70
+ </admin>
71
+ </resources>
72
+ </acl>
73
+ </adminhtml>
74
+ <phpunit>
75
+ <suite>
76
+ <modules>
77
+ <Bronto_Roundtrip />
78
+ </modules>
79
+ </suite>
80
+ </phpunit>
81
+ </config>
app/code/community/Bronto/Roundtrip/etc/system.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <bronto_roundtrip translate="label" module="bronto_roundtrip">
5
+ <label>Install Verification</label>
6
+ <tab>bronto</tab>
7
+ <sort_order>900</sort_order>
8
+ <show_in_default>1</show_in_default>
9
+ <show_in_website>0</show_in_website>
10
+ <show_in_store>0</show_in_store>
11
+ <groups>
12
+ <status>
13
+ <frontend_type>text</frontend_type>
14
+ <frontend_model>bronto_roundtrip/adminhtml_system_config_status</frontend_model>
15
+ <sort_order>2</sort_order>
16
+ <show_in_default>1</show_in_default>
17
+ <show_in_website>1</show_in_website>
18
+ <show_in_store>1</show_in_store>
19
+ </status>
20
+ </groups>
21
+ </bronto_roundtrip>
22
+ </sections>
23
+ </config>
app/design/adminhtml/default/default/layout/bronto/email.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout>
3
+ <adminhtml_system_email_log_index>
4
+ <reference name="content">
5
+ <block type="bronto_email/adminhtml_system_email_log" />
6
+ </reference>
7
+ </adminhtml_system_email_log_index>
8
+ </layout>
app/design/adminhtml/default/default/layout/bronto/reminder.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout>
3
+ <adminhtml_promo_quote_edit>
4
+ <reference name="content">
5
+ <block type="bronto_reminder/adminhtml_promo_notice" name="promo_edit_notice"/>
6
+ </reference>
7
+ </adminhtml_promo_quote_edit>
8
+ </layout>
app/design/adminhtml/default/default/layout/bronto/roundtrip.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout>
3
+ <adminhtml_system_roundtrip_status_index>
4
+ <reference name="content">
5
+ <block type="bronto_roundtrip/adminhtml_system_roundtrip_status" />
6
+ </reference>
7
+ </adminhtml_system_roundtrip_status_index>
8
+ </layout>
app/design/adminhtml/default/default/template/bronto/common/about.phtml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php /* var $this Bronto_Common_Block_Adminhtml_System_Config_About */ ?>
2
+
3
+ <div style="background-color: #f4f9f5; border: 1px solid #D6D6D6; margin-bottom: 10px; padding: 10px 5px 15px 30px; color: #000">
4
+ <a href="http://www.bronto.com" target="_blank" title="Bronto Software Homepage"><img src="<?php echo $this->getSkinUrl('bronto/images/logo.jpg') ?>" /></a>
5
+ <?php if ($this->getModuleNamespace() === 'bronto_common'): ?>
6
+ <br />
7
+ <strong>
8
+ <?php echo $this->getModuleName(); ?> <?php echo $this->getModuleVersion(); ?>
9
+ (<a href="http://a.bron.to/magento" target="_blank" title="Bronto Magento Extension Documentation">Documentation</a>)
10
+ </strong>
11
+ <br />
12
+ <span style="color: #666">Copyright &copy; 2011-<?php echo date('Y'); ?></span>
13
+ <span style="color: #ccc">|</span>
14
+ <a href="mailto:info@bronto.com" target="_blank">info@bronto.com</a>
15
+ <?php endif; ?>
16
+ </div>
app/design/adminhtml/default/default/template/bronto/common/cron.phtml ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php /* var $this Bronto_Common_Block_Adminhtml_System_Config_Cron */ ?>
2
+
3
+ <div class="grid bronto-cron">
4
+ <?php if ($this->hasProgressBar()): ?>
5
+ <?php echo $this->getProgressBarHtml(); ?>
6
+ <?php endif; ?>
7
+ <?php echo $this->getButtonsHtml(); ?>
8
+ <table width="100%" cellpadding="0" cellspacing="0" border="0" class="bronto-cron-table data">
9
+ <thead>
10
+ <tr class="">
11
+ <th width="150">Created</th>
12
+ <th width="150">Scheduled</th>
13
+ <th width="150">Executed</th>
14
+ <th width="150">Finished</th>
15
+ <th>Message</th>
16
+ <th width="200">Status</th>
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ <?php $_jobSchedule = $this->getJobSchedule(); ?>
21
+ <?php if ($_jobSchedule->count() > 0): ?>
22
+ <?php foreach ($_jobSchedule as $i => $job): ?>
23
+ <tr class="<?php echo ($i % 2 ? 'even' : 'odd'); ?>">
24
+ <td><?php echo $job->getCreatedAt(); ?></td>
25
+ <td><?php echo $job->getScheduledAt(); ?></td>
26
+ <td><?php echo $job->getExecutedAt() == '0000-00-00 00:00:00' ? '&nbsp;' : $job->getExecutedAt(); ?></td>
27
+ <td><?php echo $job->getFinishedAt() == '0000-00-00 00:00:00' ? '&nbsp;' : $job->getFinishedAt(); ?></td>
28
+ <td>
29
+ <pre title="<?php echo $job->getMessages(); ?>">
30
+ <?php echo $this->getTruncatedJobMessages($job) ; ?>
31
+ </pre>
32
+ </td>
33
+ <td><?php echo $this->decorateJobStatus($job->getStatus()); ?></td>
34
+ </tr>
35
+ <?php endforeach; ?>
36
+ <?php else: ?>
37
+ <tr>
38
+ <td colspan="99" style="text-align:center;padding:10px">
39
+ No cron schedules to show - is the Magento cron (<pre style="display:inline">cron.php</pre>) enabled?
40
+ How-To: <a href="http://www.magentocommerce.com/wiki/groups/227/setting_up_magento_in_cron" target="_blank">Setting Up Magento in Cron</a>
41
+ </td>
42
+ </tr>
43
+ <?php endif; ?>
44
+ </tbody>
45
+ </table>
46
+ </div>
app/design/adminhtml/default/default/template/bronto/conflictchecker/errors.phtml ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="entry-edit-head collapseable">
2
+ <a><?php echo $this->getTitle(); ?></a>
3
+ </div>
4
+ <fieldset class="grid">
5
+ <?php $rewrites = $this->getRewrites(); ?>
6
+ <?php if (is_array($rewrites) && !empty($rewrites)) : ?>
7
+ <table class="border">
8
+ <thead>
9
+ <tr class="headings">
10
+ <th>Node</th>
11
+ <th>New Value</th>
12
+ <th>Old Value</th>
13
+ </tr>
14
+ </thead>
15
+ <tbody>
16
+ <?php foreach ($rewrites as $rewrite) : ?>
17
+ <tr class="<?php echo $this->getParity(); ?>">
18
+ <td>
19
+ <div>
20
+ <strong>File :</strong>
21
+ <?php echo $rewrite['file']; ?>
22
+ </div>
23
+ <div>
24
+ <strong>XML Path :</strong>
25
+ <?php echo $rewrite['path']; ?>
26
+ </div>
27
+ </td>
28
+ <td>
29
+ <strong> <?php echo $rewrite['newValue']; ?> </strong>
30
+ </td>
31
+ <td>
32
+ <strong> <?php echo $rewrite['oldValue']; ?> </strong>
33
+ </td>
34
+ </tr>
35
+ <?php endforeach; ?>
36
+ </tbody>
37
+ </table>
38
+ <?php else : ?>
39
+ <table class="border">
40
+ <thead>
41
+ <tr class="headings">
42
+ <th>** No conflicting configuration rewrites **</th>
43
+ </tr>
44
+ </thead>
45
+ </table>
46
+ <?php endif; ?>
47
+ </fieldset>
app/design/adminhtml/default/default/template/bronto/email/template/edit.phtml ADDED
@@ -0,0 +1,256 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ <div class="content-header">
3
+ <h3 class="icon-head head-system-email-template"><?php echo $this->getHeaderText() ?></h3>
4
+ <p class="content-buttons form-buttons">
5
+ <?php echo $this->getBackButtonHtml(); ?>
6
+ <?php echo $this->getResetButtonHtml(); ?>
7
+ <?php if ($this->getEditMode()): ?>
8
+ <?php echo $this->getDeleteButtonHtml(); ?>
9
+ <?php endif ?>
10
+ <?php echo $this->getSaveButtonHtml(); ?>
11
+ </p>
12
+ </div>
13
+
14
+ <?php if (!$this->getEditMode()): ?>
15
+ <form action="<?php echo $this->getLoadUrl() ?>" method="post" id="email_template_load_form">
16
+ <?php echo $this->getBlockHtml('formkey')?>
17
+ <div class="entry-edit">
18
+ <div class="entry-edit-head">
19
+ <h4 class="icon-head head-edit-form fieldset-legend">
20
+ <?php echo Mage::helper('adminhtml')->__('Load Magento Template') ?>
21
+ </h4>
22
+ <div class="form-buttons"></div>
23
+ </div>
24
+ <div class="fieldset">
25
+ <table class="form-list" cellspacing="0">
26
+ <tbody>
27
+ <tr>
28
+ <td class="label">
29
+ <label for="template_select">
30
+ <?php echo Mage::helper('adminhtml')->__('Template') ?>
31
+ <span class="required">*</span>
32
+ </label>
33
+ </td>
34
+ <td class="value">
35
+ <select id="template_select" name="code" class="select required-entry">
36
+ <?php foreach ($this->getTemplateOptions() as $_option): ?>
37
+ <option value="<?php echo $_option['value'] ?>"<?php echo $this->getOrigTemplateCode() == $_option['value'] ? ' selected="selected"' : '' ?>><?php echo $_option['label'] ?></option>
38
+ <?php endforeach; ?>
39
+ </select>
40
+ </td>
41
+ <td></td>
42
+ </tr>
43
+ <tr>
44
+ <td class="label">
45
+ <label for="locale_select">
46
+ <?php echo Mage::helper('adminhtml')->__('Locale') ?>
47
+ <span class="required">*</span>
48
+ </label>
49
+ </td>
50
+ <td class="value">
51
+ <select id="locale_select" name="locale" class="select required-entry">
52
+ <?php foreach ($this->getLocaleOptions() as $_option): ?>
53
+ <option value="<?php echo $_option['value'] ?>"<?php if ($_option['value']==$this->getCurrentLocale()): ?> selected="selected"<?php endif; ?>><?php echo $_option['label'] ?></option>
54
+ <?php endforeach; ?>
55
+ </select>
56
+ </td>
57
+ <td></td>
58
+ </tr>
59
+ <tr>
60
+ <td class="label">
61
+ <label>&nbsp;</label>
62
+ </td>
63
+ <td class="value">
64
+ <?php echo $this->getLoadButtonHtml() ?>
65
+ </td>
66
+ <td></td>
67
+ </tr>
68
+ </tbody>
69
+ </table>
70
+ </div>
71
+ </div>
72
+ </form>
73
+ <?php endif ?>
74
+ <form action="<?php echo $this->getSaveUrl() ?>" method="post" id="email_template_edit_form">
75
+ <?php echo $this->getBlockHtml('formkey')?>
76
+ <fieldset>
77
+ <input type="hidden" id="change_flag_element" name="_change_type_flag" value="" />
78
+ <input type="hidden" id="orig_template_code" name="orig_template_code" value="<?php echo $this->getOrigTemplateCode() ?>" />
79
+ <?php echo $this->getFormHtml() ?>
80
+ </fieldset>
81
+ </form>
82
+ <script type="text/javascript">
83
+ //<![CDATA[
84
+ function replaceAll(txt, replace, with_this) {
85
+ return txt.replace(new RegExp(replace, 'g'), with_this);
86
+ }
87
+
88
+ function ucwords(str) {
89
+ return (str + '').replace(/^([a-z])|\s+([a-z])/g, function ($1) {
90
+ return $1.toUpperCase();
91
+ });
92
+ }
93
+
94
+ function lcfirst(str) {
95
+ str += '';
96
+ var f = str.charAt(0).toLowerCase();
97
+ return f + str.substr(1);
98
+ }
99
+
100
+ function camelize(str, dest_sep, src_sep) {
101
+ dest_sep = dest_sep || '';
102
+ src_sep = src_sep || '_';
103
+ str = ucwords(replaceAll(str, src_sep, ' '));
104
+ str = replaceAll(str, ' ', dest_sep);
105
+ return str;
106
+ }
107
+
108
+ var templateForm = new varienForm('email_template_edit_form');
109
+ var templatePreviewForm = new varienForm('email_template_preview_form');
110
+ var templateControl = {
111
+ unconvertedText: '',
112
+ variables: null,
113
+
114
+ init: function () {
115
+ this.showVariablesKey();
116
+ this.renderPaths(<?php echo $this->getUsedDefaultForPaths(); ?>, 'used_default_for');
117
+ this.renderPaths(<?php echo $this->getUsedCurrentlyForPaths(); ?>, 'used_currently_for');
118
+ },
119
+
120
+ save: function() {
121
+ templateForm.submit();
122
+ return false;
123
+ },
124
+
125
+ deleteTemplate: function() {
126
+ if (window.confirm("<?php echo $this->__('Are you sure that you want to delete this template?') ?>")) {
127
+ window.location.href = '<?php echo $this->getDeleteUrl() ?>';
128
+ }
129
+ },
130
+
131
+ load: function() {
132
+ var form = new varienForm('email_template_load_form');
133
+ if (!form.validator.validate()) {
134
+ return;
135
+ }
136
+ this.variables = null;
137
+ new Ajax.Request($('email_template_load_form').action, {
138
+ parameters: Form.serialize($('email_template_load_form'), true),
139
+ area: $('email_template_load_form'),
140
+ onComplete: function (transport) {
141
+ if (transport.responseText.isJSON()) {
142
+ var fields = $H(transport.responseText.evalJSON());
143
+ fields.each(function(pair) {
144
+ if ($(pair.key)) {
145
+ $(pair.key).value = pair.value.strip();
146
+ }
147
+ if (pair.key == 'orig_template_used_default_for') {
148
+ if (pair.value.length){
149
+ $('used_default_for').show();
150
+ this.renderPaths(pair.value, 'used_default_for');
151
+ }
152
+ else{
153
+ $('used_default_for').hide();
154
+ }
155
+ }
156
+ }.bind(this));
157
+ this.showVariablesKey();
158
+ }
159
+ }.bind(this)
160
+ });
161
+ },
162
+
163
+ convertToBrontoVariable: function(str) {
164
+ if (str.indexOf('{{store') != -1 ||
165
+ str.indexOf('{{skin') != -1 ||
166
+ str.indexOf('{{layout') != -1 ||
167
+ str.indexOf('{{block') != -1) {
168
+ return false;
169
+ }
170
+ str = str.replace('{{var ', ''),
171
+ str = str.replace('{{htmlescape var=$', ''),
172
+ str = str.replace("Formated('long')", ''),
173
+ str = str.replace('}}', '');
174
+ var parts = str.split('.');
175
+ for (var i = 0; i <= parts.length; i++) {
176
+ if (typeof parts[i] != 'undefined') {
177
+ if (parts[i].indexOf('get') == 0) {
178
+ // Method
179
+ parts[i] = parts[i].replace('get', '');
180
+ parts[i] = parts[i].replace('()', '');
181
+ }
182
+ if (parts[i].indexOf('format') == 0) {
183
+ parts.splice(i, 1);
184
+ }
185
+ }
186
+ }
187
+ str = parts.join('_');
188
+ return str;
189
+ },
190
+
191
+ showVariablesKey: function() {
192
+ this.variables = [];
193
+ var templateVariablesValue = $('template_variables').value;
194
+ if (templateVariablesValue) {
195
+ var templateVariables = templateVariablesValue.evalJSON();
196
+ if (templateVariables) {
197
+ var count = 0;
198
+ var listHtml = '<ul>';
199
+ this.variables.push(templateVariables);
200
+ this.variables.each(function(variableGroup) {
201
+ if (variableGroup.label && variableGroup.value) {
202
+ (variableGroup.value).each(function(variable){
203
+ if (variable.value && variable.label) {
204
+ var brontoValue = this.convertToBrontoVariable(variable.value);
205
+ if (brontoValue) {
206
+ listHtml += '<li>';
207
+ listHtml += '<label style="display:block;float:left;font-weight:bold;width:200px">' + variable.label + '</label>';
208
+ listHtml += '<pre>' + lcfirst(camelize(brontoValue)) + '</pre>'
209
+ listHtml += '</li>';
210
+ count++;
211
+ }
212
+ }
213
+ }.bind(this));
214
+ }
215
+ }.bind(this));
216
+ listHtml += '</ul>';
217
+ $('template_variables_key_list').innerHTML = listHtml;
218
+ if (count) {
219
+ $("template_variables_key_row").show();
220
+ } else {
221
+ $("template_variables_key_row").hide();
222
+ }
223
+ }
224
+ }
225
+ },
226
+
227
+ renderPaths: function(paths, fieldId){
228
+ var field = $(fieldId);
229
+ if (field){
230
+ field.down('td').next('td').update(this.parsePath(paths, '<span class="path-delimiter">&nbsp;-&gt;&nbsp;</span>', '<br />'));
231
+ if (paths.length == 0) {
232
+ field.hide();
233
+ }
234
+ }
235
+ },
236
+
237
+ parsePath: function (value, pathDelimiter, lineDelimiter) {
238
+ if (Object.isArray(value)) {
239
+ var result = [];
240
+ for (var i = 0, len = value.length; i < len; i++) {
241
+ result.push(this.parsePath(value[i], pathDelimiter, pathDelimiter));
242
+ }
243
+ return result.join(lineDelimiter);
244
+ }
245
+
246
+ if(!Object.isString(value) && value.title) {
247
+ value = (value.url ? '<a href="' + value.url + '">' + value.title + '</a>' : value.title) + (value.scope ? '&nbsp;&nbsp;<span class="path-scope-label">(' + value.scope + ')</span>' : '');
248
+ }
249
+
250
+ return value;
251
+ }
252
+ };
253
+
254
+ templateControl.init();
255
+ //]]>
256
+ </script>
app/design/adminhtml/default/default/template/bronto/email/template/list.phtml ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Academic Free License (AFL 3.0)
8
+ * that is bundled with this package in the file LICENSE_AFL.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/afl-3.0.php
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 design
22
+ * @package default_default
23
+ * @copyright Copyright (c) 2011 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
25
+ */
26
+ ?>
27
+ <div class="content-header">
28
+ <table cellspacing="0">
29
+ <tr>
30
+ <td style="width:50%;"><h3 class="icon-head head-system-email-template"><?php echo $this->getHeaderText() ?></h3></td>
31
+ <td class="form-buttons">
32
+ <?php echo $this->getChildHtml('log_button') ?>
33
+ <?php echo $this->getChildHtml('import_button') ?>
34
+ <?php echo $this->getChildHtml('add_button') ?>
35
+ </td>
36
+ </tr>
37
+ </table>
38
+ </div>
39
+ <div>
40
+ <?php echo $this->getChildHtml('grid') ?>
41
+ </div>
app/design/adminhtml/default/default/template/bronto/permissionchecker/errors.phtml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="entry-edit-head collapseable"> <a>Errors</a> </div>
2
+ <fieldset class="grid">
3
+ <table class="border">
4
+ <thead>
5
+ <tr class="headings">
6
+ <th>File</th>
7
+ <th>Deviation</th>
8
+ </tr>
9
+ </thead>
10
+ <tbody>
11
+ <?php $errors = $this->getErrors(); ?>
12
+ <?php foreach ($errors as $file => $error) : ?>
13
+ <tr class="<?php echo $this->getParity(); ?>">
14
+ <td><?php echo $file; ?></td>
15
+ <td>
16
+ <?php foreach ($error as $issue => $deviation) : ?>
17
+ <div>
18
+ <strong> <?php echo $issue; ?> </strong>
19
+ is set to
20
+ <strong> <?php echo $deviation; ?> </strong>
21
+ </div>
22
+ <?php endforeach; ?>
23
+ </td>
24
+ </tr>
25
+ <?php endforeach; ?>
26
+ </tbody>
27
+ </table>
28
+ </fieldset>
app/design/adminhtml/default/default/template/bronto/roundtrip/status.phtml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php /* var $this Bronto_Roundtrip_Block_Adminhtml_System_Config_Status */ ?>
2
+
3
+ <div style="background-color: #f4f9f5; border: 1px solid #D6D6D6; margin-bottom: 10px; padding: 10px 5px 15px 30px; color: #666">
4
+ <strong><?php echo $this->getRoundtripButton(); ?> Current Status: <?php echo $this->getRoundtripStatus(); ?></strong>
5
+ </div>
app/locale/en_US/template/email/bronto/abandoned_cart.html ADDED
@@ -0,0 +1,279 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+ <html xmlns="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5
+ <title></title>
6
+ </head>
7
+
8
+ <body>
9
+ <table border="0" cellspacing="0" cellpadding="0" align="center" bgcolor="#ffffff">
10
+ <Tr>
11
+ <td width="650">
12
+ <table border="0" cellspacing="0" cellpadding="0">
13
+ <Tr>
14
+ <td width="5">
15
+ </td>
16
+ <td width="645" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt;">Preheader text here</td>
17
+ </Tr>
18
+ </table>
19
+ </td>
20
+ </Tr>
21
+ <tr>
22
+ <td height="5"></td>
23
+ </tr>
24
+ <tr>
25
+ <td width="650" height="10" bgcolor="#ffffff"></td>
26
+ </tr>
27
+ <tr>
28
+ <td width="650">
29
+ <table border="0" cellspacing="0" cellpadding="0">
30
+ <Tr>
31
+ <td width="5" bgcolor="#ffffff"></td>
32
+ <td width="229"><a href="%%#storeURL%%"><img src="%%#logoURL%%" alt="LOGO here" height="112" width="229" /></a></td>
33
+ <td width="45" bgcolor="#ffffff"></td>
34
+ <td width="351" bgcolor="#ffffff" align="right" style="font-size:14pt; color:#4A432A;d">Questions or Comments?<br />Call 877-309-7333</td>
35
+ <td width="20" bgcolor="#ffffff"></td>
36
+ </Tr>
37
+ </table>
38
+ </td>
39
+ </tr>
40
+ <tr>
41
+ <td width="650" height="10" bgcolor="#ffffff"></td>
42
+ </tr>
43
+ <tr>
44
+ <td width="650" height="5" bgcolor="#4F472E"></td>
45
+ </tr>
46
+ <tr>
47
+ <td width="650">
48
+ <table border="0" cellspacing="0" cellpadding="0">
49
+ <Tr>
50
+ <td bgcolor="#4F472E" width="135" align="center" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt; color:#ffffff;"><a href="" style="color:#ffffff; text-decoration:none;">Link 1</a></td>
51
+ <td width="1" bgcolor="#746942"></td>
52
+ <td bgcolor="#4F472E" width="115" align="center" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt; color:#ffffff;"><a href="" style="color:#ffffff; text-decoration:none;">Link 2</a></td>
53
+ <td width="1" bgcolor="#746942"></td>
54
+ <td bgcolor="#4F472E" width="150" align="center" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt; color:#ffffff;"><a href="" style="color:#ffffff; text-decoration:none;">Link 3</a></td>
55
+ <td width="1" bgcolor="#746942"></td>
56
+ <td bgcolor="#4F472E" width="125" align="center" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt; color:#ffffff;"><a href="" style="color:#ffffff; text-decoration:none;">Link 4</a></td>
57
+ <td width="1" bgcolor="#746942"></td>
58
+ <td bgcolor="#4F472E" width="121" align="center" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt; color:#ffffff;"><a href="" style="color:#ffffff; text-decoration:none;">Link 5</a></td>
59
+ </Tr>
60
+ </table>
61
+ </td>
62
+ </tr>
63
+ <tr>
64
+ <td width="650" height="5" bgcolor="#4F472E"></td>
65
+ </tr>
66
+ <tr>
67
+ <td width="650" height="10"></td>
68
+ </tr>
69
+ <tr>
70
+ <td width="650">
71
+ <table border="0" cellspacing="0" cellpadding="0">
72
+ <Tr>
73
+ <td width="10"></td>
74
+ <td width="350" valign="top" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt;">
75
+
76
+ Dear %%#customerName%%,<br/><br/>
77
+ We noticed that you left items in your shopping cart recently. If you have any question about them, please feel free to call our Helpful Products Specialists at %%!account_telephone%%.<br/><Br/>
78
+ We'd love to see you back at <a href="%%#storeURL%%">%%#storeName%%</a> - and thanks for shopping with us.
79
+
80
+
81
+ </td>
82
+ <td width="10"></td>
83
+ <td width="1" bgcolor="#4D452B"></td>
84
+ <td width="10"></td>
85
+ <td width="259" valign="top">
86
+ <table border="0" cellspacing="0" cellpadding="0">
87
+ <Tr>
88
+ <td width="259" colspan="3" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt;">
89
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi et nisl ac libero tempor sagittis a ut erat. Morbi urna erat, condimentum nec tempor quis, sollicitudin condimentum mauris.
90
+ </td>
91
+ </Tr>
92
+ <tr>
93
+ <td height="15" colspan="3" width="259"></td>
94
+ </tr>
95
+ <tr>
96
+ <td width="55"></td>
97
+ <td width="149" height="35" align="center" bgcolor="#5A942A" style="font-family:Arial, Helvetica, sans-serif; font-size:12pt; color:#ffffff; font-weight:bold;"><a href="%%#quoteURL%%" style="color:#ffffff; text-decoration:none;">Review My Cart</a></td>
98
+ <td width="55"></td>
99
+ </tr>
100
+ </table>
101
+ </td>
102
+ <td width="10"></td>
103
+ </Tr>
104
+ </table>
105
+ </td>
106
+ </tr>
107
+ <tr>
108
+ <td width="650" height="20"></td>
109
+ </tr>
110
+ <tr>
111
+ <td width="650" height="10">
112
+ <table border="0" cellspacing="0" cellpadding="0">
113
+ <tr>
114
+ <td width="10" height="30" bgcolor="#4F472E"></td>
115
+ <td width="640" bgcolor="#4F472E" style="font-family:Arial, Helvetica, sans-serif; font-size:12pt; font-weight:bold; color:#ffffff;">Shopping Cart</td>
116
+ </tr>
117
+ </table>
118
+ </td>
119
+ </tr>
120
+ <tr>
121
+ <td width="650" height="5"></td>
122
+ </tr>
123
+ <tr>
124
+ <td width="650" height="10">
125
+ <table border="0" cellspacing="0" cellpadding="0">
126
+ <tr>
127
+ <td width="10" ></td>
128
+ <td width="455" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt;">Item</td>
129
+ <td width="65" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt;">Price</td>
130
+ <td width="85" align="center" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt;">Qty</td>
131
+
132
+ </tr>
133
+ </table>
134
+ </td>
135
+ </tr>
136
+ <tr>
137
+ <td width="650" height="8"></td>
138
+ </tr>
139
+ <tr>
140
+ <td width="650" height="1" bgcolor="#4F472E"></td>
141
+ </tr>
142
+ <tr>
143
+ <td width="650" height="10"></td>
144
+ </tr>
145
+ {dynamic_code}
146
+ {loop}
147
+ <tr>
148
+ <td width="650" height="10">
149
+ <table border="0" cellspacing="0" cellpadding="0">
150
+
151
+ <tr>
152
+ <td width="10" ></td>
153
+ <td width="435" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt;">
154
+
155
+ <a href="%%#productUrl_#%%"><img src="%%#productImgUrl_#%%" style="vertical-align:middle;"/></a> &nbsp;&nbsp; <a href="%%#productUrl_#%%">%%#productName_#%%</a>
156
+ </td>
157
+ <td width="10"></td>
158
+ <td width="65" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt;">
159
+
160
+ $%%#productPrice_#%%
161
+
162
+ </td>
163
+ <td width="85" align="center" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt;">
164
+
165
+ %%#productQty_#%%
166
+
167
+ </td>
168
+
169
+ </tr>
170
+
171
+ </table>
172
+ </td>
173
+ </tr>
174
+ {/loop}
175
+ {/dynamic_code}
176
+
177
+ <tr>
178
+ <td width="650" height="20"></td>
179
+ </tr>
180
+ <tr>
181
+ <td width="650" height="1" bgcolor="#4F472E"></td>
182
+ </tr>
183
+ <tr>
184
+ <td width="650" height="20"></td>
185
+ </tr>
186
+ <tr>
187
+ <td width="650">
188
+ <table border="0" cellspacing="0" cellpadding="0">
189
+ <Tr>
190
+ <td width="10"></td>
191
+ <td width="350" valign="top" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt;">
192
+ <table border="0" cellspacing="0" cellpadding="0">
193
+ <tr>
194
+ <td width="350" height="25" style="font-family:Arial, Helvetica, sans-serif; font-size:12pt; font-weight:bold;">May We Also Suggest</td>
195
+ </tr>
196
+ <tr>
197
+ <td height="10"></td>
198
+ </tr>
199
+ <tr>
200
+ <td style="font-family:Arial, Helvetica, sans-serif; font-size:10pt;">
201
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi et nisl ac libero tempor sagittis a ut erat. Morbi urna erat, condimentum nec tempor quis, sollicitudin condimentum mauris.
202
+ </td>
203
+ </tr>
204
+ </table>
205
+ </td>
206
+ <td width="10"></td>
207
+ <td width="1" bgcolor="#4D452B"></td>
208
+ <td width="10"></td>
209
+ <td width="259" valign="top" style="font-family:Arial, Helvetica, sans-serif; font-size:10pt;">
210
+ <table border="0" cellspacing="0" cellpadding="0">
211
+ <tr>
212
+ <td height="60" colspan="3" width="259"></td>
213
+ </tr>
214
+ <Tr>
215
+ <td width="259" colspan="3">
216
+ <table border="0" cellspacing="0" cellpadding="0">
217
+ <Tr>
218
+ <td width="249" align="right" style="font-family:Arial, Helvetica, sans-serif; font-size:12pt; font-weight:bold;">
219
+ Total: <span style="color:#990000;">$%%#subTotal%%</span>
220
+ </td>
221
+ <td width="10"></td>
222
+ </Tr>
223
+ </table>
224
+ </td>
225
+ </Tr>
226
+ <tr>
227
+ <td height="15" colspan="3" width="259"></td>
228
+ </tr>
229
+ <tr>
230
+ <td width="66"></td>
231
+ <td width="183" height="35" align="center" bgcolor="#5A942A" style="font-family:Arial, Helvetica, sans-serif; font-size:12pt; color:#ffffff; font-weight:bold;"><a href="%%#quoteURL%%" style="color:#ffffff; text-decoration:none;">Proceed To Checkout</a></td>
232
+ <td width="10"></td>
233
+ </tr>
234
+ <tr>
235
+ <td height="10" colspan="3" width="259"></td>
236
+ </tr>
237
+ <tr>
238
+ <td colspan="3" width="259" height="1" bgcolor="#4F472E"></td>
239
+ </tr>
240
+ <tr>
241
+ <td height="20" colspan="3" width="259"></td>
242
+ </tr>
243
+ </table>
244
+ </td>
245
+ <td width="10"></td>
246
+ </Tr>
247
+ </table>
248
+ </td>
249
+ </tr>
250
+ <tr>
251
+ <td width="650" height="20"></td>
252
+ </tr>
253
+ <tr>
254
+ <td width="650">
255
+ <table border="0" cellspacing="0" cellpadding="0">
256
+ <tr>
257
+ <td width="209" valign="top"><img src="http://hosting-source.bm23.com/23342/public/item.jpg" height="150" width="209" /></td>
258
+ <td width="11"></td>
259
+ <td width="209" valign="top"><img src="http://hosting-source.bm23.com/23342/public/item.jpg" height="150" width="209" /></td>
260
+ <td width="12"></td>
261
+ <td width="209" valign="top"><img src="http://hosting-source.bm23.com/23342/public/item.jpg" height="150" width="209" /></td>
262
+ </tr>
263
+ </table>
264
+ </td>
265
+ </tr>
266
+ <tr>
267
+ <td width="650" height="20"></td>
268
+ </tr>
269
+ <tr>
270
+ <td width="650" height="35" bgcolor="#4F472E" align="center" style="font-family:Arial, Helvetica, sans-serif; color:#ffffff; font-size:8pt;">
271
+ <br />
272
+ Share this message:<br /><span class="socialshare" xml="lang"><a class="socialshare facebook" href="http://app.bronto.com/public/social/process_share/?fn=SocialShare&amp;socnet=facebook&amp;ssid=8428&amp;tid=%%!tracksent_key%%&amp;title="><img alt="Share this email with your network on facebook" src="http://appstatic.bronto.com/shared/icons/social/tiny_facebook.gif" border="0px" class="socialshare facebook mceItem" /></a><a class="socialshare twitter" href="http://app.bronto.com/public/social/process_share/?fn=SocialShare&amp;socnet=twitter&amp;ssid=8428&amp;tid=%%!tracksent_key%%&amp;title=&amp;summary="><img alt="Share this email with your network on twitter" src="http://appstatic.bronto.com/shared/icons/social/tiny_twitter.gif" border="0px" class="socialshare twitter mceItem" /></a><a class="socialshare digg" href="http://app.bronto.com/public/social/process_share/?fn=SocialShare&amp;socnet=digg&amp;ssid=8428&amp;tid=%%!tracksent_key%%&amp;title=&amp;summary="><img alt="Share this email with your network on digg" src="http://appstatic.bronto.com/shared/icons/social/tiny_digg.gif" border="0px" class="socialshare digg mceItem" /></a><a class="socialshare linkedin" href="http://app.bronto.com/public/social/process_share/?fn=SocialShare&amp;socnet=linkedin&amp;ssid=8428&amp;tid=%%!tracksent_key%%&amp;title=&amp;summary="><img alt="Share this email with your network on LinkedIn" src="http://appstatic.bronto.com/shared/icons/social/tiny_linkedin.gif" border="0px" class="socialshare linkedin mceItem" /></a><a class="socialshare myspace" href="http://app.bronto.com/public/social/process_share/?fn=SocialShare&amp;socnet=myspace&amp;ssid=8428&amp;tid=%%!tracksent_key%%&amp;title=&amp;summary="><img alt="Share this email with your network on MySpace" src="http://appstatic.bronto.com/shared/icons/social/tiny_myspace.gif" border="0px" class="socialshare myspace mceItem" /></a></span><br /><Br />
273
+
274
+ <a href="%%!unsubscribe_url%%" style="font-family:Arial, Helvetica, sans-serif; color:#ffffff; font-size:8pt;">Unsubscribe</a> | <a href="%%!manage_url%%" style="color:#ffffff; font-size:8pt;">Manage Preferences</a> | <a href="%%!forward_url%%" style="color:#ffffff; font-size:8pt;">Forward to a Friend</a><Br />%%!account_address%%<br /><br />
275
+ </td>
276
+ </tr>
277
+ </table>
278
+ </body>
279
+ </html>
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Bronto_Extension</name>
4
- <version>2.0.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">OSL</license>
7
  <channel>community</channel>
@@ -43,9 +43,9 @@
43
  &lt;p&gt;For installation and configuration instructions, as well as a full list of new features and known issues, please review the Implementation Guide at &lt;a href="http://a.bron.to/magento"&gt;http://a.bron.to/magento&lt;/a&gt;.&#xD;
44
  </notes>
45
  <authors><author><name>Dave Johnson</name><user>BrontoSoftware</user><email>dave.johnson@bronto.com</email></author></authors>
46
- <date>2013-01-27</date>
47
- <time>14:42:01</time>
48
- <contents><target name="magecommunity"><dir name="."><file name="Bronto" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir></target><target name="mageetc"><dir name="modules"><file name="Bronto_All.xml" hash="5a9c06b6313882589765b9bcf0402bbb"/><file name="Bronto_ConflictChecker.xml" hash="1a7dc00b830ca2cc696e67d94b85be5d"/><file name="Bronto_Customer.xml" hash="a11c20f008ee2eae14baa3b549d5adee"/><file name="Bronto_Email.xml" hash="b7cdca4b15753edcefe8b9e0abb780bd"/><file name="Bronto_Newsletter.xml" hash="2115c5225e02ab5d4e56749cc5eff6ad"/><file name="Bronto_Order.xml" hash="63f1537add6088417945657bec98ffe9"/><file name="Bronto_PermissionChecker.xml" hash="55ff239c291529be2dc05799102d24a1"/><file name="Bronto_Reminder.xml" hash="08503ab78994178b822ef9b0add243f9"/><file name="Bronto_Roundtrip.xml" hash="bd2b89f3254e995904da92f025b6321c"/></dir></target><target name="magelib"><dir name="Bronto"><dir name="Api"><dir name="Account"><file name="Exception.php" hash="6048e32e08bac337f37e22918ae92e6a"/><file name="Row.php" hash="de3cb2496c217c25e850573c4d5b2dc2"/></dir><file name="Account.php" hash="30d5ef4bb101748553e239ffe2481183"/><dir name="Activity"><file name="Exception.php" hash="39ac264e8429c000372e849327372471"/><file name="Row.php" hash="b5612081f50d117a7c66f93f9b90382a"/></dir><file name="Activity.php" hash="35aaf580eb62df39b631041937c10187"/><dir name="ApiToken"><file name="Exception.php" hash="ff31b1be1c06581a115aabb7a782d9b5"/><file name="Row.php" hash="1716b6859c05b82301cf28bc7dcca4be"/></dir><file name="ApiToken.php" hash="20ecd2591d6634c42de7b05879c4bc04"/><dir name="Contact"><file name="Exception.php" hash="232fece284740b8e49a5d22ba3082b32"/><file name="Row.php" hash="a85937ee83f1a852372782a8dc1d2eab"/></dir><file name="Contact.php" hash="0413b22277d97b9d9f910281c14a6cea"/><dir name="Conversion"><file name="Exception.php" hash="edaba96e7118b8ce27220ffdabf56721"/><file name="Row.php" hash="495064d7f358f568c0c93b291a267b33"/></dir><file name="Conversion.php" hash="17d45962719271cdc834660cc3478071"/><dir name="Delivery"><file name="Exception.php" hash="c9c746a033ef90ac5e7c70e906331779"/><file name="Recipient.php" hash="9756477b2cbde59ece2b3720c02a5d75"/><file name="Row.php" hash="ca0880566674966a7aa9dee7c4c2c6eb"/></dir><file name="Delivery.php" hash="1866bf3ae809010f630deead7c76a09e"/><dir name="DeliveryGroup"><file name="Exception.php" hash="6ae170c14038a49413580a19ce7ee144"/><file name="Row.php" hash="d5046f7a5dbf39442730f45d17aeaf87"/></dir><file name="DeliveryGroup.php" hash="0e4572ad563c61dd78229af2b6d35cad"/><file name="Exception.php" hash="0df72a2002acff46885dd3978ea95678"/><dir name="Field"><file name="Exception.php" hash="3f900dcdbf5b8b321e48fa6d4a4a5ae1"/><file name="Predefined.php" hash="e876d133b211c4d66ad70ccba7bdff04"/><file name="Row.php" hash="d0c4001b14954dc45e35c8bf8e89cb65"/><file name="TypeGuesser.php" hash="d74ed1da1bd21c93ec68e753edee745f"/></dir><file name="Field.php" hash="4d42365676ef739f72ab50b09595bfa0"/><dir name="List"><file name="Exception.php" hash="ba39e47457265a2042dfaaf0b1c93d70"/><file name="Row.php" hash="bc8f0c84d486f1a41b113529e0da4cc4"/></dir><file name="List.php" hash="589a011d54b9cd6e2400f42fb0391967"/><dir name="Login"><file name="ContactInformation.php" hash="871630e7a0762cb4055183fe9b52b8ea"/><file name="Exception.php" hash="37a401b1206264c7865c62c1c62d394c"/><file name="Row.php" hash="3bfc793c2defa6f538c4b8749dbac22a"/></dir><file name="Login.php" hash="57afd59cd524e57e5a2bdb839a6207e4"/><dir name="Message"><file name="Exception.php" hash="3688ca7320fa9b0a5a3bba80ac4ed072"/><file name="Row.php" hash="ed93a1f123c65324b05e1d2c7b8b4b12"/></dir><file name="Message.php" hash="993e0bfd24d5663078735cbeae9a4b23"/><dir name="MessageRule"><file name="Exception.php" hash="500de77f33962484a640c24521f63659"/><file name="Row.php" hash="5a16b597def2515423e58ab36d17ff01"/></dir><file name="MessageRule.php" hash="bd30a4aa770714ac17b1b33da363aa60"/><file name="Object.php" hash="9681a0940cf96835f2d14b876cce0a4e"/><dir name="Order"><file name="Exception.php" hash="843fd9b527ad8be267664e59e803a2d8"/><file name="Product.php" hash="446161d2fe36cfd849f72066bda8c2ff"/><file name="Row.php" hash="470b921a06f832a0cad81c869038b26e"/></dir><file name="Order.php" hash="9a27755d756a06b82a0cc0d97c315519"/><dir name="Row"><file name="Exception.php" hash="2a48372f5f71cbaad940bc0a62327cff"/></dir><file name="Row.php" hash="459df27d460fd4c3923e860bc8a76a78"/><dir name="Rowset"><file name="Exception.php" hash="5b109a1eef32d14cbc66016fdf65ad9c"/><file name="Iterator.php" hash="0797f8c5a95d47a521ac333e853e6cd3"/></dir><file name="Rowset.php" hash="a10029ba58512887eb7aeb8e40a96a33"/><dir name="Segment"><file name="Exception.php" hash="c0fb3c3a1ed79177f5247abe40adf504"/><file name="Row.php" hash="5211fe7639821a8e413f7832d33dca3c"/></dir><file name="Segment.php" hash="67cf81752cd21a42ad7b6b2ab713c9eb"/></dir><file name="Api.php" hash="2f4d300d9921f4b46faf7d78e34466d9"/><file name="SoapClient.php" hash="f07d2c4551825a1018ddfbd997d660d8"/><dir name="Util"><file name="Colors.php" hash="9bc5a4ce486972d493c82fcb671b416c"/><file name="CountryCodes.php" hash="c666d446d3a156fb2881bf33f2acfc80"/><dir name="Retryer"><file name="FileRetryer.php" hash="6ce89108476048a6e45a7457f53272de"/><file name="RetryerException.php" hash="65ab6cc1f4e71fad55832657f700c653"/><file name="RetryerInterface.php" hash="29aab11684d6eb27439281cd9f6cee76"/></dir><file name="Uuid.php" hash="00f349c1dc57463ebf13639a6bbff6fd"/></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="base"><dir name="default"><dir name="bronto"><file name="cron.css" hash="c7260d3aa14b5945ee76c72dbd914efa"/><dir name="images"><file name="bg_notifications.gif" hash="df73b8aa7e48bb56e0a644245aa3683f"/><file name="logo.jpg" hash="3c6059218195679d99dbb874bdabbd07"/><file name="message_approved.gif" hash="465a056a3ba3d94367f51c3c0b751391"/><file name="message_not_approved.gif" hash="e4f28607f075a105e53fa3113d84bd26"/></dir></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="bronto"><dir name="newsletter"><file name="js.phtml" hash="1b36b8d1f438d5970b4ab0e8f97246d7"/></dir></dir></dir><dir name="layout"><dir name="bronto"><file name="newsletter.xml" hash="b7d4c9b1fb4fabb4255c6df64e98d332"/></dir></dir></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><dir name="template"><dir name="email"><file name="bronto" hash="d41d8cd98f00b204e9800998ecf8427e"/></dir></dir></dir></target></contents>
49
  <compatible/>
50
  <dependencies><required><php><min>5.3.0</min><max>5.5.0</max></php><extension><name>soap</name><min></min><max></max></extension><extension><name>openssl</name><min></min><max></max></extension></required></dependencies>
51
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Bronto_Extension</name>
4
+ <version>2.0.0.1</version>
5
  <stability>stable</stability>
6
  <license uri="http://opensource.org/licenses/osl-3.0.php">OSL</license>
7
  <channel>community</channel>
43
  &lt;p&gt;For installation and configuration instructions, as well as a full list of new features and known issues, please review the Implementation Guide at &lt;a href="http://a.bron.to/magento"&gt;http://a.bron.to/magento&lt;/a&gt;.&#xD;
44
  </notes>
45
  <authors><author><name>Dave Johnson</name><user>BrontoSoftware</user><email>dave.johnson@bronto.com</email></author></authors>
46
+ <date>2013-01-30</date>
47
+ <time>15:38:26</time>
48
+ <contents><target name="magecommunity"><dir name="Bronto"><dir name="Common"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><file name="About.php" hash="f4be0821dadfb40b0dbcfd4bc4ee5f32"/><file name="Cron.php" hash="b1c18891073fa233cd5e44f16c60ec97"/><dir name="Form"><dir name="Field"><file name="Apitoken.php" hash="6f3121e8a5ee54c58993654018048b9e"/><file name="Hidden.php" hash="18a13153df6dd084840086105f8117cc"/><file name="List.php" hash="48f36e9d06e6bc759e36ebb1128aa513"/></dir><file name="Field.php" hash="bfc0b65b927934ba54bb5225c0fb9247"/></dir></dir></dir></dir></dir><dir name="Helper"><file name="Contact.php" hash="aa0f86b84c97399bdf259935de33dca0"/><file name="Data.php" hash="42a3e392c17c1bae812ebfc4e9d19ccb"/><file name="DataInterface.php" hash="a6700f3a4a79f6d6468df24f714427a9"/><file name="Field.php" hash="683839cfcd4fd5cd81b0393fc67b019c"/><file name="Message.php" hash="22d6224ab354a6ed7dc13d1e6e0a2fc5"/><file name="Product.php" hash="64202787e5f0c63a38efff387ab3c325"/></dir><dir name="Model"><file name="Api.php" hash="3716948a5e50e621625714a1e3a93263"/><dir name="Email"><dir name="Message"><file name="Filter.php" hash="4668bb03abbb5029980765c0b712fd5c"/><file name="Templatefilter.php" hash="783dcbb689021665f2b7f34f83bb99c2"/></dir><file name="Message.php" hash="17086fba16eed6986c0ab1fafbeffbd6"/></dir><file name="Keysentry.php" hash="a28e79f0ddd83f662931e67638990f51"/><file name="Observer.php" hash="73b02a94aba279c05dd7753ac10fdb75"/><dir name="Resource"><file name="Setup.php" hash="780f5c070cbd9da2f003372ee90a0891"/></dir><dir name="System"><dir name="Config"><dir name="Backend"><file name="Cron.php" hash="b05e28fb0cc0db0377eee68ffc712c10"/><file name="Token.php" hash="03a0cf45efe77307e06afa3b4a98b214"/></dir><dir name="Source"><dir name="Contact"><file name="Status.php" hash="1bf6c053f8132a36dd6882e0f1faf45f"/></dir><dir name="Cron"><file name="Frequency.php" hash="c6689871a7a8add3dc4b84e4a2ff6f10"/><file name="Minutes.php" hash="be3e3066819785b55a25f22c5bc9392a"/></dir><file name="Field.php" hash="875707da33979b4717ea05bb75959b0d"/><file name="List.php" hash="69497100fe9f036c442b9d94133c8f4a"/><file name="Message.php" hash="4fb4e4f9deaabe4971bfcdf3e12b0da4"/></dir></dir></dir></dir><dir name="Test"><dir name="Config"><file name="Config.php" hash="02b55ba2804a024740506c4df0ebdd42"/></dir><dir name="Model"><file name="Checkout.php" hash="9716ab2c76558e463f1a105308973b74"/><dir name="Keysentry"><dir name="fixtures"><file name="seed.yaml" hash="3a9b13b2ef5a72bea298be72edba821d"/></dir></dir><file name="Keysentry.php" hash="21a68afb98418e416d934d356951f246"/></dir></dir><dir name="controllers"><file name="LogController.php" hash="d97e8dc3624053d563389b8b19c71c06"/></dir><dir name="etc"><file name="adminhtml.xml" hash="f5792bf262cf83cc193d23c09a17a03f"/><file name="config.xml" hash="648b43b9d5bfad8dc117153216d928ad"/><file name="system.xml" hash="f681ef11d508da77376180b05d5b0296"/></dir><dir name="sql"><dir name="bronto_common_setup"><file name="mysql4-install-1.7.0.php" hash="c8459d26fdfea2fb9430e8829b3257e1"/></dir></dir></dir><dir name="ConflictChecker"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><file name="About.php" hash="9049055c03e261b2452c926d801196a6"/><file name="Conflictchecker.php" hash="c00f929ef55e95597761871674077b10"/></dir></dir></dir><file name="Printer.php" hash="cd8ef4c01028da3d690ce6f5c53d1f61"/></dir><dir name="Helper"><file name="Data.php" hash="0f5c562370c77b6cfe9579dc7fe396d0"/></dir><dir name="Model"><dir name="Config"><file name="Blocks.php" hash="78eb63947ae94be2b1dc9ee42de52152"/><file name="Checker.php" hash="a1a38b9c4a518e0be2e4ea84adab0107"/><file name="ConfigAbstract.php" hash="8bc2be8485543a17338cb953d760c71c"/><file name="ConfigInterface.php" hash="86a788c1b1971828c8f947b42f03baea"/><file name="Datastore.php" hash="d2b37735fe127d831e6055e05b232fb8"/><file name="Helpers.php" hash="3de600b842bf90c53417843e9b4c1946"/><file name="Models.php" hash="0358f506ff4e5820b61b076701f0746d"/><file name="Printer.php" hash="6d2aec31a623b943d3d982c97999be13"/><file name="Resources.php" hash="9f12487e864cd4005c53b72fe02e4cf4"/></dir><dir name="Core"><dir name="Config"><file name="Base.php" hash="b1ecb5cd90e050d1c825beb65e6d888e"/><file name="Element.php" hash="2efb1a1c022cb393ab5718c1f7eafd1f"/></dir><file name="Config.php" hash="29408203a0aa8b7afa84ba16b1416f91"/></dir><dir name="Lib"><dir name="Varien"><dir name="Simplexml"><file name="Config.php" hash="3acbdd7d7c9fa6c346688e5083569596"/><file name="Element.php" hash="f5961e7a41035851cabf7fcd8022a13a"/></dir></dir></dir><dir name="Mysql4"><dir name="Core"><file name="Config.php" hash="36685bb89b45c71cfc447727ce66ea9a"/></dir></dir><dir name="Path"><dir name="Locator"><file name="Array.php" hash="f82c5966dab92ed91a9441a0231e7ace"/><file name="Factory.php" hash="bea2e4a6bea17815a9040341209f4256"/><file name="IteratorAbstract.php" hash="9adccb7c853d80e8d64a0eb8346f3cbc"/><file name="LocatorInterface.php" hash="b3cf0d528296ee0e87e7898da44baa47"/><file name="Stack.php" hash="4524078604b43dffcf57c7a23959ef03"/></dir></dir><dir name="Resource"><dir name="Core"><file name="Config.php" hash="6b69bd1c0ce0e4c92c1c96436f79e83d"/></dir></dir></dir><dir name="Test"><dir name="Config"><file name="Config.php" hash="23de17a20f7a5588bb9761a2d3eb79ae"/></dir><dir name="Model"><dir name="Path"><dir name="Locator"><file name="Array.php" hash="e219f193e027d5c9a5d9cb9d7a27a6ac"/><file name="Factory.php" hash="36ffe1ec656f3f3ba1f99dd743e52c0b"/><file name="Stack.php" hash="29cbf00cd66bc61ee16c740847d9f400"/></dir></dir></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="9d5cab56f52b0d12688c5787e3bfa03f"/><file name="config.xml" hash="0497e6c9bf942db62d01e0595437166b"/><file name="system.xml" hash="6d6b10860c55f815efe815d7ee0c2290"/></dir></dir><dir name="Customer"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><file name="About.php" hash="5874d9bf1ff106212a348815104c5244"/><file name="Cron.php" hash="0af7552b1b21d706adc5249acf466fc8"/><dir name="Form"><dir name="Fieldset"><dir name="Attributes"><file name="Address.php" hash="4e07b4f417c57d291669d7380ec83c19"/><file name="Customer.php" hash="c4cae63b2f176689a42aef673e437df4"/></dir><file name="Attributes.php" hash="fd77169977b903ecbd179723c9bad5dd"/></dir></dir></dir></dir><dir name="Widget"><dir name="Button"><file name="Reset.php" hash="74d38897533f7b4e67d476dd791a38ee"/><file name="Run.php" hash="e707627c781ea4323d1924fa33094320"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="60e9424dbf9f2e7d7b1e494f1fa8f794"/></dir><dir name="Model"><dir name="Customer"><file name="Observer.php" hash="887c118c435ca41324444a7583ec9f0b"/></dir><file name="Observer.php" hash="3f78e716b0615abeab84d95c8b9c6111"/><dir name="Resource"><dir name="Customer"><file name="Collection.php" hash="5b9489d7293bce6589a84973dca8d5f3"/></dir><file name="Setup.php" hash="6e988a951049e5b0e0e7ed214e84f277"/></dir><dir name="System"><dir name="Config"><dir name="Backend"><file name="Cron.php" hash="dbcd55d41447d46fded27dfa2e6febb0"/><file name="Newfield.php" hash="1862d6819c9b4f04aa07359099404eb6"/></dir></dir></dir></dir><dir name="Test"><dir name="Config"><file name="Config.php" hash="1610a3a3256fc0d1b277bb2d82431ae0"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="CustomerController.php" hash="d25faab3ee92f4af43347d7924239592"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="6cc229b440b34da710887aaf96bbcf81"/><file name="config.xml" hash="2be4f9a2678307c9e06063dd25a5ede9"/><file name="system.xml" hash="4ea888d7af3d269937ac8358e8c862ff"/></dir><dir name="sql"><dir name="bronto_customer_setup"><file name="mysql4-install-1.0.0.php" hash="871c225318588b2804a05751bce45e1f"/></dir></dir></dir><dir name="Email"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><file name="About.php" hash="10cb51420b205c100ef46cf59edef05b"/></dir><dir name="Email"><dir name="Log"><dir name="Grid"><dir name="Renderer"><file name="Customer.php" hash="c2530287b293e05508816049586ef5c2"/><file name="Fields.php" hash="6c5d921b6c636329f035381af4c7f028"/></dir></dir><file name="Grid.php" hash="b54cada4029aa45290679e6cf69f8c47"/></dir><file name="Log.php" hash="3fa0b873d262b3d5c6161c1aef33e6ae"/><dir name="Template"><dir name="Edit"><file name="Form.php" hash="804a3fc8d0e773639f8eb2fe3df1ab1f"/></dir><file name="Edit.php" hash="bcc5b9ba9bee92a3e8f33684dd02506f"/><dir name="Grid"><dir name="Renderer"><file name="Message.php" hash="bf56f19c9f4310609fbb9a788768e222"/></dir></dir><file name="Grid.php" hash="6a253035cf2db239f93b73667e92ee63"/></dir><file name="Template.php" hash="b33503babba2480ca840569629dfbb07"/></dir></dir></dir></dir><dir name="Helper"><file name="Contact.php" hash="712033409f93712e4a22cf89252d44e4"/><file name="Data.php" hash="e582e103dfe73cb4ab9e6eb675f81309"/><file name="Field.php" hash="e4714e9cc95bdfe4da9a16feb604f44c"/><file name="Message.php" hash="f328dcee7934ddc48d6f4d40afff74cc"/></dir><dir name="Model"><dir name="Email"><file name="Message.php" hash="5d2c4b3ac3120352f8424863ad176dc6"/></dir><file name="Log.php" hash="2740d9cd5073106f58880e57e84ce8ee"/><dir name="Mysql4"><dir name="Log"><file name="Collection.php" hash="6de4819537636d3ea7816cb7c6fc250c"/></dir><file name="Log.php" hash="15ffb2c83281c77b5d427ff29abac776"/></dir><file name="Observer.php" hash="0b67950706c21220a4712bc0c279ba00"/><dir name="System"><dir name="Config"><dir name="Source"><dir name="Email"><file name="Template.php" hash="ba80e6553c61e731b85c027cd688ca8f"/></dir></dir></dir></dir><dir name="Template"><file name="Import.php" hash="b808d3e5a70dc30e09448b20dd000708"/></dir></dir><dir name="Test"><dir name="Config"><file name="Config.php" hash="8a74889c3f24c3053baefca6e7d7eddb"/></dir><dir name="Model"><dir name="Email"><file name="Message.php" hash="5ac860c2519eb9719ce318c5f60e88f8"/></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><dir name="System"><dir name="Email"><file name="LogController.php" hash="386560ba30da12796614db1d0381bb7c"/><file name="TemplateController.php" hash="578112502761e70000ff10ca67502034"/></dir></dir></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="35a2ffa5e273f87b6d2de172cea4a219"/><file name="config.xml" hash="37e21ee9d0458bd28379446f063457a5"/><file name="system.xml" hash="2e6f8375e4794780c2f49f68536d2c6b"/></dir><dir name="sql"><dir name="bronto_email_setup"><file name="mysql4-install-1.0.0.php" hash="516265312ede986c1a35a19b9e5bbfea"/><file name="mysql4-install-1.0.2.php" hash="327ac219e947d608fbf9d3209dd03bab"/><file name="mysql4-install-1.0.5.php" hash="327ac219e947d608fbf9d3209dd03bab"/><file name="mysql4-install-1.0.8.php" hash="b572625c1380dfffe3b089275ac1dc7e"/><file name="mysql4-install-1.1.2.php" hash="bf80f7b12eccdad2e0e36a564e18530c"/><file name="mysql4-upgrade-1.0.0-1.0.2.php" hash="1f797c3f909d72219ef5d00017b10554"/><file name="mysql4-upgrade-1.0.2-1.0.5.php" hash="f2c83b65500d9df0fd10c2e6721f2bfe"/><file name="mysql4-upgrade-1.0.5-1.0.8.php" hash="cdbda7aa084e51b9b222c56e548462a6"/><file name="mysql4-upgrade-1.0.8-1.1.1.php" hash="f2c83b65500d9df0fd10c2e6721f2bfe"/><file name="mysql4-upgrade-1.1.1-1.1.2.php" hash="0538afef03b1e21d509593e2ad275c34"/></dir></dir></dir><dir name="Newsletter"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><file name="About.php" hash="bc44a52305e7cbe3a41c5f19e6257ede"/><file name="Cron.php" hash="1b4aca8bcab75685754a441e4dd77b04"/></dir></dir><dir name="Widget"><dir name="Button"><file name="Run.php" hash="4d23a9eba8aab13d9fc71ed369e42e4e"/></dir></dir></dir><dir name="Checkout"><dir name="Onepage"><file name="Newsletter.php" hash="e0ba7884794f68fe3c299946ef8e63a4"/></dir></dir></dir><dir name="Helper"><file name="Contact.php" hash="85dffba4f8edd375e53ca59f7a4bf1a0"/><file name="Data.php" hash="62e5be8e1326862fee10774654daad15"/></dir><dir name="Model"><dir name="Mysql4"><dir name="Queue"><file name="Collection.php" hash="de63f9f3b73cf040d16b1eb971d499a5"/></dir><file name="Queue.php" hash="f5a1e0ee4f7901fc555313d9828761c5"/></dir><file name="Observer.php" hash="8318825696a7020c88cec0b459843c5f"/><file name="Queue.php" hash="e7bf4ff44b4033257ae7892f1966e20d"/></dir><dir name="Test"><dir name="Config"><file name="Config.php" hash="c749aea6f1147d0b164de83c7eb0d8d1"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="NewsletterController.php" hash="18972c972f84cf8d267bfead4ffc1b7d"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="253518e92554bf89fabe7b832a7a562c"/><file name="config.xml" hash="5f292e14c0f89d901ed94de2351ca978"/><file name="system.xml" hash="b1cfe14bf4b8c5c4097790996bddd2f0"/></dir><dir name="sql"><dir name="bronto_newsletter_setup"><file name="mysql4-install-1.0.0.php" hash="49beafe0e59744cfe7dd1297da7c5975"/><file name="mysql4-install-1.4.0.php" hash="fa8797dee2ef1096292aefb983487eb2"/><file name="mysql4-upgrade-1.4.0-1.4.1.php" hash="bd58648cbf4a65e300ef386db3f51de5"/></dir></dir></dir><dir name="Order"><dir name="Block"><dir name="Adminhtml"><dir name="Sales"><dir name="Order"><dir name="View"><dir name="Tab"><file name="Info.php" hash="7ba16c9e796b59a179ae8af230ccf33e"/></dir></dir></dir></dir><dir name="System"><dir name="Config"><file name="About.php" hash="126e3166dace48941fccbe2bb4c80264"/><file name="Cron.php" hash="ce303baf533f78ce71680602cae07e94"/></dir></dir><dir name="Widget"><dir name="Button"><file name="Reset.php" hash="9bfbc1f1ffb38389a3a47ca009a24a35"/><file name="Run.php" hash="5b833a216bea22b962f633e33f6a86b8"/></dir></dir></dir><file name="Bta.php" hash="10f7f6f5e5e701dafefe8034095ae11e"/></dir><dir name="Helper"><file name="Data.php" hash="87f5a3a40ce32e8fcb2588ef7971c38d"/></dir><dir name="Model"><file name="Observer.php" hash="ef95f78e32c6097f97c8fe34ef951755"/><dir name="Order"><file name="Observer.php" hash="6cd2eab4b2f3535ad51125207f51a329"/></dir><dir name="Quote"><file name="Observer.php" hash="e3edc38e2c4a29c67a65348d1998bded"/></dir><dir name="Resource"><dir name="Order"><file name="Collection.php" hash="115c9b1e668b6c832b158cbce3544254"/></dir><file name="Setup.php" hash="6ad289c714abf1cf9caba38014998838"/></dir><dir name="System"><dir name="Config"><dir name="Backend"><file name="Cron.php" hash="96199a296f15518a89fde9384cf5fb0d"/></dir><dir name="Source"><file name="Description.php" hash="67364bc17dc197e4dd2a6e0382c75722"/><file name="Limit.php" hash="789f0e42eaafa65b4970ad107206102c"/></dir></dir></dir></dir><dir name="Test"><dir name="Config"><file name="Config.php" hash="34bc93c0aab6b4898e3637d2307cab3f"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="OrderController.php" hash="c1873347a5d6046ed593d52a74d307e2"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="0c4a0a1117117613d148157557f2abb3"/><file name="config.xml" hash="00072f04579c82955d6215dde944659d"/><file name="system.xml" hash="131d320296a91ef24c43dcb60c01ec8e"/></dir><dir name="sql"><dir name="bronto_order_setup"><file name="mysql4-install-1.0.0.php" hash="81b57488dbc44047db4099c41fdac54e"/></dir></dir></dir><dir name="PermissionChecker"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><file name="About.php" hash="5c0990417244c38485b5c9eda45fa80a"/><file name="Permissionchecker.php" hash="9cabf571a4dab49fa26d8ff1b35b0646"/></dir></dir></dir><file name="Printer.php" hash="7f9d480227c8211aa9e2db66ecd34f3f"/></dir><dir name="Helper"><file name="Data.php" hash="4fab093494eb9a793583e2294d2a2489"/></dir><dir name="Model"><dir name="Validator"><file name="Checker.php" hash="2a8259840b7f0e75b52bdcc93adb8922"/><file name="Directory.php" hash="89a0981e5ed7b70446054d9e8f31300e"/><file name="File.php" hash="539342c217889f7fd0f19f3b731bea23"/><dir name="Filter"><file name="PatternIterator.php" hash="9bdc50cda8d18e3335d8fc07fa72f733"/></dir><file name="Group.php" hash="8dc26a97c43fa2bbe58264b3117324a9"/><file name="Owner.php" hash="fc20d838f28c3406d74475fd4dbf33f0"/><file name="Printer.php" hash="e49b843f43f835d35ba838a2b8c7d00d"/><file name="ValidatorAbstract.php" hash="bccd4db6601922c5a632680c226e03c6"/><file name="ValidatorInterface.php" hash="877e881c030573fdbcd344174eceec8a"/></dir></dir><dir name="Test"><dir name="Config"><file name="Config.php" hash="672ed6161380fbf88a516377e62031be"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="058c7be44feea32fc5bc646a5632b4f3"/><file name="config.xml" hash="c4df9b0d873371a626029bd25cfe1c41"/><file name="system.xml" hash="4bb28ac8646a04f6ea857f79cd75475e"/></dir></dir><dir name="Reminder"><dir name="Block"><dir name="Adminhtml"><dir name="Promo"><file name="Notice.php" hash="d5991ebe75066fa76f23eb9464619f08"/></dir><dir name="Reminder"><dir name="Edit"><file name="Form.php" hash="779f8effae92303da303c889db9cef65"/><dir name="Tab"><file name="Bronto.php" hash="a4f19c14cddab68e1180723984f10ccb"/><file name="Conditions.php" hash="f3ad1c6438079bf43183825b52fde3f3"/><file name="Customers.php" hash="668c91478d859d2aa1eb6027d2bbef75"/><file name="General.php" hash="8c7ff650f320b57a208ecf825142e877"/></dir><file name="Tabs.php" hash="accefd148ad3cf28d36e890c138078f2"/></dir><file name="Edit.php" hash="a05e23f5249c97ac7965ecf27672d1a6"/><file name="Grid.php" hash="ebbe203d00c8e21ca591b55c48572cdb"/></dir><file name="Reminder.php" hash="82d616907ffc84eed0aa688f218ed7f1"/><dir name="System"><dir name="Config"><file name="About.php" hash="ce52e60802d1b9d251cef6a7c34564ce"/><file name="Cron.php" hash="ba8f69a491407b48ec72eb7351249c98"/></dir></dir><dir name="Widget"><dir name="Grid"><dir name="Column"><dir name="Renderer"><file name="Email.php" hash="5d9cbf69ea3bfcbc0f96d9a3dd8f613a"/><file name="Id.php" hash="e221f8f87969c1299a7daf3796dd7bbf"/></dir></dir></dir></dir></dir></dir><dir name="Helper"><file name="Contact.php" hash="a46c741761b5440eda28c9a8ac2df080"/><file name="Data.php" hash="36eff50aafd65ca66f13aa15c5e65beb"/><file name="Message.php" hash="a02936281f98cd990ecd17c32bfada46"/></dir><dir name="Model"><dir name="Condition"><file name="Abstract.php" hash="92b5e50a4e9b39dff50d83f1099db882"/><dir name="Combine"><file name="Abstract.php" hash="ea03be5f19662b5392147b64c1049e2c"/></dir></dir><dir name="Email"><file name="Message.php" hash="fe2f318ef70bd0d7be3de34b77b5ef2d"/></dir><file name="Guest.php" hash="4e220c343693ca30560294f8e4cfc9be"/><dir name="Mysql4"><dir name="Customer"><file name="Collection.php" hash="4fc63d20f3f7a92770dcaebf17bba84e"/></dir><dir name="Guest"><file name="Collection.php" hash="9002af1ece49d28124724db5dd112119"/></dir><file name="Guest.php" hash="e8b815dce460b039053ef224628ad676"/><dir name="Rule"><file name="Collection.php" hash="2969bb11fa9e83523da7b41d834381b4"/></dir><file name="Rule.php" hash="38a1ac22b504900fe3b0d11426c3f7cf"/></dir><file name="Observer.php" hash="fc4471bd9b2aaaaa8eb689b591cce43f"/><dir name="Rule"><dir name="Condition"><dir name="Cart"><file name="Amount.php" hash="8b2a76a43ebe3735556757db407e3409"/><file name="Attributes.php" hash="6bc41aca8c8a7846fae4f894306ffa45"/><file name="Combine.php" hash="add54bf57284e6c48008db605e0df3d4"/><file name="Couponcode.php" hash="f0144e4e5bbf157e2268e3765b46dd24"/><file name="Itemsquantity.php" hash="6c605a49ebe9582f5b57e24085079a6b"/><file name="Sku.php" hash="090610f405b398600e00d33325ec12c4"/><file name="Storeview.php" hash="00262bc083ef7297989056cdf768274e"/><file name="Subcombine.php" hash="b10d46333d76a881654cc6d2a67e6880"/><file name="Subselection.php" hash="8873aa2845c638d6a7658652eec40f0e"/><file name="Totalquantity.php" hash="5edc528cbd0688746a01157595720076"/><file name="Virtual.php" hash="f65e64572c526c6c50e38d1bb9d9a52f"/></dir><file name="Cart.php" hash="399ea955cdabbaf90155b6a929435a50"/><dir name="Combine"><file name="Root.php" hash="4d020e164faa06fb94c01bc2f7c110b4"/></dir><file name="Combine.php" hash="74f9ec5b8560dabad1e303af18f4cff9"/><dir name="Wishlist"><file name="Attributes.php" hash="bb8205a2b00b58f2a092887db5ef8b63"/><file name="Combine.php" hash="b17a452ea9c090bea3cd1b2529171394"/><file name="Quantity.php" hash="6d228a7fbefd393924d9301c16c8e4b2"/><file name="Sharing.php" hash="9b1d05f4062a8bcda277be627a390c1d"/><file name="Storeview.php" hash="5edfdacb3d69379a4a144df29994ae97"/><file name="Subcombine.php" hash="a063b405ed07c454b5dd0b1d71af430f"/><file name="Subselection.php" hash="4640a52371cdb38c3eee73bd8b215b48"/></dir><file name="Wishlist.php" hash="3e19189f6a045df483635abfdd723304"/></dir></dir><file name="Rule.php" hash="ca40e5d9007458d4d1291ee5c96688d0"/><dir name="System"><dir name="Config"><dir name="Backend"><file name="Cron.php" hash="3c9c134aee05b3b32fc64a549a3e7cb3"/></dir></dir></dir></dir><dir name="Test"><dir name="Config"><file name="Config.php" hash="1a522335b3e13dd06b4a74576a4ae948"/></dir><dir name="Helper"><file name="Contact.php" hash="e348af94ff0f5444e766fc17f3e6c774"/><file name="Data.php" hash="1b8a488f5aa2892bc39a2a3ad6ffd1d8"/><file name="Message.php" hash="4f4cc99f871c3da8ad0c1a35b7ec04df"/></dir><dir name="Model"><file name="Observer.php" hash="e3c696a95e00821b4ce5a7d331c0aae8"/><file name="Rule.php" hash="aba91c2be53965dbbd45246990c63d55"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="RemindersController.php" hash="f6854e9616c94294236f0aa3f8d91424"/></dir><file name="LoadController.php" hash="563a01392d2df74bd929d9d9e6de5060"/></dir><dir name="etc"><file name="adminhtml.xml" hash="772c6847e1961a7a56fdbcfbce6aaf91"/><file name="config.xml" hash="2607d22509ac28b656efcbfe18188518"/><file name="system.xml" hash="e772ad2e0cf1790c397fcb035eb5f0dd"/></dir><dir name="sql"><dir name="bronto_reminder_setup"><file name="mysql4-install-1.4.2.php" hash="1372af1369e9608159f5b59af75f367e"/><file name="mysql4-upgrade-1.4.0-1.4.2.php" hash="fefa638ca0ed7c5bc80a1b67e27c8703"/><file name="mysql4-upgrade-1.4.10-1.4.11.php" hash="130a688eb03e4f476308d0d11c32141a"/><file name="mysql4-upgrade-1.4.2-1.4.9.php" hash="4692060e7c938aea129c53619f0b3c19"/><file name="mysql4-upgrade-1.4.9-1.4.10.php" hash="9698883135211d54a3c711fead02c187"/></dir><dir name="reference"><file name="saveMatchedCustomers.sql" hash="c4f32ee8be31f7a652369c148271a6c7"/></dir></dir></dir><dir name="Roundtrip"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><file name="About.php" hash="6adab60e3a5a4668fdf5da8d8d33a024"/><file name="Status.php" hash="c623240112f1f15200f918394f736720"/></dir></dir><dir name="Widget"><dir name="Button"><file name="Run.php" hash="f83df57a3248439261ccf9837a5d2ff9"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="231a77cbc7f38838454437c600189217"/></dir><dir name="Model"><dir name="Contact"><file name="Builder.php" hash="e81e78a7e07a81f5a0ec53990d629a31"/></dir><dir name="Roundtrip"><dir name="Test"><file name="Order.php" hash="04ebcb9f0010cab7952b08014010f721"/></dir></dir><file name="Roundtrip.php" hash="9325c6d924c2b9f4cda49ef0a5168d29"/></dir><dir name="Test"><dir name="Config"><file name="Config.php" hash="dbe4fb05bff7630d6130f8d458ed1f57"/></dir><dir name="Model"><dir name="Roundtrip"><file name="Contact.php" hash="787fe5d49eba3819e9af030bb80beeaa"/><dir name="Test"><file name="Order.php" hash="5bf175ebba99f97a93fb6755977dbfa0"/></dir></dir><file name="Roundtrip.php" hash="498d15680a5e7329fe267bb20b873c43"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="RoundtripController.php" hash="f52fcbd911f40b7637a88a96b0b40869"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="56be6bdda5b7652427bbab1e447a0d2e"/><file name="config.xml" hash="b34c9716b4c6fee7a1d8837b8debff65"/><file name="system.xml" hash="901a0736fb1109f9092fc98daa46dde7"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Bronto_All.xml" hash="5a9c06b6313882589765b9bcf0402bbb"/><file name="Bronto_ConflictChecker.xml" hash="1a7dc00b830ca2cc696e67d94b85be5d"/><file name="Bronto_Customer.xml" hash="a11c20f008ee2eae14baa3b549d5adee"/><file name="Bronto_Email.xml" hash="b7cdca4b15753edcefe8b9e0abb780bd"/><file name="Bronto_Newsletter.xml" hash="2115c5225e02ab5d4e56749cc5eff6ad"/><file name="Bronto_Order.xml" hash="63f1537add6088417945657bec98ffe9"/><file name="Bronto_PermissionChecker.xml" hash="55ff239c291529be2dc05799102d24a1"/><file name="Bronto_Reminder.xml" hash="08503ab78994178b822ef9b0add243f9"/><file name="Bronto_Roundtrip.xml" hash="bd2b89f3254e995904da92f025b6321c"/></dir></target><target name="magelib"><dir name="Bronto"><dir name="Api"><dir name="Account"><file name="Exception.php" hash="6048e32e08bac337f37e22918ae92e6a"/><file name="Row.php" hash="de3cb2496c217c25e850573c4d5b2dc2"/></dir><file name="Account.php" hash="30d5ef4bb101748553e239ffe2481183"/><dir name="Activity"><file name="Exception.php" hash="39ac264e8429c000372e849327372471"/><file name="Row.php" hash="b5612081f50d117a7c66f93f9b90382a"/></dir><file name="Activity.php" hash="35aaf580eb62df39b631041937c10187"/><dir name="ApiToken"><file name="Exception.php" hash="ff31b1be1c06581a115aabb7a782d9b5"/><file name="Row.php" hash="1716b6859c05b82301cf28bc7dcca4be"/></dir><file name="ApiToken.php" hash="20ecd2591d6634c42de7b05879c4bc04"/><dir name="Contact"><file name="Exception.php" hash="232fece284740b8e49a5d22ba3082b32"/><file name="Row.php" hash="a85937ee83f1a852372782a8dc1d2eab"/></dir><file name="Contact.php" hash="0413b22277d97b9d9f910281c14a6cea"/><dir name="Conversion"><file name="Exception.php" hash="edaba96e7118b8ce27220ffdabf56721"/><file name="Row.php" hash="495064d7f358f568c0c93b291a267b33"/></dir><file name="Conversion.php" hash="17d45962719271cdc834660cc3478071"/><dir name="Delivery"><file name="Exception.php" hash="c9c746a033ef90ac5e7c70e906331779"/><file name="Recipient.php" hash="9756477b2cbde59ece2b3720c02a5d75"/><file name="Row.php" hash="ca0880566674966a7aa9dee7c4c2c6eb"/></dir><file name="Delivery.php" hash="1866bf3ae809010f630deead7c76a09e"/><dir name="DeliveryGroup"><file name="Exception.php" hash="6ae170c14038a49413580a19ce7ee144"/><file name="Row.php" hash="d5046f7a5dbf39442730f45d17aeaf87"/></dir><file name="DeliveryGroup.php" hash="0e4572ad563c61dd78229af2b6d35cad"/><file name="Exception.php" hash="0df72a2002acff46885dd3978ea95678"/><dir name="Field"><file name="Exception.php" hash="3f900dcdbf5b8b321e48fa6d4a4a5ae1"/><file name="Predefined.php" hash="e876d133b211c4d66ad70ccba7bdff04"/><file name="Row.php" hash="d0c4001b14954dc45e35c8bf8e89cb65"/><file name="TypeGuesser.php" hash="d74ed1da1bd21c93ec68e753edee745f"/></dir><file name="Field.php" hash="4d42365676ef739f72ab50b09595bfa0"/><dir name="List"><file name="Exception.php" hash="ba39e47457265a2042dfaaf0b1c93d70"/><file name="Row.php" hash="bc8f0c84d486f1a41b113529e0da4cc4"/></dir><file name="List.php" hash="589a011d54b9cd6e2400f42fb0391967"/><dir name="Login"><file name="ContactInformation.php" hash="871630e7a0762cb4055183fe9b52b8ea"/><file name="Exception.php" hash="37a401b1206264c7865c62c1c62d394c"/><file name="Row.php" hash="3bfc793c2defa6f538c4b8749dbac22a"/></dir><file name="Login.php" hash="57afd59cd524e57e5a2bdb839a6207e4"/><dir name="Message"><file name="Exception.php" hash="3688ca7320fa9b0a5a3bba80ac4ed072"/><file name="Row.php" hash="ed93a1f123c65324b05e1d2c7b8b4b12"/></dir><file name="Message.php" hash="993e0bfd24d5663078735cbeae9a4b23"/><dir name="MessageRule"><file name="Exception.php" hash="500de77f33962484a640c24521f63659"/><file name="Row.php" hash="5a16b597def2515423e58ab36d17ff01"/></dir><file name="MessageRule.php" hash="bd30a4aa770714ac17b1b33da363aa60"/><file name="Object.php" hash="9681a0940cf96835f2d14b876cce0a4e"/><dir name="Order"><file name="Exception.php" hash="843fd9b527ad8be267664e59e803a2d8"/><file name="Product.php" hash="446161d2fe36cfd849f72066bda8c2ff"/><file name="Row.php" hash="470b921a06f832a0cad81c869038b26e"/></dir><file name="Order.php" hash="9a27755d756a06b82a0cc0d97c315519"/><dir name="Row"><file name="Exception.php" hash="2a48372f5f71cbaad940bc0a62327cff"/></dir><file name="Row.php" hash="459df27d460fd4c3923e860bc8a76a78"/><dir name="Rowset"><file name="Exception.php" hash="5b109a1eef32d14cbc66016fdf65ad9c"/><file name="Iterator.php" hash="0797f8c5a95d47a521ac333e853e6cd3"/></dir><file name="Rowset.php" hash="a10029ba58512887eb7aeb8e40a96a33"/><dir name="Segment"><file name="Exception.php" hash="c0fb3c3a1ed79177f5247abe40adf504"/><file name="Row.php" hash="5211fe7639821a8e413f7832d33dca3c"/></dir><file name="Segment.php" hash="67cf81752cd21a42ad7b6b2ab713c9eb"/></dir><file name="Api.php" hash="2f4d300d9921f4b46faf7d78e34466d9"/><file name="SoapClient.php" hash="f07d2c4551825a1018ddfbd997d660d8"/><dir name="Util"><file name="Colors.php" hash="9bc5a4ce486972d493c82fcb671b416c"/><file name="CountryCodes.php" hash="c666d446d3a156fb2881bf33f2acfc80"/><dir name="Retryer"><file name="FileRetryer.php" hash="6ce89108476048a6e45a7457f53272de"/><file name="RetryerException.php" hash="65ab6cc1f4e71fad55832657f700c653"/><file name="RetryerInterface.php" hash="29aab11684d6eb27439281cd9f6cee76"/></dir><file name="Uuid.php" hash="00f349c1dc57463ebf13639a6bbff6fd"/></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="base"><dir name="default"><dir name="bronto"><file name="cron.css" hash="c7260d3aa14b5945ee76c72dbd914efa"/><dir name="images"><file name="bg_notifications.gif" hash="df73b8aa7e48bb56e0a644245aa3683f"/><file name="logo.jpg" hash="3c6059218195679d99dbb874bdabbd07"/><file name="message_approved.gif" hash="465a056a3ba3d94367f51c3c0b751391"/><file name="message_not_approved.gif" hash="e4f28607f075a105e53fa3113d84bd26"/></dir></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="bronto"><dir name="newsletter"><file name="js.phtml" hash="1b36b8d1f438d5970b4ab0e8f97246d7"/></dir></dir></dir><dir name="layout"><dir name="bronto"><file name="newsletter.xml" hash="b7d4c9b1fb4fabb4255c6df64e98d332"/></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="bronto"><dir name="common"><file name="about.phtml" hash="f115cbc70309f4e3b14d33cf29bdb274"/><file name="cron.phtml" hash="f1dbdea68c377d7057230697450e16b1"/></dir><dir name="conflictchecker"><file name="errors.phtml" hash="26c9fa4332b8518141de9dab0db0c823"/></dir><dir name="email"><dir name="template"><file name="edit.phtml" hash="35c4f68337a6be7186be1aac0fbe404e"/><file name="list.phtml" hash="cf2503d79273b5a611cde3acde2bb79d"/></dir></dir><dir name="permissionchecker"><file name="errors.phtml" hash="0306e132afed0c88058be67d37dd211c"/></dir><dir name="roundtrip"><file name="status.phtml" hash="9ce88385bb507dfeb2df9e049a5f9f9d"/></dir></dir></dir><dir name="layout"><dir name="bronto"><file name="email.xml" hash="be77c906770a0d818898a910b03cbe4f"/><file name="reminder.xml" hash="98d835f287cb3aa2ff801f0219f88ccc"/><file name="roundtrip.xml" hash="3da91d3bcb40e1805a80fb2a18ed9cee"/></dir></dir></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><dir name="template"><dir name="email"><dir name="bronto"><file name="abandoned_cart.html" hash="20b0f55098c0f07bf96da3c5309d9192"/></dir></dir></dir></dir></target></contents>
49
  <compatible/>
50
  <dependencies><required><php><min>5.3.0</min><max>5.5.0</max></php><extension><name>soap</name><min></min><max></max></extension><extension><name>openssl</name><min></min><max></max></extension></required></dependencies>
51
  </package>