Version Notes
General Enhancement :
* A list of the status of prerequisites and extensions is now available in the SmartFocus menu of the System Configuration section.
* Cron jobs can now be configured to run on specific days of the week or on a specific day of the month.
* The cron job processes scheduled in the Magento Connector can now be restarted even if a previous cron job process encountered an error and did not close.
Data Synchronization :
* Data synchronization can now be configured to synchronize based on member email addresses.
* The data synchronization process now runs faster than in previous versions of the Magento Connector.
* You can now configure data synchronization for different stores with different SmartFocus accounts.
* In the Mapping feature:
** fields have been arranged into different categories,
** the following new fields for Calculated Purchase Information category have been added:
Used Email Addresses
Base Currency Code
List of Order #
Total Orders Purchased
Total Items Purchased
Average Items Purchased per Order
Total Order Amount Spent
Average Order Amount Spent per Purchase
Total Discount Amount
Average Discount Amount per Purchase
Total Shipping Amount
Average Shipping Amount per Purchase
Minimum Purchase Total
Maximum Purchase Total
First Purchase
Last Purchase
Minimum Items Purchased
Maximum Items Purchased
Shipping Methods
Payment Methods
Used Coupons
Total Purchases With Discount
* The menu Data Process List has been added to the Magento Connector, allowing you to monitor the progress of your scheduled synchronizations at a glance.
Transactional Emails
* You can now verify that your SmartFocus account is compatible with the Magento Connector in the Transactional Messages (NMP) menu and configure your account if you have modified the credentials for your account.
* A log clean-up process has been created.
Abandoned Carts Feature
* You can now process more than 8,000 abandoned carts simultaneously.
* You can now enable the test mode to send abandoned cart reminders in minutes rather than hours, and configure how long the cart will be able to receive reminders in hours.
* In the new menu 'List in the Abandoned Cart menu, you can access the list of abandoned cart reminder information.
Release Info
Developer | SmartFocus |
Extension | Campaign_Commander_Transactional_Email_1_5 |
Version | 3.1.0 |
Comparing to | |
See all releases |
Code changes from version 3.0.1 to 3.1.0
- app/code/community/Emv/CHANGELOG +60 -0
- app/code/community/Emv/CartAlert/Block/Adminhtml/List.php +66 -0
- app/code/community/Emv/CartAlert/Block/Adminhtml/List/Grid.php +336 -0
- app/code/community/Emv/CartAlert/Block/Adminhtml/List/Grid/Column/Renderer/Currency.php +33 -0
- app/code/community/Emv/CartAlert/Block/Adminhtml/Quote.php +43 -0
- app/code/community/Emv/CartAlert/Block/Adminhtml/Quote/Grid.php +123 -0
- app/code/community/Emv/CartAlert/Block/Adminhtml/System/Config/PromoRule.php +100 -0
- app/code/community/Emv/CartAlert/Block/Cart/Items.php +1 -1
- app/code/community/Emv/CartAlert/Constants.php +5 -0
- app/code/community/Emv/CartAlert/Helper/Data.php +151 -9
- app/code/community/Emv/CartAlert/Model/Observer.php +267 -59
- app/code/community/Emv/CartAlert/controllers/Adminhtml/AbandonmentController.php +195 -0
- app/code/community/Emv/CartAlert/etc/adminhtml.xml +32 -0
- app/code/community/Emv/CartAlert/etc/config.xml +29 -15
- app/code/community/Emv/CartAlert/etc/system.xml +55 -19
- app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.5.2-0.5.3.php +15 -0
- app/code/community/Emv/CartAlert/sql/abandonment_setup/mysql4-upgrade-0.5.3-0.5.4.php +25 -0
- app/code/community/Emv/Core/Block/Adminhtml/Account/Edit/AssociatedUrls.php +1 -1
- app/code/community/Emv/Core/Block/Adminhtml/Config/ExtensionStatus.php +434 -0
- app/code/community/Emv/Core/Block/Adminhtml/DataProcessing/Process.php +25 -0
- app/code/community/Emv/Core/Block/Adminhtml/DataProcessing/Process/Grid.php +164 -0
- app/code/community/Emv/Core/Block/Adminhtml/DataProcessing/Process/Grid/Column/Renderer/Links.php +33 -0
- app/code/community/Emv/Core/Block/Adminhtml/DataProcessing/Process/Grid/Column/Renderer/Output.php +59 -0
- app/code/community/Emv/Core/Helper/Data.php +181 -18
- app/code/community/Emv/Core/Model/Account.php +16 -0
- app/code/community/Emv/Core/Model/Adminhtml/System/Config/Backend/Account/Abstract.php +1 -14
- app/code/community/Emv/Core/Model/Adminhtml/System/Config/Backend/Cron.php +87 -0
- app/code/community/Emv/Core/Model/{System → Adminhtml/System}/Config/Source/Account.php +1 -1
- app/code/community/Emv/Core/Model/Adminhtml/System/Config/Source/CronDate.php +36 -0
- app/code/community/Emv/Core/Model/Adminhtml/System/Config/Source/CronDay.php +58 -0
- app/code/community/Emv/Core/Model/DataProcessing/Exception.php +12 -0
- app/code/community/Emv/Core/Model/DataProcessing/Process.php +335 -0
- app/code/community/Emv/Core/Model/DataProcessing/Process/Log.php +102 -0
- app/code/community/Emv/Core/Model/DataProcessing/Profile.php +195 -0
- app/code/community/Emv/Core/Model/DataProcessing/Profile/Interface.php +46 -0
- app/code/community/Emv/Core/Model/Mysql4/DataProcessing/Process.php +29 -0
- app/code/community/Emv/Core/Model/Mysql4/DataProcessing/Process/Collection.php +16 -0
- app/code/community/Emv/Core/Model/Service/Abstract.php +1 -0
- app/code/community/Emv/Core/Model/Service/Notification.php +1 -1
- app/code/community/Emv/Core/Model/Service/Transactional.php +2 -2
- app/code/community/Emv/Core/controllers/Adminhtml/AccountController.php +1 -1
- app/code/community/Emv/Core/controllers/Adminhtml/DataProcessingController.php +175 -0
- app/code/community/Emv/Core/etc/adminhtml.xml +12 -3
- app/code/community/Emv/Core/etc/config.xml +11 -1
- app/code/community/Emv/Core/functions.php +118 -0
- app/code/community/Emv/Core/sql/emvcore_setup/mysql4-upgrade-0.2.0-0.3.0.php +26 -0
- app/code/community/Emv/DataSync/Block/Adminhtml/Form/Field/CustomerAttributes.php +8 -42
- app/code/community/Emv/DataSync/Block/Adminhtml/Newsletter/Subscriber.php +24 -0
- app/code/community/Emv/DataSync/Block/Adminhtml/Newsletter/Subscriber/Grid.php +255 -0
- app/code/community/Emv/DataSync/Block/Adminhtml/System/Config/CustomerAttributes.php +1 -1
- app/code/community/Emv/DataSync/Block/Adminhtml/System/Config/GetFields.php +19 -2
- app/code/community/Emv/DataSync/Helper/Data.php +206 -26
- app/code/community/Emv/DataSync/Helper/Service.php +58 -211
- app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/BatchMember/Cron.php +2 -48
- app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/Clean/Cron.php +3 -2
- app/code/community/Emv/DataSync/Model/Adminhtml/System/Config/Backend/PurchaseProcess/Cron.php +59 -0
- app/code/community/Emv/DataSync/Model/AttributeProcessing/Config.php +321 -0
- app/code/community/Emv/DataSync/Model/AttributeProcessing/Handler/Abstract.php +106 -0
- app/code/community/Emv/DataSync/Model/AttributeProcessing/Handler/Customer.php +321 -0
- app/code/community/Emv/DataSync/Model/AttributeProcessing/Handler/Newsletter.php +99 -0
- app/code/community/Emv/DataSync/Model/AttributeProcessing/Handler/PurchaseInformation.php +154 -0
- app/code/community/Emv/DataSync/Model/Cron.php +132 -37
- app/code/community/Emv/DataSync/Model/DataProcess/PurchaseInformation.php +32 -0
- app/code/community/Emv/DataSync/Model/Mysql4/DataProcess/PurchaseInformation.php +42 -0
- app/code/community/Emv/DataSync/Model/Mysql4/DataProcess/PurchaseInformation/Collection.php +19 -0
- app/code/community/Emv/DataSync/Model/Observer.php +94 -27
- app/code/community/Emv/DataSync/Model/Service/BatchMember.php +707 -219
- app/code/community/Emv/DataSync/Model/Service/DataProcess.php +360 -0
- app/code/community/Emv/DataSync/Model/Service/Member.php +133 -107
- app/code/community/Emv/DataSync/controllers/Adminhtml/DataSyncController.php +270 -12
- app/code/community/Emv/DataSync/etc/adminhtml.xml +33 -0
- app/code/community/Emv/DataSync/etc/config.xml +45 -5
- app/code/community/Emv/DataSync/etc/system.xml +110 -11
- app/code/community/Emv/DataSync/sql/emvdatasync_setup/mysql4-install-0.0.1.php +3 -3
- app/code/community/Emv/DataSync/sql/emvdatasync_setup/mysql4-upgrade-0.1.0-0.2.0.php +20 -0
- app/code/community/Emv/DataSync/sql/emvdatasync_setup/mysql4-upgrade-0.2.0-0.2.1.php +60 -0
- app/code/community/Emv/Emt/Block/Adminhtml/Config/ExtensionStatus.php +56 -0
- app/code/community/Emv/Emt/Block/Adminhtml/Log/Grid.php +12 -1
- app/code/community/Emv/Emt/Block/Adminhtml/Resending/Grid.php +2 -1
- app/code/community/Emv/Emt/Block/Adminhtml/System/Config/ValidateAccount.php +39 -0
- app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit.php +4 -3
- app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit/Tab/EmvDyn.php +1 -1
- app/code/community/Emv/Emt/Block/Adminhtml/Template/Edit/Tab/General.php +1 -1
- app/code/community/Emv/Emt/Helper/Emvtemplate.php +78 -8
- app/code/community/Emv/Emt/Model/Adminhtml/System/Config/Backend/Account.php +1 -23
- app/code/community/Emv/Emt/Model/Adminhtml/System/Config/Backend/Log/Cron.php +12 -0
- app/code/community/Emv/Emt/Model/Cron.php +45 -1
- app/code/community/Emv/Emt/Model/Emt.php +1 -1
- app/code/community/Emv/Emt/Model/Log.php +11 -1
- app/code/community/Emv/Emt/Model/Mailmode.php +3 -3
- app/code/community/Emv/Emt/Model/Mysql4/Log.php +53 -0
- app/code/community/Emv/Emt/Model/Observer.php +28 -0
- app/code/community/Emv/Emt/Model/Resending/Rule.php +1 -1
- app/code/community/Emv/Emt/controllers/Adminhtml/TemplateController.php +23 -0
- app/code/community/Emv/Emt/etc/config.xml +30 -0
- app/code/community/Emv/Emt/etc/system.xml +77 -4
- app/code/community/Emv/Report/controllers/Adminhtml/ConversionController.php +1 -1
- app/code/community/Emv/Report/etc/adminhtml.xml +16 -6
- app/code/community/Emv/Report/etc/config.xml +1 -1
- app/design/adminhtml/default/default/layout/{emailvision → smartfocus}/abandonment_report.xml +1 -1
- app/design/adminhtml/default/default/layout/smartfocus/core.xml +8 -0
- app/design/adminhtml/default/default/template/emailvision/datasync/system/config/getfields.phtml +0 -15
- app/design/adminhtml/default/default/template/{emailvision → smartfocus}/abandonment/grid/container.phtml +0 -0
- app/design/adminhtml/default/default/template/{emailvision → smartfocus}/account/associated_urls.phtml +0 -0
- app/design/adminhtml/default/default/template/smartfocus/cartalert/system/config/promo_rule.phtml +75 -0
- app/design/adminhtml/default/default/template/smartfocus/config/extension_status.phtml +61 -0
- app/design/adminhtml/default/default/template/{emailvision → smartfocus}/datasync/system/config/form/field/array.phtml +0 -0
- app/design/adminhtml/default/default/template/smartfocus/datasync/system/config/getfields.phtml +12 -0
- app/design/adminhtml/default/default/template/smartfocus/emt/system/config/account_validation.phtml +96 -0
- app/design/adminhtml/default/default/template/{emailvision → smartfocus}/emt/template/common_js.phtml +0 -0
- app/design/adminhtml/default/default/template/{emailvision → smartfocus}/emt/template/edit.phtml +0 -0
- app/design/adminhtml/default/default/template/{emailvision → smartfocus}/emt/template/mapped_attributes.phtml +0 -0
- app/design/frontend/base/default/layout/{emailvision → smartfocus}/abandonment.xml +1 -1
- app/design/frontend/base/default/template/{emailvision → smartfocus}/abandonment/customer.phtml +0 -0
- app/design/frontend/base/default/template/{emailvision → smartfocus}/abandonment/reminder/items.phtml +4 -4
- app/locale/en_US/Emv_CartAlert.csv +40 -15
- app/locale/en_US/Emv_Core.csv +32 -2
- app/locale/en_US/Emv_DataSync.csv +15 -1
- app/locale/en_US/Emv_Emt.csv +6 -4
- app/locale/en_US/template/email/emailvision/datasync/cron_errors.html +0 -5
- app/locale/en_US/template/email/{emailvision → smartfocus}/abandonment/template1.html +0 -0
- app/locale/en_US/template/email/{emailvision → smartfocus}/abandonment/template2.html +0 -0
- app/locale/en_US/template/email/{emailvision → smartfocus}/abandonment/template3.html +0 -0
- app/locale/en_US/template/email/smartfocus/datasync/cron_errors.html +5 -0
- app/locale/fr_FR/Emv_CartAlert.csv +40 -15
- app/locale/fr_FR/Emv_Core.csv +32 -2
- app/locale/fr_FR/Emv_DataSync.csv +16 -1
- app/locale/fr_FR/Emv_Emt.csv +6 -4
- app/locale/fr_FR/Emv_Report.csv +1 -0
- lib/EmailVision/Api/BatchMemberService.php +62 -6
- lib/EmailVision/Api/NotificationService.php +3 -3
- lib/EmailVision/Tools/File/Csv.php +4 -1
- package.xml +48 -8
- skin/adminhtml/default/default/campaign-commander.css +0 -14
- skin/adminhtml/default/default/images/smartfocus/tick.png +0 -0
- skin/adminhtml/default/default/images/smartfocus/untick.gif +0 -0
- skin/adminhtml/default/default/images/smartfocus/warning.png +0 -0
- skin/adminhtml/default/default/smartfocus.css +25 -0
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
v3.1.0 - the 15th May 2014 ********************************************************************
|
2 |
+
[General]
|
3 |
+
#33 - Feature - Add new UI menu to display the global version of the extension and prerequisite status
|
4 |
+
#45 - Enhancement - Enhance cron job scheduling interface
|
5 |
+
#46 - Enhancement - Enhance lock mechanism for cron processes
|
6 |
+
|
7 |
+
[Data Sync]
|
8 |
+
#27 - Feature - DataSync should allow email sync.
|
9 |
+
#35 - Enhancement - Simplify the verifications
|
10 |
+
#38 - Feature - Add multi-store support
|
11 |
+
#39 - Enhancement - Enhance Mapping Zone
|
12 |
+
#42 - Bug - The performance parameter (Max number of fetched members per page) is not correctly taken in account.
|
13 |
+
#44 - Bug - When no mapping is setup, a fatal error has been raised.
|
14 |
+
#55 - Feature - Add new menu to show the progress of synchronization.
|
15 |
+
#56 - Feature - Add Customer Shipping Address in the mapping list.
|
16 |
+
#58 - Feature - Add new menu to show the subscriber queue to export.
|
17 |
+
#59 - Feature - Add new column "queued" inside newsletter_subscriber table in order to manage the subscriber queue to export
|
18 |
+
#66 - Feature - Add calculated purchase information by customer v1
|
19 |
+
For this version, only calculated purchase information is available :
|
20 |
+
* Used Email Addresses
|
21 |
+
* Base Currency Code
|
22 |
+
* List of Order #
|
23 |
+
* Total Orders Purchased
|
24 |
+
* Total Items Purchased
|
25 |
+
* Average Items Purchased per Order
|
26 |
+
* Total Order Amount Spent
|
27 |
+
* Average Order Amount Spent per Purchase
|
28 |
+
* Total Discount Amount
|
29 |
+
* Average Discount Amount per Purchase
|
30 |
+
* Total Shipping Amount
|
31 |
+
* Average Shipping Amount per Purchase
|
32 |
+
* Minimum Purchase Total
|
33 |
+
* Maximum Purchase Total
|
34 |
+
* First Purchase
|
35 |
+
* Last Purchase
|
36 |
+
* Minimum Items Purchased
|
37 |
+
* Maximum Items Purchased
|
38 |
+
* Shipping Methods
|
39 |
+
* Payment Methods
|
40 |
+
* Used Coupons
|
41 |
+
* Total Purchases With Discount
|
42 |
+
|
43 |
+
[NMP]
|
44 |
+
#28 - Feature - Add new button to verify the generic template when creating or modify a smartfocus account.
|
45 |
+
#37 - Feature - Add new process to clean up the sending log + rescheduling log
|
46 |
+
#41 - Bug - When deleting a SmartFocus account, delete also the temporary sending email template
|
47 |
+
#43 - Enhancement - The sending logs should be sorted from newer to older
|
48 |
+
#62 - Enhancement - Change default sending mode name
|
49 |
+
#67 - Enhancement - Increase the default connection time out and the execution time out
|
50 |
+
|
51 |
+
[Abandoned Carts]
|
52 |
+
#30 - Enhancement - Performance issue for treating more than 8000 abandoned carts at the same time
|
53 |
+
#52 - Enhancement - Change shopping cart rule from text field to select
|
54 |
+
#57 - Feature - Add test mode and life time parameters
|
55 |
+
#61 - Enhancement - add date/time into abandonment table
|
56 |
+
#63 - Bug - When a registered customer comes back and modifies his cart, the reminder process does not restart.
|
57 |
+
#64 - Feature - New menu to display a list of abandoned cart reminder information
|
58 |
+
#64 - Enhancement - add correct index into the three tables (abandonment, stats_email_abandonment_sent, emv_order_flag)
|
59 |
+
|
60 |
+
***********************************************************************************************
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Abandoned Cart Reminder List Grid Container
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_CartAlert
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
+
*/
|
10 |
+
class Emv_CartAlert_Block_Adminhtml_List extends Mage_Adminhtml_Block_Widget_Grid_Container
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Build abandonment list
|
14 |
+
* @see Mage_Adminhtml_Block_Widget_Grid_Container::__construct()
|
15 |
+
*/
|
16 |
+
public function __construct()
|
17 |
+
{
|
18 |
+
parent::__construct();
|
19 |
+
|
20 |
+
$this->_blockGroup = 'abandonment';
|
21 |
+
$this->_controller = 'adminhtml_list';
|
22 |
+
$this->_headerText = Mage::helper('abandonment')->__('Abandoned Cart Reminders');
|
23 |
+
$this->_removeButton('add');
|
24 |
+
}
|
25 |
+
|
26 |
+
/**
|
27 |
+
* Add Store switcher to layout
|
28 |
+
*
|
29 |
+
* (non-PHPdoc)
|
30 |
+
* @see Mage_Adminhtml_Block_Widget_Grid_Container::_prepareLayout()
|
31 |
+
*/
|
32 |
+
protected function _prepareLayout()
|
33 |
+
{
|
34 |
+
$this->setChild('store_switcher',
|
35 |
+
$this->getLayout()->createBlock('adminhtml/store_switcher')
|
36 |
+
->setUseConfirm(false)
|
37 |
+
->setSwitchUrl($this->getUrl('*/*/*', array('store'=>null)))
|
38 |
+
->setTemplate('report/store/switcher.phtml')
|
39 |
+
);
|
40 |
+
|
41 |
+
return parent::_prepareLayout();
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Get store switcher for multiple stores
|
46 |
+
*
|
47 |
+
* @return string
|
48 |
+
*/
|
49 |
+
public function getStoreSwitcherHtml()
|
50 |
+
{
|
51 |
+
if (Mage::app()->isSingleStoreMode()) {
|
52 |
+
return '';
|
53 |
+
}
|
54 |
+
return $this->getChildHtml('store_switcher');
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Get grid html with eventually store switcher block
|
59 |
+
* (non-PHPdoc)
|
60 |
+
* @see Mage_Adminhtml_Block_Widget_Grid_Container::getGridHtml()
|
61 |
+
*/
|
62 |
+
public function getGridHtml()
|
63 |
+
{
|
64 |
+
return $this->getStoreSwitcherHtml() . parent::getGridHtml();
|
65 |
+
}
|
66 |
+
}
|
@@ -0,0 +1,336 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Abandoned Cart Reminder List Grid Block
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_CartAlert
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
+
*/
|
10 |
+
class Emv_CartAlert_Block_Adminhtml_List_Grid extends Mage_Adminhtml_Block_Widget_Grid
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Stores current currency code
|
14 |
+
*/
|
15 |
+
protected $_currentCurrencyCode = null;
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Ids of current stores
|
19 |
+
*/
|
20 |
+
protected $_storeIds = array();
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Constructor
|
24 |
+
*
|
25 |
+
* Set main configuration of grid
|
26 |
+
*/
|
27 |
+
public function __construct()
|
28 |
+
{
|
29 |
+
parent::__construct();
|
30 |
+
$this->setId('abandonedcartGrid');
|
31 |
+
$this->setUseAjax(true);
|
32 |
+
$this->setDefaultSort('main_table.updated_at ', 'desc');
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* storeIds setter
|
37 |
+
*
|
38 |
+
* @param array $storeIds
|
39 |
+
* @return Mage_Adminhtml_Block_Report_Grid_Shopcart_Abstract
|
40 |
+
*/
|
41 |
+
public function setStoreIds($storeIds)
|
42 |
+
{
|
43 |
+
$this->_storeIds = $storeIds;
|
44 |
+
return $this;
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Retrieve currency code based on selected store
|
49 |
+
*
|
50 |
+
* @return string
|
51 |
+
*/
|
52 |
+
public function getCurrentCurrencyCode()
|
53 |
+
{
|
54 |
+
if (is_null($this->_currentCurrencyCode)) {
|
55 |
+
reset($this->_storeIds);
|
56 |
+
$this->_currentCurrencyCode = (count($this->_storeIds) > 0)
|
57 |
+
? Mage::app()->getStore(current($this->_storeIds))->getBaseCurrencyCode()
|
58 |
+
: Mage::app()->getStore()->getBaseCurrencyCode();
|
59 |
+
}
|
60 |
+
return $this->_currentCurrencyCode;
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Prepare quote collection for grid
|
65 |
+
*
|
66 |
+
* @return Mage_Adminhtml_Block_Widget_Grid
|
67 |
+
*/
|
68 |
+
protected function _prepareCollection()
|
69 |
+
{
|
70 |
+
$collection = Mage::getResourceSingleton('sales/quote_collection');
|
71 |
+
// prepare quote collection
|
72 |
+
$collection
|
73 |
+
->addFieldToFilter('items_count', array('gt' => 0)) // have at least 1 item
|
74 |
+
->addFieldToFilter('customer_email', array('notnull' => 1)) // a quote with a valid email address
|
75 |
+
->addFieldToFilter('is_active', 1) // only get active quotes
|
76 |
+
->setOrder('main_table.updated_at', Varien_Data_Collection::SORT_ORDER_DESC) // sort the carts from older to newer
|
77 |
+
;
|
78 |
+
|
79 |
+
// link to abandonment table to get sent reminder information
|
80 |
+
$resource = Mage::getModel('core/resource');
|
81 |
+
$collection->getSelect()->joinLeft(
|
82 |
+
array('abandonment' => $resource->getTableName('abandonment/abandonment')),
|
83 |
+
'main_table.entity_id = abandonment.entity_id',
|
84 |
+
array(
|
85 |
+
'abandonment.customer_abandonment_subscribed' => 'customer_abandonment_subscribed',
|
86 |
+
'abandonment.coupon_code' => 'abandonment.coupon_code',
|
87 |
+
'abandonment.updated_at' => 'abandonment.updated_at',
|
88 |
+
'abandonment.template' => 'abandonment.template'
|
89 |
+
)
|
90 |
+
);
|
91 |
+
|
92 |
+
// get subscription status to abandoned cart reminder notification
|
93 |
+
$attr = Mage::getModel('customer/customer')->getAttribute('abandonment_subscribed');
|
94 |
+
if ($attr->getAttributeId()) {
|
95 |
+
$adapter = $collection->getConnection();
|
96 |
+
$collection->getSelect()->joinLeft(
|
97 |
+
array('abandonment_subscribed' => $attr->getBackend()->getTable()),
|
98 |
+
$adapter->quoteInto(
|
99 |
+
'main_table.customer_id = abandonment_subscribed.entity_id'
|
100 |
+
. ' AND abandonment_subscribed.attribute_id = ?',
|
101 |
+
$attr->getAttributeId()
|
102 |
+
),
|
103 |
+
array(
|
104 |
+
'abandonment.customer_abandonment_subscribed'
|
105 |
+
=> 'IF(abandonment.customer_abandonment_subscribed IS NULL,
|
106 |
+
IF(abandonment_subscribed.value IS NULL, 1, abandonment_subscribed.value),
|
107 |
+
abandonment.customer_abandonment_subscribed)',
|
108 |
+
)
|
109 |
+
);
|
110 |
+
}
|
111 |
+
|
112 |
+
if (count($this->_storeIds)) {
|
113 |
+
$collection->addFieldToFilter('store_id', array('in' => $this->_storeIds));
|
114 |
+
}
|
115 |
+
|
116 |
+
$this->setCollection($collection);
|
117 |
+
|
118 |
+
return parent::_prepareCollection();
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* (non-PHPdoc)
|
123 |
+
* @see Mage_Adminhtml_Block_Widget_Grid::_prepareColumns()
|
124 |
+
*/
|
125 |
+
protected function _prepareColumns()
|
126 |
+
{
|
127 |
+
$this->addColumn('customer_email', array(
|
128 |
+
'header' => Mage::helper('reports')->__('Email'),
|
129 |
+
'index' => 'customer_email',
|
130 |
+
'sortable' => false
|
131 |
+
));
|
132 |
+
|
133 |
+
$this->addColumn('items_count', array(
|
134 |
+
'header' => Mage::helper('abandonment')->__('Number of Item Types'),
|
135 |
+
'width' => '80px',
|
136 |
+
'align' => 'right',
|
137 |
+
'index' => 'items_count',
|
138 |
+
'sortable' => false,
|
139 |
+
'type' => 'number'
|
140 |
+
));
|
141 |
+
|
142 |
+
$this->addColumn('items_qty', array(
|
143 |
+
'header' => Mage::helper('abandonment')->__('Number of Items'),
|
144 |
+
'width' => '80px',
|
145 |
+
'align' => 'right',
|
146 |
+
'index' => 'items_qty',
|
147 |
+
'sortable' => false,
|
148 |
+
'type' => 'number'
|
149 |
+
));
|
150 |
+
|
151 |
+
if ($this->getRequest()->getParam('website')) {
|
152 |
+
$storeIds = Mage::app()->getWebsite($this->getRequest()->getParam('website'))->getStoreIds();
|
153 |
+
} else if ($this->getRequest()->getParam('group')) {
|
154 |
+
$storeIds = Mage::app()->getGroup($this->getRequest()->getParam('group'))->getStoreIds();
|
155 |
+
} else if ($this->getRequest()->getParam('store')) {
|
156 |
+
$storeIds = array((int)$this->getRequest()->getParam('store'));
|
157 |
+
} else {
|
158 |
+
$storeIds = array();
|
159 |
+
}
|
160 |
+
$this->setStoreIds($storeIds);
|
161 |
+
$currencyCode = $this->getCurrentCurrencyCode();
|
162 |
+
|
163 |
+
$this->addColumn('subtotal', array(
|
164 |
+
'header' => Mage::helper('reports')->__('Subtotal'),
|
165 |
+
'width' => '80px',
|
166 |
+
'type' => 'currency',
|
167 |
+
'currency_code' => $currencyCode,
|
168 |
+
'index' => 'subtotal',
|
169 |
+
'sortable' => false,
|
170 |
+
'renderer' => 'abandonment/adminhtml_list_grid_column_renderer_currency',
|
171 |
+
'rate' => $this->getRate($currencyCode),
|
172 |
+
));
|
173 |
+
|
174 |
+
$this->addColumn('coupon_code', array(
|
175 |
+
'header' => Mage::helper('reports')->__('Applied Coupon'),
|
176 |
+
'width' => '80px',
|
177 |
+
'index' => 'coupon_code',
|
178 |
+
'filter_index' => 'main_table.coupon_code',
|
179 |
+
'sortable' => false
|
180 |
+
));
|
181 |
+
|
182 |
+
$this->addColumn('customer', array(
|
183 |
+
'header' => Mage::helper('abandonment')->__('Customer ID'),
|
184 |
+
'width' => '80px',
|
185 |
+
'index' => 'customer_id',
|
186 |
+
'filter_index' => 'main_table.customer_id',
|
187 |
+
'sortable' => false
|
188 |
+
));
|
189 |
+
|
190 |
+
$this->addColumn('created_at', array(
|
191 |
+
'header' => Mage::helper('reports')->__('Created On'),
|
192 |
+
'width' => '170px',
|
193 |
+
'type' => 'datetime',
|
194 |
+
'index' => 'created_at',
|
195 |
+
'filter_index' => 'main_table.created_at',
|
196 |
+
'sortable' => false
|
197 |
+
));
|
198 |
+
|
199 |
+
$this->addColumn('updated_at', array(
|
200 |
+
'header' => Mage::helper('reports')->__('Updated On'),
|
201 |
+
'width' => '170px',
|
202 |
+
'type' => 'datetime',
|
203 |
+
'index' => 'updated_at',
|
204 |
+
'filter_index'=> 'main_table.updated_at',
|
205 |
+
'sortable' => false
|
206 |
+
));
|
207 |
+
|
208 |
+
$this->addColumn('remote_ip', array(
|
209 |
+
'header' => Mage::helper('reports')->__('IP Address'),
|
210 |
+
'width' => '80px',
|
211 |
+
'index' => 'remote_ip',
|
212 |
+
'sortable' => false
|
213 |
+
));
|
214 |
+
|
215 |
+
$this->addColumn('reminder_id', array(
|
216 |
+
'header' => Mage::helper('abandonment')->__('Sent Reminder'),
|
217 |
+
'index' => 'abandonment.template',
|
218 |
+
'type' => 'options',
|
219 |
+
'sortable' => false,
|
220 |
+
'options' => Mage::helper('abandonment')->getReminderLables()
|
221 |
+
));
|
222 |
+
|
223 |
+
$this->addColumn('abandonment_updated_at', array(
|
224 |
+
'header' => Mage::helper('abandonment')->__('Reminder Last Update'),
|
225 |
+
'type' => 'datetime',
|
226 |
+
'index' => 'abandonment.updated_at',
|
227 |
+
'sortable' => false
|
228 |
+
));
|
229 |
+
|
230 |
+
$this->addColumn('abandonment_subscribed', array(
|
231 |
+
'header' => Mage::helper('abandonment')->__('Subscribed to abandoned cart reminders'),
|
232 |
+
'type' => 'options',
|
233 |
+
'index' => 'abandonment.customer_abandonment_subscribed',
|
234 |
+
'options' => array(
|
235 |
+
1 => Mage::helper('core')->__('Yes'),
|
236 |
+
0 => Mage::helper('core')->__('No'),
|
237 |
+
),
|
238 |
+
'filter' => false,
|
239 |
+
'sortable' => false
|
240 |
+
));
|
241 |
+
|
242 |
+
$this->addColumn('abandonment_coupon_code', array(
|
243 |
+
'header' => Mage::helper('abandonment')->__('Reminder Coupon'),
|
244 |
+
'width' => '80px',
|
245 |
+
'index' => 'abandonment.coupon_code',
|
246 |
+
'sortable' => false
|
247 |
+
));
|
248 |
+
|
249 |
+
$this->addExportType('*/*/exportAbandonedCsv', Mage::helper('reports')->__('CSV'));
|
250 |
+
$this->addExportType('*/*/exportAbandonedExcel', Mage::helper('reports')->__('Excel XML'));
|
251 |
+
|
252 |
+
return parent::_prepareColumns();
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Allow to find any abandoned carts that haven't had any reminder
|
257 |
+
*
|
258 |
+
* (non-PHPdoc)
|
259 |
+
* @see Mage_Adminhtml_Block_Widget_Grid::_addColumnFilterToCollection()
|
260 |
+
*/
|
261 |
+
protected function _addColumnFilterToCollection($column)
|
262 |
+
{
|
263 |
+
$field = ( $column->getFilterIndex() ) ? $column->getFilterIndex() : $column->getIndex();
|
264 |
+
|
265 |
+
if ($field == 'abandonment.template'
|
266 |
+
&& $column->getFilter()
|
267 |
+
&& $column->getFilter()->getValue() == Emv_CartAlert_Constants::NONE_FLAG
|
268 |
+
) {
|
269 |
+
$this->getCollection()->addFieldToFilter(
|
270 |
+
array('abandonment.template', 'abandonment.template'),
|
271 |
+
array(array('null' => 0), array('eq' => ""))
|
272 |
+
);
|
273 |
+
return $this;
|
274 |
+
}
|
275 |
+
|
276 |
+
parent::_addColumnFilterToCollection($column);
|
277 |
+
return $this;
|
278 |
+
}
|
279 |
+
|
280 |
+
/**
|
281 |
+
* (non-PHPdoc)
|
282 |
+
* @see Mage_Adminhtml_Block_Widget_Grid::_prepareMassaction()
|
283 |
+
*/
|
284 |
+
protected function _prepareMassaction()
|
285 |
+
{
|
286 |
+
$this->setMassactionIdField('entity_id');
|
287 |
+
$this->getMassactionBlock()->setFormFieldName('quotes');
|
288 |
+
|
289 |
+
$this->getMassactionBlock()->addItem('first_reminder', array(
|
290 |
+
'label' => Mage::helper('abandonment')->__('Test First Reminder'),
|
291 |
+
'url' => $this->getUrl('*/*/testReminder' , array('template' => Emv_CartAlert_Constants::FIRST_ALERT_FLAG)),
|
292 |
+
'confirm' => Mage::helper('customer')->__('Are you sure?')
|
293 |
+
));
|
294 |
+
$this->getMassactionBlock()->addItem('second_reminder', array(
|
295 |
+
'label' => Mage::helper('abandonment')->__('Test Second Reminder'),
|
296 |
+
'url' => $this->getUrl('*/*/testReminder', array('template' => Emv_CartAlert_Constants::SECOND_ALERT_FLAG)),
|
297 |
+
'confirm' => Mage::helper('customer')->__('Are you sure?')
|
298 |
+
));
|
299 |
+
$this->getMassactionBlock()->addItem('third_reminder', array(
|
300 |
+
'label' => Mage::helper('abandonment')->__('Test Third Reminder'),
|
301 |
+
'url' => $this->getUrl('*/*/testReminder', array('template' => Emv_CartAlert_Constants::THIRD_ALERT_FLAG)),
|
302 |
+
'confirm' => Mage::helper('customer')->__('Are you sure?')
|
303 |
+
));
|
304 |
+
return $this;
|
305 |
+
}
|
306 |
+
|
307 |
+
/**
|
308 |
+
* Get row class - determine the row class according to their subscription information to reminder notification
|
309 |
+
*
|
310 |
+
* @param Varien_Object $emvEmt
|
311 |
+
* @return string
|
312 |
+
*/
|
313 |
+
public function getRowClass(Varien_Object $row)
|
314 |
+
{
|
315 |
+
$class = "";
|
316 |
+
if ($row->getData('abandonment.customer_abandonment_subscribed') == 0) {
|
317 |
+
$class= "invalid";
|
318 |
+
}
|
319 |
+
return $class;
|
320 |
+
}
|
321 |
+
|
322 |
+
/**
|
323 |
+
* (non-PHPdoc)
|
324 |
+
* @see Mage_Adminhtml_Block_Widget_Grid::getRowUrl()
|
325 |
+
*/
|
326 |
+
public function getRowUrl($row)
|
327 |
+
{
|
328 |
+
if ($row->getCustomerId()) {
|
329 |
+
return $this->getUrl('adminhtml/customer/edit', array('id' => $row->getCustomerId(), 'active_tab'=>'cart'));
|
330 |
+
} else {
|
331 |
+
return $this->getUrl('*/*/displayQuote', array('quote' => $row->getId()));
|
332 |
+
}
|
333 |
+
|
334 |
+
return '#';
|
335 |
+
}
|
336 |
+
}
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Adminhtml grid item renderer currency
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_CartAlert
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
+
*/
|
10 |
+
|
11 |
+
class Emv_CartAlert_Block_Adminhtml_List_Grid_Column_Renderer_Currency extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Currency
|
12 |
+
{
|
13 |
+
/**
|
14 |
+
* Renders grid column
|
15 |
+
*
|
16 |
+
* @param Varien_Object $row
|
17 |
+
* @return string
|
18 |
+
*/
|
19 |
+
public function render(Varien_Object $row)
|
20 |
+
{
|
21 |
+
$data = $row->getData($this->getColumn()->getIndex());
|
22 |
+
$currency_code = $this->_getCurrencyCode($row);
|
23 |
+
|
24 |
+
if (!$currency_code) {
|
25 |
+
return $data;
|
26 |
+
}
|
27 |
+
|
28 |
+
$data = floatval($data) * $this->_getRate($row);
|
29 |
+
$data = sprintf("%f", $data);
|
30 |
+
$data = Mage::app()->getLocale()->currency($currency_code)->toCurrency($data);
|
31 |
+
return $data;
|
32 |
+
}
|
33 |
+
}
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Quote grid container block
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_CartAlert
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
+
*/
|
10 |
+
class Emv_CartAlert_Block_Adminhtml_Quote extends Mage_Adminhtml_Block_Widget_Grid_Container
|
11 |
+
{
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Construct account menu
|
15 |
+
* @see Mage_Adminhtml_Block_Widget_Grid_Container::__construct()
|
16 |
+
*/
|
17 |
+
public function __construct()
|
18 |
+
{
|
19 |
+
parent::__construct();
|
20 |
+
$this->_blockGroup = 'abandonment';
|
21 |
+
$this->_controller = 'adminhtml_quote';
|
22 |
+
|
23 |
+
$quote = Mage::registry('smartfocus_quote');
|
24 |
+
$this->_headerText = Mage::helper('abandonment')->__(
|
25 |
+
'Abandoned Cart (customer email : %s - on store %s)',
|
26 |
+
$quote->getCustomerEmail(),
|
27 |
+
Mage::app()->getStore($quote->getStoreId())->getName()
|
28 |
+
);
|
29 |
+
|
30 |
+
$this->_removeButton('add');
|
31 |
+
$this->_addBackButton();
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Link back to abandoned cart list page
|
36 |
+
*
|
37 |
+
* @return string
|
38 |
+
*/
|
39 |
+
public function getBackUrl()
|
40 |
+
{
|
41 |
+
return $this->getUrl('*/*/list');
|
42 |
+
}
|
43 |
+
}
|
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Quote Product Information Grid Block
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_CartAlert
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
+
*/
|
10 |
+
class Emv_CartAlert_Block_Adminhtml_Quote_Grid extends Mage_Adminhtml_Block_Widget_Grid
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Prepare grid
|
14 |
+
*
|
15 |
+
* @return void
|
16 |
+
*/
|
17 |
+
protected function _prepareGrid()
|
18 |
+
{
|
19 |
+
$this->setId('smartfocus_cart_grid');
|
20 |
+
$quote = Mage::registry('smartfocus_quote');
|
21 |
+
|
22 |
+
if ($quote) {
|
23 |
+
$this->setStoreId($quote->getStoreId());
|
24 |
+
}
|
25 |
+
parent::_prepareGrid();
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Prepare collection
|
30 |
+
*
|
31 |
+
* (non-PHPdoc)
|
32 |
+
* @see Mage_Adminhtml_Block_Widget_Grid::_prepareCollection()
|
33 |
+
*/
|
34 |
+
protected function _prepareCollection()
|
35 |
+
{
|
36 |
+
$quote = Mage::registry('smartfocus_quote');
|
37 |
+
if ($quote) {
|
38 |
+
$collection = $quote->getItemsCollection(false);
|
39 |
+
} else {
|
40 |
+
$collection = new Varien_Data_Collection();
|
41 |
+
}
|
42 |
+
|
43 |
+
$collection->addFieldToFilter('parent_item_id', array('null' => true));
|
44 |
+
|
45 |
+
$this->setCollection($collection);
|
46 |
+
|
47 |
+
return parent::_prepareCollection();
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* (non-PHPdoc)
|
52 |
+
* @see Mage_Adminhtml_Block_Widget_Grid::_prepareColumns()
|
53 |
+
*/
|
54 |
+
protected function _prepareColumns()
|
55 |
+
{
|
56 |
+
$this->addColumn('product_id', array(
|
57 |
+
'header' => Mage::helper('catalog')->__('Product ID'),
|
58 |
+
'index' => 'product_id',
|
59 |
+
'width' => '100px',
|
60 |
+
));
|
61 |
+
|
62 |
+
$this->addColumn('name', array(
|
63 |
+
'header' => Mage::helper('catalog')->__('Product Name'),
|
64 |
+
'index' => 'name',
|
65 |
+
'renderer' => 'adminhtml/customer_edit_tab_view_grid_renderer_item'
|
66 |
+
));
|
67 |
+
|
68 |
+
$this->addColumn('created_at', array(
|
69 |
+
'header' => Mage::helper('reports')->__('Created At'),
|
70 |
+
'index' => 'created_at',
|
71 |
+
'type' => 'datetime',
|
72 |
+
'width' => '150px',
|
73 |
+
));
|
74 |
+
$this->addColumn('updated_at', array(
|
75 |
+
'header' => Mage::helper('reports')->__('Updated At'),
|
76 |
+
'index' => 'updated_at',
|
77 |
+
'type' => 'datetime',
|
78 |
+
'width' => '150px',
|
79 |
+
));
|
80 |
+
|
81 |
+
$this->addColumn('sku', array(
|
82 |
+
'header' => Mage::helper('catalog')->__('SKU'),
|
83 |
+
'index' => 'sku',
|
84 |
+
'width' => '100px',
|
85 |
+
));
|
86 |
+
|
87 |
+
$this->addColumn('qty', array(
|
88 |
+
'header' => Mage::helper('catalog')->__('Qty'),
|
89 |
+
'index' => 'qty',
|
90 |
+
'type' => 'number',
|
91 |
+
'width' => '60px',
|
92 |
+
));
|
93 |
+
|
94 |
+
$this->addColumn('price', array(
|
95 |
+
'header' => Mage::helper('catalog')->__('Price'),
|
96 |
+
'index' => 'price',
|
97 |
+
'type' => 'currency',
|
98 |
+
'currency_code' => (string) Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE,
|
99 |
+
$this->getStoreId()),
|
100 |
+
));
|
101 |
+
|
102 |
+
$this->addColumn('total', array(
|
103 |
+
'header' => Mage::helper('sales')->__('Total'),
|
104 |
+
'index' => 'row_total',
|
105 |
+
'type' => 'currency',
|
106 |
+
'currency_code' => (string) Mage::getStoreConfig(Mage_Directory_Model_Currency::XML_PATH_CURRENCY_BASE,
|
107 |
+
$this->getStoreId()),
|
108 |
+
));
|
109 |
+
|
110 |
+
return parent::_prepareColumns();
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* The link to product page
|
115 |
+
*
|
116 |
+
* (non-PHPdoc)
|
117 |
+
* @see Mage_Adminhtml_Block_Widget_Grid::getRowUrl()
|
118 |
+
*/
|
119 |
+
public function getRowUrl($row)
|
120 |
+
{
|
121 |
+
return $this->getUrl('adminhtml/catalog_product/edit', array('id' => $row->getProductId()));
|
122 |
+
}
|
123 |
+
}
|
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Promotion Rule Chooser block
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_CartAlert
|
7 |
+
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
|
11 |
+
class Emv_CartAlert_Block_Adminhtml_System_Config_PromoRule
|
12 |
+
extends Mage_Adminhtml_Block_System_Config_Form_Field
|
13 |
+
{
|
14 |
+
/**
|
15 |
+
* Set template to itself
|
16 |
+
*
|
17 |
+
* @return Emv_CartAlert_Block_Adminhtml_System_Config_PromoRule
|
18 |
+
*/
|
19 |
+
protected function _prepareLayout()
|
20 |
+
{
|
21 |
+
parent::_prepareLayout();
|
22 |
+
if (!$this->getTemplate()) {
|
23 |
+
$this->setTemplate('smartfocus/cartalert/system/config/promo_rule.phtml');
|
24 |
+
}
|
25 |
+
return $this;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Get button config in Json
|
30 |
+
*
|
31 |
+
* @return string
|
32 |
+
*/
|
33 |
+
public function getButtonConfigInJson()
|
34 |
+
{
|
35 |
+
$config = array(
|
36 |
+
'buttons' => array(
|
37 |
+
'open' => Mage::helper('abandonment')->__('Select Promotion Rule'),
|
38 |
+
'close' => Mage::helper('abandonment')->__('Close'),
|
39 |
+
)
|
40 |
+
);
|
41 |
+
return Mage::helper('core')->jsonEncode($config);
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Get promotion rule id
|
46 |
+
*
|
47 |
+
* @return int
|
48 |
+
*/
|
49 |
+
public function getRuleId()
|
50 |
+
{
|
51 |
+
$id = '';
|
52 |
+
if ($this->getElement()) {
|
53 |
+
$id = (int)$this->getElement()->getValue();
|
54 |
+
}
|
55 |
+
return $id;
|
56 |
+
}
|
57 |
+
|
58 |
+
/**
|
59 |
+
* Get Label for element
|
60 |
+
*
|
61 |
+
* @return string
|
62 |
+
*/
|
63 |
+
public function getLabel()
|
64 |
+
{
|
65 |
+
$label = false;
|
66 |
+
if ($this->getElement()) {
|
67 |
+
$rule = Mage::getModel('salesrule/rule')->load((int)$this->getElement()->getValue());
|
68 |
+
if ($rule->getId()) {
|
69 |
+
$label = $rule->getName();
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
if (!$label) {
|
74 |
+
$label = Mage::helper('widget')->__('Not Selected');
|
75 |
+
}
|
76 |
+
|
77 |
+
return $label;
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* @return string
|
82 |
+
*/
|
83 |
+
public function getElementName()
|
84 |
+
{
|
85 |
+
return ($this->getElement()) ? $this->getElement()->getName() : '';
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Get the button and scripts contents
|
90 |
+
*
|
91 |
+
* @param Varien_Data_Form_Element_Abstract $element
|
92 |
+
*
|
93 |
+
* @return string
|
94 |
+
*/
|
95 |
+
protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
|
96 |
+
{
|
97 |
+
$this->setElement($element);
|
98 |
+
return $this->_toHtml();
|
99 |
+
}
|
100 |
+
}
|
@@ -14,6 +14,6 @@ class Emv_CartAlert_Block_Cart_Items extends Mage_Sales_Block_Items_Abstract
|
|
14 |
public function __construct()
|
15 |
{
|
16 |
parent::__construct();
|
17 |
-
$this->setTemplate('
|
18 |
}
|
19 |
}
|
14 |
public function __construct()
|
15 |
{
|
16 |
parent::__construct();
|
17 |
+
$this->setTemplate('smartfocus' . DS . 'abandonment' . DS . 'reminder' . DS . 'items.phtml');
|
18 |
}
|
19 |
}
|
@@ -4,10 +4,14 @@
|
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_CartAlert
|
|
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
*/
|
9 |
interface Emv_CartAlert_Constants
|
10 |
{
|
|
|
|
|
|
|
11 |
const XML_PATH_FIRST_ALERT_ENABLED = 'abandonment/first_alert_config/enabled';
|
12 |
const XML_PATH_FIRST_ALERT_TEMPLATE = 'abandonment/first_alert_config/template';
|
13 |
const XML_PATH_FIRST_ALERT_DELAY = 'abandonment/first_alert_config/delay';
|
@@ -28,6 +32,7 @@ interface Emv_CartAlert_Constants
|
|
28 |
const XML_PATH_COUPON_CODE_SUFFIX = 'abandonment/general/suffix';
|
29 |
const XML_PATH_COUPON_CODE_DASH = 'abandonment/general/dash';
|
30 |
|
|
|
31 |
const FIRST_ALERT_FLAG = 'first_alert';
|
32 |
const FIRST_ALERT_REMINDER_ID = 1;
|
33 |
const SECOND_ALERT_FLAG = 'second_alert';
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_CartAlert
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
9 |
*/
|
10 |
interface Emv_CartAlert_Constants
|
11 |
{
|
12 |
+
const XML_PATH_TEST_MODE_ENABLED = 'abandonment/general/test_mode';
|
13 |
+
const XML_PATH_LIFETIME = 'abandonment/general/lifetime';
|
14 |
+
|
15 |
const XML_PATH_FIRST_ALERT_ENABLED = 'abandonment/first_alert_config/enabled';
|
16 |
const XML_PATH_FIRST_ALERT_TEMPLATE = 'abandonment/first_alert_config/template';
|
17 |
const XML_PATH_FIRST_ALERT_DELAY = 'abandonment/first_alert_config/delay';
|
32 |
const XML_PATH_COUPON_CODE_SUFFIX = 'abandonment/general/suffix';
|
33 |
const XML_PATH_COUPON_CODE_DASH = 'abandonment/general/dash';
|
34 |
|
35 |
+
const NONE_FLAG = 'none';
|
36 |
const FIRST_ALERT_FLAG = 'first_alert';
|
37 |
const FIRST_ALERT_REMINDER_ID = 1;
|
38 |
const SECOND_ALERT_FLAG = 'second_alert';
|
@@ -4,6 +4,7 @@
|
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_CartAlert
|
|
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
*/
|
9 |
class Emv_CartAlert_Helper_Data extends Mage_Core_Helper_Abstract
|
@@ -18,6 +19,12 @@ class Emv_CartAlert_Helper_Data extends Mage_Core_Helper_Abstract
|
|
18 |
*/
|
19 |
const XML_PATH_IMAGE_SIZE = 'abandonment/general/image_size';
|
20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
/**
|
22 |
* @var array
|
23 |
*/
|
@@ -46,6 +53,53 @@ class Emv_CartAlert_Helper_Data extends Mage_Core_Helper_Abstract
|
|
46 |
*/
|
47 |
protected $_rules = array();
|
48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
/**
|
50 |
* Detect whether the quote is associated with a registered customer
|
51 |
*
|
@@ -154,12 +208,12 @@ class Emv_CartAlert_Helper_Data extends Mage_Core_Helper_Abstract
|
|
154 |
* Retrieves an image URL for the product, if it exists.
|
155 |
* The priority is: thumbnail -> small image -> image -> Magento's placeholder.
|
156 |
*
|
157 |
-
* @param $
|
158 |
* @return string the image's URL
|
159 |
*/
|
160 |
-
public function getProductImageUrl ($
|
161 |
{
|
162 |
-
$product = $this->
|
163 |
|
164 |
$imageSize = Mage::getStoreConfig(self::XML_PATH_IMAGE_SIZE);
|
165 |
if (!$imageSize) {
|
@@ -186,10 +240,11 @@ class Emv_CartAlert_Helper_Data extends Mage_Core_Helper_Abstract
|
|
186 |
* @param string $productId
|
187 |
* @return multitype:
|
188 |
*/
|
189 |
-
public function
|
190 |
{
|
|
|
191 |
if (!isset($this->_loadedProducts[$productId])) {
|
192 |
-
$this->_loadedProducts[$productId] =
|
193 |
}
|
194 |
|
195 |
return $this->_loadedProducts[$productId];
|
@@ -224,11 +279,13 @@ class Emv_CartAlert_Helper_Data extends Mage_Core_Helper_Abstract
|
|
224 |
* @param $storeId
|
225 |
* @param Emv_CartAlert_Model_Abandonment $abandonment
|
226 |
* @param Mage_Core_Model_Email_Template
|
|
|
227 |
*/
|
228 |
public function sendReminder(
|
229 |
Mage_Sales_Model_Quote $abandonedCart,
|
230 |
$storeId,
|
231 |
-
Emv_CartAlert_Model_Abandonment $abandonment
|
|
|
232 |
) {
|
233 |
// determine which template should be used
|
234 |
$reminderId = false;
|
@@ -269,17 +326,58 @@ class Emv_CartAlert_Helper_Data extends Mage_Core_Helper_Abstract
|
|
269 |
Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_ALERT_SENDER_IDENTITY, $storeId),
|
270 |
$abandonedCart->getCustomerEmail(),
|
271 |
$abandonedCart->getPreparedCustomerName(),
|
272 |
-
|
273 |
$storeId
|
274 |
);
|
275 |
|
276 |
-
|
277 |
-
|
|
|
|
|
278 |
}
|
279 |
}
|
280 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
281 |
/**
|
282 |
* Update statistic information about the reminder sending
|
|
|
283 |
* @param int $reminderId
|
284 |
* @param int $quoteId
|
285 |
* @param int $storeId
|
@@ -440,6 +538,50 @@ class Emv_CartAlert_Helper_Data extends Mage_Core_Helper_Abstract
|
|
440 |
return $code;
|
441 |
}
|
442 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
443 |
/**
|
444 |
* Support functions - Used for debugging purposes
|
445 |
*/
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_CartAlert
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
9 |
*/
|
10 |
class Emv_CartAlert_Helper_Data extends Mage_Core_Helper_Abstract
|
19 |
*/
|
20 |
const XML_PATH_IMAGE_SIZE = 'abandonment/general/image_size';
|
21 |
|
22 |
+
/**
|
23 |
+
*
|
24 |
+
* XML PATH to get the limit to run
|
25 |
+
*/
|
26 |
+
const XML_PATH_CART_LIMIT = 'abandonment/general/limit';
|
27 |
+
|
28 |
/**
|
29 |
* @var array
|
30 |
*/
|
53 |
*/
|
54 |
protected $_rules = array();
|
55 |
|
56 |
+
/**
|
57 |
+
* Lock file name pattern
|
58 |
+
*/
|
59 |
+
const LOCK_FILE_NAME_PATTERN = 'abandoned_cart_process';
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Check if lock file exists
|
63 |
+
*
|
64 |
+
* @return boolean
|
65 |
+
*/
|
66 |
+
public function checkLockFile()
|
67 |
+
{
|
68 |
+
return Mage::helper('emvcore')->checkLockFile(self::LOCK_FILE_NAME_PATTERN);
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Get cart limit for one run
|
73 |
+
*
|
74 |
+
* @return int
|
75 |
+
*/
|
76 |
+
public function getCartLimitForOneRun()
|
77 |
+
{
|
78 |
+
return (int)Mage::getStoreConfig(self::XML_PATH_CART_LIMIT);
|
79 |
+
}
|
80 |
+
|
81 |
+
/**
|
82 |
+
* Create a lock file
|
83 |
+
*
|
84 |
+
* @param string $content
|
85 |
+
* @return mutilple <number, boolean>
|
86 |
+
*/
|
87 |
+
public function createLockFile($content = '')
|
88 |
+
{
|
89 |
+
return Mage::helper('emvcore')->createLockFile(self::LOCK_FILE_NAME_PATTERN, $content);
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Remove a lock file
|
94 |
+
*
|
95 |
+
* @param string $content
|
96 |
+
* @return boolean
|
97 |
+
*/
|
98 |
+
public function removeLockFile($content = '')
|
99 |
+
{
|
100 |
+
return Mage::helper('emvcore')->removeLockFile(self::LOCK_FILE_NAME_PATTERN);
|
101 |
+
}
|
102 |
+
|
103 |
/**
|
104 |
* Detect whether the quote is associated with a registered customer
|
105 |
*
|
208 |
* Retrieves an image URL for the product, if it exists.
|
209 |
* The priority is: thumbnail -> small image -> image -> Magento's placeholder.
|
210 |
*
|
211 |
+
* @param Mage_Sales_Model_Quote_Item $item
|
212 |
* @return string the image's URL
|
213 |
*/
|
214 |
+
public function getProductImageUrl (Mage_Sales_Model_Quote_Item $item)
|
215 |
{
|
216 |
+
$product = $this->getProductFromQuoteItem($item);
|
217 |
|
218 |
$imageSize = Mage::getStoreConfig(self::XML_PATH_IMAGE_SIZE);
|
219 |
if (!$imageSize) {
|
240 |
* @param string $productId
|
241 |
* @return multitype:
|
242 |
*/
|
243 |
+
public function getProductFromQuoteItem(Mage_Sales_Model_Quote_Item $item)
|
244 |
{
|
245 |
+
$productId = $item->getProductId();
|
246 |
if (!isset($this->_loadedProducts[$productId])) {
|
247 |
+
$this->_loadedProducts[$productId] = $item->getProduct();
|
248 |
}
|
249 |
|
250 |
return $this->_loadedProducts[$productId];
|
279 |
* @param $storeId
|
280 |
* @param Emv_CartAlert_Model_Abandonment $abandonment
|
281 |
* @param Mage_Core_Model_Email_Template
|
282 |
+
* @param boolean $updateStats
|
283 |
*/
|
284 |
public function sendReminder(
|
285 |
Mage_Sales_Model_Quote $abandonedCart,
|
286 |
$storeId,
|
287 |
+
Emv_CartAlert_Model_Abandonment $abandonment,
|
288 |
+
$updateStats = true
|
289 |
) {
|
290 |
// determine which template should be used
|
291 |
$reminderId = false;
|
326 |
Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_ALERT_SENDER_IDENTITY, $storeId),
|
327 |
$abandonedCart->getCustomerEmail(),
|
328 |
$abandonedCart->getPreparedCustomerName(),
|
329 |
+
array('cart' => $abandonedCart, 'promo_code' => $abandonment->getCouponCode()),
|
330 |
$storeId
|
331 |
);
|
332 |
|
333 |
+
if ($updateStats) {
|
334 |
+
// update reminder statistic
|
335 |
+
$this->updateStats($reminderId, $abandonedCart->getId(), $storeId);
|
336 |
+
}
|
337 |
}
|
338 |
}
|
339 |
|
340 |
+
/**
|
341 |
+
* Prepare necessary information and send an appropriate reminder for a given quote.
|
342 |
+
* If $updateStats is equal to true, we update the reminder sending statistics
|
343 |
+
*
|
344 |
+
* @param string $reminderTemplate (which reminder to send - first, second or third)
|
345 |
+
* @param Mage_Sales_Model_Quote $quote
|
346 |
+
* @param Emv_CartAlert_Model_Abandonment $abandonment
|
347 |
+
* @param boolean $updateStats
|
348 |
+
*/
|
349 |
+
public function prepareAndSendReminder($reminderTemplate,
|
350 |
+
Mage_Sales_Model_Quote $quote,
|
351 |
+
Emv_CartAlert_Model_Abandonment $abandonment,
|
352 |
+
$updateStats = true
|
353 |
+
)
|
354 |
+
{
|
355 |
+
$preparedCustomerName = ($quote->getCustomerPrefix() ? $quote->getCustomerPrefix() . ' ' : '')
|
356 |
+
. $quote->getCustomerFirstname()
|
357 |
+
. ' ' . ($quote->getCustomerMiddlename() ? $quote->getCustomerMiddlename() . ' ' : '')
|
358 |
+
. $quote->getCustomerLastname()
|
359 |
+
. ($quote->getCustomerSuffix() ? ' ' . $quote->getCustomerSuffix() : '')
|
360 |
+
;
|
361 |
+
$quote->setPreparedCustomerName($preparedCustomerName);
|
362 |
+
|
363 |
+
// set the unsubscription link (depends on whether the user was logged in)
|
364 |
+
$quote->setUnsubLink($this->getUnsubscribeLink($quote));
|
365 |
+
// set the cart link (depends on whether the user was logged in)
|
366 |
+
$quote->setCartLink($this->getCartLink($quote, $reminderTemplate));
|
367 |
+
// set the store link (depends on whether the user was logged in)
|
368 |
+
$quote->setStoreLink($this->getStoreLink($quote, $reminderTemplate));
|
369 |
+
// set the reminder template will be used to send
|
370 |
+
$quote->setReminderTemplate($reminderTemplate);
|
371 |
+
|
372 |
+
// set formated grand total
|
373 |
+
$quote->setPreparedGrandToTal(Mage::helper('checkout')->formatPrice($quote->getGrandTotal(), true, true));
|
374 |
+
|
375 |
+
$this->sendReminder($quote, $quote->getStoreId(), $abandonment, $updateStats);
|
376 |
+
}
|
377 |
+
|
378 |
/**
|
379 |
* Update statistic information about the reminder sending
|
380 |
+
*
|
381 |
* @param int $reminderId
|
382 |
* @param int $quoteId
|
383 |
* @param int $storeId
|
538 |
return $code;
|
539 |
}
|
540 |
|
541 |
+
/**
|
542 |
+
* Remove the last save reminder template for a give quote
|
543 |
+
* so that the abandoned cart reminder processus can restart again
|
544 |
+
*
|
545 |
+
* @param Mage_Sales_Model_Quote $quote
|
546 |
+
*/
|
547 |
+
public function resetReminderForQuote(Mage_Sales_Model_Quote $quote)
|
548 |
+
{
|
549 |
+
$gmtDate = Mage::getModel('core/date')->gmtDate();
|
550 |
+
|
551 |
+
$resource = Mage::getModel('core/resource');
|
552 |
+
$writeConnection = $resource->getConnection(Mage_Core_Model_Resource::DEFAULT_WRITE_RESOURCE);
|
553 |
+
|
554 |
+
$query = "
|
555 |
+
UPDATE {$resource->getTableName('abandonment/abandonment')}
|
556 |
+
SET updated_at = '$gmtDate', template = NULL
|
557 |
+
";
|
558 |
+
$query .= $writeConnection->quoteInto(' WHERE entity_id = ?', $quote->getId());
|
559 |
+
|
560 |
+
if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_ENABLED)) {
|
561 |
+
$query .= $writeConnection->quoteInto(' AND template = ?', Emv_CartAlert_Constants::THIRD_ALERT_FLAG);
|
562 |
+
} else if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_ENABLED)) {
|
563 |
+
$query .= $writeConnection->quoteInto(' AND template = ?', Emv_CartAlert_Constants::SECOND_ALERT_FLAG);
|
564 |
+
} else if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_ENABLED)) {
|
565 |
+
$query .= $writeConnection->quoteInto(' AND template = ?', Emv_CartAlert_Constants::FIRST_ALERT_FLAG);
|
566 |
+
}
|
567 |
+
$writeConnection->query($query);
|
568 |
+
}
|
569 |
+
|
570 |
+
/**
|
571 |
+
* Get available reminder labels
|
572 |
+
*
|
573 |
+
* @return array
|
574 |
+
*/
|
575 |
+
public function getReminderLables()
|
576 |
+
{
|
577 |
+
return array(
|
578 |
+
Emv_CartAlert_Constants::NONE_FLAG => Mage::helper('abandonment')->__('None'),
|
579 |
+
Emv_CartAlert_Constants::FIRST_ALERT_FLAG => Mage::helper('abandonment')->__('First Reminder'),
|
580 |
+
Emv_CartAlert_Constants::SECOND_ALERT_FLAG => Mage::helper('abandonment')->__('Second Reminder'),
|
581 |
+
Emv_CartAlert_Constants::THIRD_ALERT_FLAG => Mage::helper('abandonment')->__('Third Reminder')
|
582 |
+
);
|
583 |
+
}
|
584 |
+
|
585 |
/**
|
586 |
* Support functions - Used for debugging purposes
|
587 |
*/
|
@@ -5,15 +5,59 @@
|
|
5 |
*
|
6 |
* @category Emv
|
7 |
* @package Emv_CartAlert
|
|
|
8 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
9 |
*/
|
10 |
class Emv_CartAlert_Model_Observer extends Mage_Core_Model_Abstract
|
11 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
/**
|
13 |
* Get abandoned quotes to send reminders
|
|
|
|
|
|
|
14 |
* @return Mage_Sales_Model_Mysql4_Quote_Collection
|
15 |
*/
|
16 |
-
protected function _getConcernedQuotes()
|
17 |
{
|
18 |
// prepare query for abandoned quotes
|
19 |
$minHour = Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_DELAY);
|
@@ -23,27 +67,44 @@ class Emv_CartAlert_Model_Observer extends Mage_Core_Model_Abstract
|
|
23 |
|
24 |
/* @var $date Zend_Date */
|
25 |
$from = Mage::app()->getLocale()->utcDate(null, $now);
|
26 |
-
|
|
|
|
|
|
|
|
|
|
|
27 |
$from = $from->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
|
28 |
|
29 |
// the expiration date
|
30 |
$expDate = Mage::app()->getLocale()->utcDate(null, $now);
|
31 |
-
$expDate->sub(Emv_CartAlert_Constants::
|
32 |
$expDate = $expDate->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
|
33 |
|
34 |
// get abandoned quotes
|
35 |
/* @var $quotes Mage_Sales_Model_Mysql4_Quote_Collection */
|
36 |
$quotes = Mage::getModel('sales/quote')->getCollection();
|
37 |
$select = $quotes->getSelect();
|
38 |
-
|
|
|
|
|
|
|
|
|
39 |
$select->joinLeft(
|
40 |
array('a' => $quotes->getTable('abandonment/abandonment')),
|
41 |
'main_table.entity_id = a.entity_id',
|
42 |
-
array(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
);
|
44 |
|
45 |
-
//get customers' abandonment_subscribed value
|
46 |
-
$attr =
|
47 |
$adapter = $quotes->getConnection();
|
48 |
if ($attr->getAttributeId()) {
|
49 |
$select->joinLeft(
|
@@ -53,45 +114,87 @@ class Emv_CartAlert_Model_Observer extends Mage_Core_Model_Abstract
|
|
53 |
. ' AND abandonment_subscribed.attribute_id = ?',
|
54 |
$attr->getAttributeId()
|
55 |
),
|
56 |
-
// by default, we activate abandonment reminder
|
57 |
-
array(
|
|
|
|
|
|
|
58 |
);
|
59 |
}
|
60 |
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
->where('a.template <> ? OR a.template IS NULL', Emv_CartAlert_Constants::OUTDATED_FLAG)
|
63 |
->where('a.template <> ? OR a.template IS NULL', Emv_CartAlert_Constants::THIRD_ALERT_FLAG)
|
64 |
;
|
65 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
66 |
$quotes
|
67 |
-
->addFieldToFilter('updated_at', array('to' => $from, 'from' => $expDate))
|
68 |
-
->addFieldToFilter('items_count', array('gt' => 0))
|
69 |
->addFieldToFilter('customer_email', array('notnull' => 1)) // a quote with a valid email address
|
70 |
->addFieldToFilter('is_active', 1) // only get active quotes
|
71 |
-
->setOrder('updated_at')
|
72 |
;
|
73 |
|
74 |
return $quotes;
|
75 |
}
|
76 |
|
77 |
/**
|
78 |
-
*
|
|
|
|
|
79 |
*/
|
80 |
-
public function
|
81 |
{
|
82 |
-
|
83 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
84 |
|
85 |
-
// if
|
86 |
-
if(
|
87 |
-
|
88 |
-
|
89 |
-
|| Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_ENABLED) == 1
|
90 |
-
) {
|
91 |
-
/* @var $helper Emv_CartAlert_Helper_Data */
|
92 |
-
$helper = Mage::helper('abandonment');
|
93 |
|
94 |
-
$quotes = $this->_getConcernedQuotes();
|
95 |
/* @var $quote Mage_Sales_Model_Quote */
|
96 |
foreach ($quotes as $quote) {
|
97 |
// Set the current store
|
@@ -101,7 +204,7 @@ class Emv_CartAlert_Model_Observer extends Mage_Core_Model_Abstract
|
|
101 |
$needToSaveAbandonment = false;
|
102 |
|
103 |
// search abandoned carts for this particular quote
|
104 |
-
$abandonment =
|
105 |
|
106 |
if (!$abandonment->getId()) {
|
107 |
$abandonment->setEntityId($quote->getId())
|
@@ -127,53 +230,115 @@ class Emv_CartAlert_Model_Observer extends Mage_Core_Model_Abstract
|
|
127 |
);
|
128 |
|
129 |
if ($updatedTemplate != null) {
|
130 |
-
$preparedCustomerName = ($quote->getCustomerPrefix() ? $quote->getCustomerPrefix() . ' ' : '')
|
131 |
-
. $quote->getCustomerFirstname()
|
132 |
-
. ' ' . ($quote->getCustomerMiddlename() ? $quote->getCustomerMiddlename() . ' ' : '')
|
133 |
-
. $quote->getCustomerLastname()
|
134 |
-
. ($quote->getCustomerSuffix() ? ' ' . $quote->getCustomerSuffix() : '')
|
135 |
-
;
|
136 |
-
$quote->setPreparedCustomerName($preparedCustomerName);
|
137 |
-
|
138 |
-
// set the unsubscription link (depends on whether the user was logged in)
|
139 |
-
$quote->setUnsubLink($helper->getUnsubscribeLink($quote));
|
140 |
-
// set the cart link (depends on whether the user was logged in)
|
141 |
-
$quote->setCartLink($helper->getCartLink($quote, $updatedTemplate));
|
142 |
-
// set the store link (depends on whether the user was logged in)
|
143 |
-
$quote->setStoreLink($helper->getStoreLink($quote, $updatedTemplate));
|
144 |
-
// set the reminder template will be used to send
|
145 |
-
$quote->setReminderTemplate($updatedTemplate);
|
146 |
-
|
147 |
-
// set formated grand total
|
148 |
-
$quote->setPreparedGrandToTal(Mage::helper('checkout')->formatPrice($quote->getGrandTotal(), true, true));
|
149 |
-
|
150 |
if ($previousTemplate != $updatedTemplate) {
|
151 |
// update the reminder template will be used to send
|
152 |
$abandonment->setTemplate($updatedTemplate);
|
153 |
|
|
|
154 |
$rule = $helper->getShoppingCartPriceRule();
|
155 |
if ($rule->getId() != $abandonment->getShoppingCartRuleId()) {
|
156 |
$abandonment->setShoppingCartRuleId($rule->getId());
|
157 |
$abandonment->setCouponCode($helper->getCouponCode($rule->getId()));
|
158 |
}
|
159 |
-
|
160 |
$needToSaveAbandonment = true;
|
161 |
}
|
162 |
|
163 |
-
$helper->
|
164 |
}
|
165 |
}
|
166 |
|
167 |
if ($needToSaveAbandonment) {
|
|
|
|
|
168 |
$abandonment->save();
|
169 |
}
|
170 |
}
|
171 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
|
173 |
// return the store to normal
|
174 |
Mage::app()->setCurrentStore($currentStore);
|
175 |
}
|
176 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
177 |
/**
|
178 |
* Indicate which reminder template can be used to send.
|
179 |
* Return null if we can't send the reminder else the reminder name
|
@@ -199,7 +364,7 @@ class Emv_CartAlert_Model_Observer extends Mage_Core_Model_Abstract
|
|
199 |
|
200 |
// expiration date
|
201 |
$expirationDate = $locale->utcDate(null, $now);
|
202 |
-
$expirationDate->subHour(Emv_CartAlert_Constants::
|
203 |
|
204 |
if ($expirationDate->isLater($lastUpdate)) {
|
205 |
$updatedTemplate = Emv_CartAlert_Constants::OUTDATED_FLAG;
|
@@ -210,23 +375,41 @@ class Emv_CartAlert_Model_Observer extends Mage_Core_Model_Abstract
|
|
210 |
|
211 |
if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_ENABLED, $store)) {
|
212 |
$firstAlertDelay = $locale->utcDate(null, $now);
|
213 |
-
$
|
214 |
-
|
215 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
216 |
}
|
217 |
|
218 |
if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_ENABLED, $store)) {
|
219 |
$secondAlertDelay = $locale->utcDate(null, $now);
|
220 |
-
$
|
221 |
-
|
222 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
}
|
224 |
|
225 |
if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_ENABLED, $store)) {
|
226 |
$thirdAlertDelay = $locale->utcDate(null, $now);
|
227 |
-
$
|
228 |
-
|
229 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
}
|
231 |
|
232 |
// determine which reminder (first, second, third) needs to be sent
|
@@ -307,4 +490,29 @@ class Emv_CartAlert_Model_Observer extends Mage_Core_Model_Abstract
|
|
307 |
$session->unsetData('abandonment_flag');
|
308 |
$session->unsetData('abandonment_date');
|
309 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
310 |
}
|
5 |
*
|
6 |
* @category Emv
|
7 |
* @package Emv_CartAlert
|
8 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
9 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
10 |
*/
|
11 |
class Emv_CartAlert_Model_Observer extends Mage_Core_Model_Abstract
|
12 |
{
|
13 |
+
protected $_testMode = null;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var Mage_Customer_Model_Entity_Attribute
|
17 |
+
*/
|
18 |
+
protected $_subscribeAttribute = null;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var array
|
22 |
+
*/
|
23 |
+
protected $_reminderTypes = array('first', 'second', 'third');
|
24 |
+
|
25 |
+
/**
|
26 |
+
* @return boolean
|
27 |
+
*/
|
28 |
+
public function getTestMode()
|
29 |
+
{
|
30 |
+
if ($this->_testMode === null) {
|
31 |
+
$this->_testMode = (bool)Mage::getStoreConfig(
|
32 |
+
Emv_CartAlert_Constants::XML_PATH_TEST_MODE_ENABLED,
|
33 |
+
Mage_Core_Model_App::ADMIN_STORE_ID
|
34 |
+
);
|
35 |
+
}
|
36 |
+
|
37 |
+
return $this->_testMode;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Get abandonment_subscribed attribute
|
42 |
+
* @return Mage_Customer_Model_Entity_Attribute | null
|
43 |
+
*/
|
44 |
+
protected function _getSubscribeAttribute()
|
45 |
+
{
|
46 |
+
if (!$this->_subscribeAttribute) {
|
47 |
+
// get customers' abandonment_subscribed value
|
48 |
+
$this->_subscribeAttribute = Mage::getModel('customer/customer')->getAttribute('abandonment_subscribed');
|
49 |
+
}
|
50 |
+
return $this->_subscribeAttribute;
|
51 |
+
}
|
52 |
+
|
53 |
/**
|
54 |
* Get abandoned quotes to send reminders
|
55 |
+
*
|
56 |
+
* @param int $limit
|
57 |
+
* @param string $type reminder type
|
58 |
* @return Mage_Sales_Model_Mysql4_Quote_Collection
|
59 |
*/
|
60 |
+
protected function _getConcernedQuotes($limit, $type)
|
61 |
{
|
62 |
// prepare query for abandoned quotes
|
63 |
$minHour = Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_DELAY);
|
67 |
|
68 |
/* @var $date Zend_Date */
|
69 |
$from = Mage::app()->getLocale()->utcDate(null, $now);
|
70 |
+
|
71 |
+
if ($this->getTestMode()) {
|
72 |
+
$from->subMinute($minHour);
|
73 |
+
} else {
|
74 |
+
$from->subHour($minHour);
|
75 |
+
}
|
76 |
$from = $from->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
|
77 |
|
78 |
// the expiration date
|
79 |
$expDate = Mage::app()->getLocale()->utcDate(null, $now);
|
80 |
+
$expDate->sub(Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_LIFETIME), Zend_Date::HOUR);
|
81 |
$expDate = $expDate->toString(Varien_Date::DATETIME_INTERNAL_FORMAT);
|
82 |
|
83 |
// get abandoned quotes
|
84 |
/* @var $quotes Mage_Sales_Model_Mysql4_Quote_Collection */
|
85 |
$quotes = Mage::getModel('sales/quote')->getCollection();
|
86 |
$select = $quotes->getSelect();
|
87 |
+
|
88 |
+
// set the limit
|
89 |
+
$select->limit($limit);
|
90 |
+
|
91 |
+
// make a left join to abandonment table get all data
|
92 |
$select->joinLeft(
|
93 |
array('a' => $quotes->getTable('abandonment/abandonment')),
|
94 |
'main_table.entity_id = a.entity_id',
|
95 |
+
array(
|
96 |
+
'abandonment_id',
|
97 |
+
'abandonment_entity_id' => 'a.entity_id',
|
98 |
+
'abandonment_template' => 'a.template',
|
99 |
+
'abandonment_customer_abandonment_subscribed' => 'a.customer_abandonment_subscribed',
|
100 |
+
'abandonment_customer_id' => 'a.customer_id',
|
101 |
+
'abandonment_shopping_cart_rule_id' => 'a.shopping_cart_rule_id',
|
102 |
+
'abandonment_coupon_code' => 'a.coupon_code'
|
103 |
+
)
|
104 |
);
|
105 |
|
106 |
+
// get customers' abandonment_subscribed value
|
107 |
+
$attr = $this->_getSubscribeAttribute();
|
108 |
$adapter = $quotes->getConnection();
|
109 |
if ($attr->getAttributeId()) {
|
110 |
$select->joinLeft(
|
114 |
. ' AND abandonment_subscribed.attribute_id = ?',
|
115 |
$attr->getAttributeId()
|
116 |
),
|
117 |
+
// by default, we activate abandonment reminder for all clients
|
118 |
+
array(
|
119 |
+
'abandonment_subscribed_value'
|
120 |
+
=> 'IF(abandonment_subscribed.value IS NULL, 1, abandonment_subscribed.value)'
|
121 |
+
)
|
122 |
);
|
123 |
}
|
124 |
|
125 |
+
// only get the carts which
|
126 |
+
// 1. their users allow to receive the reminders
|
127 |
+
// 2. are not too late
|
128 |
+
// 3. have not received the third reminders yet
|
129 |
+
$select
|
130 |
+
->where('
|
131 |
+
(
|
132 |
+
main_table.customer_id IS NOT NULL
|
133 |
+
AND (abandonment_subscribed.value = 1 OR abandonment_subscribed.value IS NULL)
|
134 |
+
)
|
135 |
+
OR (
|
136 |
+
main_table.customer_id IS NULL
|
137 |
+
AND (a.customer_abandonment_subscribed = 1 OR a.customer_abandonment_subscribed IS NULL)
|
138 |
+
)
|
139 |
+
')
|
140 |
->where('a.template <> ? OR a.template IS NULL', Emv_CartAlert_Constants::OUTDATED_FLAG)
|
141 |
->where('a.template <> ? OR a.template IS NULL', Emv_CartAlert_Constants::THIRD_ALERT_FLAG)
|
142 |
;
|
143 |
|
144 |
+
switch ($type) {
|
145 |
+
case 'first' :
|
146 |
+
$select->where(
|
147 |
+
'a.template IS NULL OR a.template = "" OR a.template = ?',
|
148 |
+
Emv_CartAlert_Constants::TO_BE_PROCESSED_FLAG
|
149 |
+
);
|
150 |
+
break;
|
151 |
+
case 'second' :
|
152 |
+
$select->where('a.template = ?', Emv_CartAlert_Constants::FIRST_ALERT_FLAG);
|
153 |
+
break;
|
154 |
+
case 'third' :
|
155 |
+
$select->where('a.template = ?', Emv_CartAlert_Constants::SECOND_ALERT_FLAG);
|
156 |
+
break;
|
157 |
+
}
|
158 |
+
|
159 |
$quotes
|
160 |
+
->addFieldToFilter('main_table.updated_at', array('to' => $from, 'from' => $expDate))
|
161 |
+
->addFieldToFilter('items_count', array('gt' => 0)) // have at least 1 item
|
162 |
->addFieldToFilter('customer_email', array('notnull' => 1)) // a quote with a valid email address
|
163 |
->addFieldToFilter('is_active', 1) // only get active quotes
|
164 |
+
->setOrder('updated_at', Varien_Data_Collection::SORT_ORDER_ASC) // sort the carts from older to newer
|
165 |
;
|
166 |
|
167 |
return $quotes;
|
168 |
}
|
169 |
|
170 |
/**
|
171 |
+
* Process the abandonned carts for a given type reminder
|
172 |
+
* @param int $limit
|
173 |
+
* @param string $type reminder type (first, second, third)
|
174 |
*/
|
175 |
+
public function processAbandonedCartsForType($limit, $type)
|
176 |
{
|
177 |
+
/* @var $helper Emv_CartAlert_Helper_Data */
|
178 |
+
$helper = Mage::helper('abandonment');
|
179 |
+
|
180 |
+
$pathConfig;
|
181 |
+
switch ($type) {
|
182 |
+
case 'first' :
|
183 |
+
$pathConfig = Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_ENABLED;
|
184 |
+
break;
|
185 |
+
case 'second' :
|
186 |
+
$pathConfig = Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_ENABLED;
|
187 |
+
break;
|
188 |
+
case 'third' :
|
189 |
+
$pathConfig = Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_ENABLED;
|
190 |
+
break;
|
191 |
+
}
|
192 |
|
193 |
+
// check if this reminder is activated
|
194 |
+
if (Mage::getStoreConfig($pathConfig) == 1) {
|
195 |
+
// get all quotes that can be sent for this reminder
|
196 |
+
$quotes = $this->_getConcernedQuotes($limit, $type);
|
|
|
|
|
|
|
|
|
197 |
|
|
|
198 |
/* @var $quote Mage_Sales_Model_Quote */
|
199 |
foreach ($quotes as $quote) {
|
200 |
// Set the current store
|
204 |
$needToSaveAbandonment = false;
|
205 |
|
206 |
// search abandoned carts for this particular quote
|
207 |
+
$abandonment = $this->_prepareAbandonmentObjectFromQuote($quote);
|
208 |
|
209 |
if (!$abandonment->getId()) {
|
210 |
$abandonment->setEntityId($quote->getId())
|
230 |
);
|
231 |
|
232 |
if ($updatedTemplate != null) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
if ($previousTemplate != $updatedTemplate) {
|
234 |
// update the reminder template will be used to send
|
235 |
$abandonment->setTemplate($updatedTemplate);
|
236 |
|
237 |
+
// if we change the promotion shopping cart rule, we need to change the coupon code
|
238 |
$rule = $helper->getShoppingCartPriceRule();
|
239 |
if ($rule->getId() != $abandonment->getShoppingCartRuleId()) {
|
240 |
$abandonment->setShoppingCartRuleId($rule->getId());
|
241 |
$abandonment->setCouponCode($helper->getCouponCode($rule->getId()));
|
242 |
}
|
|
|
243 |
$needToSaveAbandonment = true;
|
244 |
}
|
245 |
|
246 |
+
$helper->prepareAndSendReminder($updatedTemplate, $quote, $abandonment, true);
|
247 |
}
|
248 |
}
|
249 |
|
250 |
if ($needToSaveAbandonment) {
|
251 |
+
$gmtDate = Mage::getModel('core/date')->gmtDate();
|
252 |
+
$abandonment->setUpdatedAt($gmtDate);
|
253 |
$abandonment->save();
|
254 |
}
|
255 |
}
|
256 |
}
|
257 |
+
}
|
258 |
+
|
259 |
+
/**
|
260 |
+
* Observer to check for abandoned shopping carts
|
261 |
+
*/
|
262 |
+
public function processAbandonedCarts ()
|
263 |
+
{
|
264 |
+
/* @var $helper Emv_CartAlert_Helper_Data */
|
265 |
+
$helper = Mage::helper('abandonment');
|
266 |
+
$createdLock = false;
|
267 |
+
|
268 |
+
// save the current store so that this observer doesn't interfere with any other functions
|
269 |
+
$currentStore = Mage::app()->getStore()->getStoreId();
|
270 |
+
// !!! it's very important to set a custom error handler in order to remove lock file in case of fatal error
|
271 |
+
Mage::helper('emvcore')->setSmartFocusErrorHandler();
|
272 |
+
|
273 |
+
try {
|
274 |
+
// check if another process is being run now
|
275 |
+
if (!$helper->checkLockFile()) {
|
276 |
+
// create lock file => do not allow several process at the same time
|
277 |
+
$helper->createLockFile();
|
278 |
+
$createdLock = true;
|
279 |
+
|
280 |
+
$limit = $helper->getCartLimitForOneRun();
|
281 |
+
$activatedTypes = 0;
|
282 |
+
if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_ENABLED) == 1) {
|
283 |
+
$activatedTypes++;
|
284 |
+
}
|
285 |
+
if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_ENABLED) == 1) {
|
286 |
+
$activatedTypes++;
|
287 |
+
}
|
288 |
+
if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_ENABLED) == 1) {
|
289 |
+
$activatedTypes++;
|
290 |
+
}
|
291 |
+
$limitPerType = $limit;
|
292 |
+
if ($activatedTypes > 0) {
|
293 |
+
$limitPerType = (int)$limit / $activatedTypes;
|
294 |
+
}
|
295 |
+
|
296 |
+
foreach($this->_reminderTypes as $type) {
|
297 |
+
$this->processAbandonedCartsForType($limitPerType, $type);
|
298 |
+
// return the store to normal
|
299 |
+
Mage::app()->setCurrentStore($currentStore);
|
300 |
+
}
|
301 |
+
}
|
302 |
+
} catch (Exception $e) {
|
303 |
+
Mage::logException($e);
|
304 |
+
}
|
305 |
+
|
306 |
+
// if lock is created, need to delete it
|
307 |
+
if ($createdLock) {
|
308 |
+
try {
|
309 |
+
$helper->removeLockFile();
|
310 |
+
} catch (Exception $e) {
|
311 |
+
Mage::logException($e);
|
312 |
+
}
|
313 |
+
}
|
314 |
+
|
315 |
+
// reset error handler to Magento one
|
316 |
+
Mage::helper('emvcore')->resetErrorHandler();
|
317 |
|
318 |
// return the store to normal
|
319 |
Mage::app()->setCurrentStore($currentStore);
|
320 |
}
|
321 |
|
322 |
+
/**
|
323 |
+
* Prepare abandonment object from quote retrieved from last query select
|
324 |
+
*
|
325 |
+
* @param Varien_Object $quote
|
326 |
+
* @return Emv_CartAlert_Model_Abandonment
|
327 |
+
*/
|
328 |
+
protected function _prepareAbandonmentObjectFromQuote(Varien_Object $quote)
|
329 |
+
{
|
330 |
+
$abandonment = Mage::getModel('abandonment/abandonment');
|
331 |
+
$abandonment->setData('abandonment_id', $quote->getData('abandonment_id'));
|
332 |
+
$abandonment->setData('entity_id', $quote->getData('abandonment_entity_id'));
|
333 |
+
$abandonment->setData('template', $quote->getData('abandonment_template'));
|
334 |
+
$abandonment->setData('customer_abandonment_subscribed', $quote->getData('abandonment_customer_abandonment_subscribed'));
|
335 |
+
$abandonment->setData('customer_id', $quote->getData('abandonment_customer_id'));
|
336 |
+
$abandonment->setData('shopping_cart_rule_id', $quote->getData('abandonment_shopping_cart_rule_id'));
|
337 |
+
$abandonment->setData('coupon_code', $quote->getData('abandonment_coupon_code'));
|
338 |
+
|
339 |
+
return $abandonment;
|
340 |
+
}
|
341 |
+
|
342 |
/**
|
343 |
* Indicate which reminder template can be used to send.
|
344 |
* Return null if we can't send the reminder else the reminder name
|
364 |
|
365 |
// expiration date
|
366 |
$expirationDate = $locale->utcDate(null, $now);
|
367 |
+
$expirationDate->subHour(Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_LIFETIME));
|
368 |
|
369 |
if ($expirationDate->isLater($lastUpdate)) {
|
370 |
$updatedTemplate = Emv_CartAlert_Constants::OUTDATED_FLAG;
|
375 |
|
376 |
if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_ENABLED, $store)) {
|
377 |
$firstAlertDelay = $locale->utcDate(null, $now);
|
378 |
+
if ($this->getTestMode()) {
|
379 |
+
$firstAlertDelay->subMinute(
|
380 |
+
Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_DELAY, $store)
|
381 |
+
);
|
382 |
+
} else {
|
383 |
+
$firstAlertDelay->subHour(
|
384 |
+
Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_FIRST_ALERT_DELAY, $store)
|
385 |
+
);
|
386 |
+
}
|
387 |
}
|
388 |
|
389 |
if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_ENABLED, $store)) {
|
390 |
$secondAlertDelay = $locale->utcDate(null, $now);
|
391 |
+
if ($this->getTestMode()) {
|
392 |
+
$secondAlertDelay->subMinute(
|
393 |
+
Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_DELAY, $store)
|
394 |
+
);
|
395 |
+
} else {
|
396 |
+
$secondAlertDelay->subHour(
|
397 |
+
Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_SECOND_ALERT_DELAY, $store)
|
398 |
+
);
|
399 |
+
}
|
400 |
}
|
401 |
|
402 |
if (Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_ENABLED, $store)) {
|
403 |
$thirdAlertDelay = $locale->utcDate(null, $now);
|
404 |
+
if ($this->getTestMode()) {
|
405 |
+
$thirdAlertDelay->subMinute(
|
406 |
+
Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_DELAY, $store)
|
407 |
+
);
|
408 |
+
} else {
|
409 |
+
$thirdAlertDelay->subHour(
|
410 |
+
Mage::getStoreConfig(Emv_CartAlert_Constants::XML_PATH_THIRD_ALERT_DELAY, $store)
|
411 |
+
);
|
412 |
+
}
|
413 |
}
|
414 |
|
415 |
// determine which reminder (first, second, third) needs to be sent
|
490 |
$session->unsetData('abandonment_flag');
|
491 |
$session->unsetData('abandonment_date');
|
492 |
}
|
493 |
+
|
494 |
+
/**
|
495 |
+
* Handle Quote save after event - reset the reminder template for a registered customer
|
496 |
+
* so that he can receive a new reminder
|
497 |
+
* @param Varien_Event_Observer $observer
|
498 |
+
*/
|
499 |
+
public function handleQuoteSaveAfter(Varien_Event_Observer $observer)
|
500 |
+
{
|
501 |
+
/* @var $order Mage_Sales_Model_Quote */
|
502 |
+
$quote = $observer->getEvent()->getQuote();
|
503 |
+
if ($quote instanceof Mage_Sales_Model_Quote) {
|
504 |
+
$session = Mage::getSingleton('customer/session');
|
505 |
+
// if customer is logged in and he has some products inside cart
|
506 |
+
if ($session->isLoggedIn() && $quote->getItemsCount() && $quote->getId()) {
|
507 |
+
if (!$session->getData('abandonment_reset_flag')) {
|
508 |
+
try {
|
509 |
+
Mage::helper('abandonment')->resetReminderForQuote($quote);
|
510 |
+
} catch (Exception $e) {
|
511 |
+
Mage::logException($e);
|
512 |
+
}
|
513 |
+
$session->setData('abandonment_reset_flag', 1);
|
514 |
+
}
|
515 |
+
}
|
516 |
+
}
|
517 |
+
}
|
518 |
}
|
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Abandoned Cart Reminder controller
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_CartAlert
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
+
*/
|
10 |
+
class Emv_CartAlert_Adminhtml_AbandonmentController extends Mage_Adminhtml_Controller_Action
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Initialise action
|
14 |
+
* - load all layout
|
15 |
+
* - set active menu SmartFocus
|
16 |
+
*/
|
17 |
+
protected function _initAction()
|
18 |
+
{
|
19 |
+
$this->loadLayout();
|
20 |
+
$this->_setActiveMenu('emailvision/abandonment');
|
21 |
+
// Define module dependent translate
|
22 |
+
$this->setUsedModuleName('Emv_CartAlert');
|
23 |
+
$this->_title(Mage::helper('abandonment')->__('SmartFocus'))
|
24 |
+
->_title(Mage::helper('abandonment')->__('Abandoned Cart Reminders'));
|
25 |
+
}
|
26 |
+
|
27 |
+
/**
|
28 |
+
* Check menu access
|
29 |
+
*
|
30 |
+
* (non-PHPdoc)
|
31 |
+
* @see Mage_Adminhtml_Controller_Action::_isAllowed()
|
32 |
+
*/
|
33 |
+
protected function _isAllowed()
|
34 |
+
{
|
35 |
+
return Mage::getSingleton('admin/session')->isAllowed('emailvision/abandonment/list');
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Abandoned Cart Reminder List
|
40 |
+
*/
|
41 |
+
public function listAction()
|
42 |
+
{
|
43 |
+
if ($this->getRequest()->getParam('ajax')) {
|
44 |
+
$this->_forward('grid');
|
45 |
+
return;
|
46 |
+
}
|
47 |
+
|
48 |
+
// save all messages from session
|
49 |
+
$this->getLayout()->getMessagesBlock()->setMessages(
|
50 |
+
$this->_getSession()->getMessages()
|
51 |
+
);
|
52 |
+
|
53 |
+
$this->_initAction();
|
54 |
+
$this->_addContent(
|
55 |
+
$this->getLayout()->createBlock('abandonment/adminhtml_list','list')
|
56 |
+
);
|
57 |
+
$this->renderLayout();
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Abandoned Cart Reminder Grid (for ajax query)
|
62 |
+
*/
|
63 |
+
public function gridAction()
|
64 |
+
{
|
65 |
+
$this->loadLayout();
|
66 |
+
$this->getResponse()->setBody(
|
67 |
+
$this->getLayout()->createBlock('abandonment/adminhtml_list_grid')->toHtml()
|
68 |
+
);
|
69 |
+
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Display product information in a given quote
|
73 |
+
*/
|
74 |
+
public function displayQuoteAction()
|
75 |
+
{
|
76 |
+
$quoteId = $this->getRequest()->getParam('quote');
|
77 |
+
if ($quoteId) {
|
78 |
+
$collection = Mage::getModel('sales/quote')->getCollection();
|
79 |
+
$collection->addFieldToFilter('entity_id', array('in' => array($quoteId)));
|
80 |
+
$quote = $collection->getFirstItem();
|
81 |
+
if ($quote && $quote->getId()) {
|
82 |
+
Mage::register('smartfocus_quote', $quote);
|
83 |
+
|
84 |
+
// save all messages from session
|
85 |
+
$this->getLayout()->getMessagesBlock()->setMessages(
|
86 |
+
$this->_getSession()->getMessages()
|
87 |
+
);
|
88 |
+
|
89 |
+
$this->_initAction();
|
90 |
+
|
91 |
+
$this->_addContent(
|
92 |
+
$this->getLayout()->createBlock('abandonment/adminhtml_quote','list')
|
93 |
+
);
|
94 |
+
$this->renderLayout();
|
95 |
+
}
|
96 |
+
}
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Test reminder - send a list of abandoned carts with a given reminder (first, second or third)
|
101 |
+
*/
|
102 |
+
public function testReminderAction()
|
103 |
+
{
|
104 |
+
$quoteIds = $this->getRequest()->getParam('quotes');
|
105 |
+
if (!is_array($quoteIds)) {
|
106 |
+
$this->_getSession()->addError(Mage::helper('emvcore')->__('Please select something!'));
|
107 |
+
} else {
|
108 |
+
$template = $this->getRequest()->getParam('template');
|
109 |
+
if ($template && in_array($template,
|
110 |
+
array(
|
111 |
+
Emv_CartAlert_Constants::FIRST_ALERT_FLAG,
|
112 |
+
Emv_CartAlert_Constants::SECOND_ALERT_FLAG,
|
113 |
+
Emv_CartAlert_Constants::THIRD_ALERT_FLAG
|
114 |
+
)
|
115 |
+
)
|
116 |
+
) {
|
117 |
+
// save the current store so that it doesn't interfere with any other functions
|
118 |
+
$currentStore = Mage::app()->getStore()->getStoreId();
|
119 |
+
|
120 |
+
/* @var $helper Emv_CartAlert_Helper_Data */
|
121 |
+
$helper = Mage::helper('abandonment');
|
122 |
+
$rule = $helper->getShoppingCartPriceRule();
|
123 |
+
|
124 |
+
$sent = 0;
|
125 |
+
$collection = Mage::getModel('sales/quote')->getCollection();
|
126 |
+
$collection->addFieldToFilter('entity_id', array('in' => array($quoteIds)));
|
127 |
+
foreach($collection as $quote) {
|
128 |
+
// Set the current store
|
129 |
+
Mage::app()->setCurrentStore($quote->getStoreId());
|
130 |
+
|
131 |
+
try {
|
132 |
+
$abandonment = Mage::getModel('abandonment/abandonment');
|
133 |
+
$abandonment->setShoppingCartRuleId($rule->getId());
|
134 |
+
$abandonment->setCouponCode($helper->getCouponCode($rule->getId()));
|
135 |
+
|
136 |
+
$helper->prepareAndSendReminder($template, $quote, $abandonment, false);
|
137 |
+
$sent ++;
|
138 |
+
} catch (Exception $e) {
|
139 |
+
$this->_getSession()->addError(
|
140 |
+
$helper->__(
|
141 |
+
'Cannot send reminder for cart #%s. Reason: %s',
|
142 |
+
$quote->getEntityId(), $e->getMessage()
|
143 |
+
)
|
144 |
+
);
|
145 |
+
}
|
146 |
+
}
|
147 |
+
|
148 |
+
// return the store to normal
|
149 |
+
Mage::app()->setCurrentStore($currentStore);
|
150 |
+
|
151 |
+
$reminderLabels = Mage::helper('abandonment')->getReminderLables();
|
152 |
+
$label = $template;
|
153 |
+
if (isset($reminderLabels[$template])) {
|
154 |
+
$label = $reminderLabels[$template];
|
155 |
+
}
|
156 |
+
if ($sent > 1) {
|
157 |
+
$this->_getSession()->addSuccess(
|
158 |
+
$helper->__('%s carts were successfully sent with %s', $sent, $label)
|
159 |
+
);
|
160 |
+
} elseif ($sent == 1) {
|
161 |
+
$this->_getSession()->addSuccess(
|
162 |
+
$helper->__('One cart was successfully sent with %s', $label)
|
163 |
+
);
|
164 |
+
}
|
165 |
+
}
|
166 |
+
}
|
167 |
+
|
168 |
+
// get back to abandoned cart reminder list
|
169 |
+
$this->_redirect('*/*/list');
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Export abandoned cart grid in csv file
|
174 |
+
*/
|
175 |
+
public function exportAbandonedCsvAction()
|
176 |
+
{
|
177 |
+
$fileName = 'abandoned_carts.csv';
|
178 |
+
$content = $this->getLayout()->createBlock('abandonment/adminhtml_list_grid')
|
179 |
+
->getCsvFile();
|
180 |
+
|
181 |
+
$this->_prepareDownloadResponse($fileName, $content);
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Export abandoned cart grid in excel file (xml)
|
186 |
+
*/
|
187 |
+
public function exportAbandonedExcelAction()
|
188 |
+
{
|
189 |
+
$fileName = 'abandoned_carts.xml';
|
190 |
+
$content = $this->getLayout()->createBlock('abandonment/adminhtml_list_grid')
|
191 |
+
->getExcelFile();
|
192 |
+
|
193 |
+
$this->_prepareDownloadResponse($fileName, $content);
|
194 |
+
}
|
195 |
+
}
|
@@ -1,9 +1,41 @@
|
|
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<config>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
<acl>
|
4 |
<resources>
|
5 |
<admin>
|
6 |
<children>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
<system>
|
8 |
<children>
|
9 |
<config>
|
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<config>
|
3 |
+
<menu>
|
4 |
+
<!-- EmailVision menu in the back office -->
|
5 |
+
<emailvision>
|
6 |
+
<children>
|
7 |
+
<abandonment translate="title" module="abandonment">
|
8 |
+
<title>Abandoned Carts</title>
|
9 |
+
<sort_order>50</sort_order>
|
10 |
+
<children>
|
11 |
+
<list translate="title" module="abandonment">
|
12 |
+
<title>List</title>
|
13 |
+
<sort_order>10</sort_order>
|
14 |
+
<action>abandonment/abandonment/list</action>
|
15 |
+
</list>
|
16 |
+
</children>
|
17 |
+
</abandonment>
|
18 |
+
</children>
|
19 |
+
</emailvision>
|
20 |
+
</menu>
|
21 |
+
|
22 |
<acl>
|
23 |
<resources>
|
24 |
<admin>
|
25 |
<children>
|
26 |
+
<emailvision>
|
27 |
+
<children>
|
28 |
+
<abandonment translate="title" module="abandonment">
|
29 |
+
<title>Abandonment Carts</title>
|
30 |
+
<children>
|
31 |
+
<list>
|
32 |
+
<title>List</title>
|
33 |
+
<sort_order>10</sort_order>
|
34 |
+
</list>
|
35 |
+
</children>
|
36 |
+
</abandonment>
|
37 |
+
</children>
|
38 |
+
</emailvision>
|
39 |
<system>
|
40 |
<children>
|
41 |
<config>
|
@@ -1,7 +1,7 @@
|
|
1 |
<config>
|
2 |
<modules>
|
3 |
<Emv_CartAlert>
|
4 |
-
<version>0.5.
|
5 |
</Emv_CartAlert>
|
6 |
</modules>
|
7 |
<global>
|
@@ -46,18 +46,18 @@
|
|
46 |
<template>
|
47 |
<email>
|
48 |
<abandonment_first_alert_config_template translate="label" module="abandonment">
|
49 |
-
<label>Abandoned Cart 1</label>
|
50 |
-
<file>
|
51 |
<type>html</type>
|
52 |
</abandonment_first_alert_config_template>
|
53 |
<abandonment_second_alert_config_template translate="label" module="abandonment">
|
54 |
-
<label>Abandoned Cart 2</label>
|
55 |
-
<file>
|
56 |
<type>html</type>
|
57 |
</abandonment_second_alert_config_template>
|
58 |
<abandonment_third_alert_config_template translate="label" module="abandonment">
|
59 |
-
<label>Abandoned Cart 3</label>
|
60 |
-
<file>
|
61 |
<type>html</type>
|
62 |
</abandonment_third_alert_config_template>
|
63 |
</email>
|
@@ -79,14 +79,15 @@
|
|
79 |
</abandonment>
|
80 |
</observers>
|
81 |
</sales_order_save_after>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
82 |
</events>
|
83 |
-
<layout>
|
84 |
-
<updates>
|
85 |
-
<abandonment module="Emv_CartAlert">
|
86 |
-
<file>emailvision/abandonment.xml</file>
|
87 |
-
</abandonment>
|
88 |
-
</updates>
|
89 |
-
</layout>
|
90 |
</global>
|
91 |
<frontend>
|
92 |
<routers>
|
@@ -101,7 +102,7 @@
|
|
101 |
<layout>
|
102 |
<updates>
|
103 |
<abandonment module="Emv_CartAlert">
|
104 |
-
<file>
|
105 |
</abandonment>
|
106 |
</updates>
|
107 |
</layout>
|
@@ -141,7 +142,9 @@
|
|
141 |
<default>
|
142 |
<abandonment>
|
143 |
<general>
|
|
|
144 |
<image_size>256</image_size>
|
|
|
145 |
<length>8</length>
|
146 |
<format>Alphanumeric</format>
|
147 |
<dash>4</dash>
|
@@ -157,4 +160,15 @@
|
|
157 |
</third_alert_config>
|
158 |
</abandonment>
|
159 |
</default>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
</config>
|
1 |
<config>
|
2 |
<modules>
|
3 |
<Emv_CartAlert>
|
4 |
+
<version>0.5.4</version>
|
5 |
</Emv_CartAlert>
|
6 |
</modules>
|
7 |
<global>
|
46 |
<template>
|
47 |
<email>
|
48 |
<abandonment_first_alert_config_template translate="label" module="abandonment">
|
49 |
+
<label>SmartFocus Abandoned Cart 1</label>
|
50 |
+
<file>smartfocus/abandonment/template1.html</file>
|
51 |
<type>html</type>
|
52 |
</abandonment_first_alert_config_template>
|
53 |
<abandonment_second_alert_config_template translate="label" module="abandonment">
|
54 |
+
<label>SmartFocus Abandoned Cart 2</label>
|
55 |
+
<file>smartfocus/abandonment/template2.html</file>
|
56 |
<type>html</type>
|
57 |
</abandonment_second_alert_config_template>
|
58 |
<abandonment_third_alert_config_template translate="label" module="abandonment">
|
59 |
+
<label>SmartFocus Abandoned Cart 3</label>
|
60 |
+
<file>smartfocus/abandonment/template3.html</file>
|
61 |
<type>html</type>
|
62 |
</abandonment_third_alert_config_template>
|
63 |
</email>
|
79 |
</abandonment>
|
80 |
</observers>
|
81 |
</sales_order_save_after>
|
82 |
+
<sales_quote_save_after>
|
83 |
+
<observers>
|
84 |
+
<abandonment>
|
85 |
+
<class>abandonment/observer</class>
|
86 |
+
<method>handleQuoteSaveAfter</method>
|
87 |
+
</abandonment>
|
88 |
+
</observers>
|
89 |
+
</sales_quote_save_after>
|
90 |
</events>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
91 |
</global>
|
92 |
<frontend>
|
93 |
<routers>
|
102 |
<layout>
|
103 |
<updates>
|
104 |
<abandonment module="Emv_CartAlert">
|
105 |
+
<file>smartfocus/abandonment.xml</file>
|
106 |
</abandonment>
|
107 |
</updates>
|
108 |
</layout>
|
142 |
<default>
|
143 |
<abandonment>
|
144 |
<general>
|
145 |
+
<lifetime>168</lifetime>
|
146 |
<image_size>256</image_size>
|
147 |
+
<limit>500</limit>
|
148 |
<length>8</length>
|
149 |
<format>Alphanumeric</format>
|
150 |
<dash>4</dash>
|
160 |
</third_alert_config>
|
161 |
</abandonment>
|
162 |
</default>
|
163 |
+
<admin>
|
164 |
+
<routers>
|
165 |
+
<abandonment>
|
166 |
+
<use>admin</use>
|
167 |
+
<args>
|
168 |
+
<module>Emv_CartAlert_Adminhtml</module>
|
169 |
+
<frontName>abandonment</frontName>
|
170 |
+
</args>
|
171 |
+
</abandonment>
|
172 |
+
</routers>
|
173 |
+
</admin>
|
174 |
</config>
|
@@ -2,7 +2,7 @@
|
|
2 |
<config>
|
3 |
<sections>
|
4 |
<abandonment translate="label" module="abandonment">
|
5 |
-
<label>
|
6 |
<tab>emailvision</tab>
|
7 |
<frontend_type>text</frontend_type>
|
8 |
<sort_order>50</sort_order>
|
@@ -10,20 +10,54 @@
|
|
10 |
<show_in_website>1</show_in_website>
|
11 |
<show_in_store>1</show_in_store>
|
12 |
<groups>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
<general translate="label" module="abandonment">
|
14 |
<label>General</label>
|
15 |
<expanded>0</expanded>
|
16 |
<frontend_type>text</frontend_type>
|
17 |
-
<sort_order>
|
18 |
<show_in_default>1</show_in_default>
|
19 |
<show_in_website>1</show_in_website>
|
20 |
<show_in_store>1</show_in_store>
|
21 |
<fields>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
<email_identity translate="label" module="abandonment">
|
23 |
<label>Email Sender</label>
|
24 |
<frontend_type>select</frontend_type>
|
25 |
<source_model>adminhtml/system_config_source_email_identity</source_model>
|
26 |
-
<sort_order>
|
27 |
<show_in_default>1</show_in_default>
|
28 |
<show_in_website>1</show_in_website>
|
29 |
<show_in_store>1</show_in_store>
|
@@ -31,20 +65,19 @@
|
|
31 |
<image_size translate="label" module="abandonment">
|
32 |
<label>Image Size</label>
|
33 |
<frontend_type>text</frontend_type>
|
34 |
-
<sort_order>
|
35 |
<show_in_default>1</show_in_default>
|
36 |
<show_in_website>1</show_in_website>
|
37 |
<show_in_store>1</show_in_store>
|
38 |
<frontend_class>validate-digits</frontend_class>
|
39 |
</image_size>
|
40 |
<cart_rule translate="label comment" module="abandonment">
|
41 |
-
<label>Shopping Cart Prices Rule
|
42 |
-
<
|
43 |
<sort_order>12</sort_order>
|
44 |
<show_in_default>1</show_in_default>
|
45 |
<show_in_website>1</show_in_website>
|
46 |
<show_in_store>1</show_in_store>
|
47 |
-
<frontend_class>validate-digits</frontend_class>
|
48 |
</cart_rule>
|
49 |
<length translate="label comment" module="abandonment">
|
50 |
<label>Coupon Code Length</label>
|
@@ -94,7 +127,7 @@
|
|
94 |
</fields>
|
95 |
</general>
|
96 |
<first_alert_config translate="label" module="abandonment">
|
97 |
-
<label>First
|
98 |
<expanded>0</expanded>
|
99 |
<frontend_type>text</frontend_type>
|
100 |
<sort_order>5</sort_order>
|
@@ -103,7 +136,7 @@
|
|
103 |
<show_in_store>1</show_in_store>
|
104 |
<fields>
|
105 |
<enabled translate="label" module="abandonment">
|
106 |
-
<label>First Email
|
107 |
<frontend_type>select</frontend_type>
|
108 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
109 |
<sort_order>10</sort_order>
|
@@ -112,15 +145,16 @@
|
|
112 |
<show_in_store>1</show_in_store>
|
113 |
</enabled>
|
114 |
<delay translate="label" module="abandonment">
|
115 |
-
<label>First Email
|
116 |
<frontend_type>text</frontend_type>
|
|
|
117 |
<sort_order>20</sort_order>
|
118 |
<show_in_default>1</show_in_default>
|
119 |
<show_in_website>1</show_in_website>
|
120 |
<show_in_store>1</show_in_store>
|
121 |
</delay>
|
122 |
<template translate="label" module="abandonment">
|
123 |
-
<label>First Email
|
124 |
<frontend_type>select</frontend_type>
|
125 |
<source_model>adminhtml/system_config_source_email_template</source_model>
|
126 |
<sort_order>30</sort_order>
|
@@ -131,7 +165,7 @@
|
|
131 |
</fields>
|
132 |
</first_alert_config>
|
133 |
<second_alert_config translate="label" module="abandonment">
|
134 |
-
<label>Second
|
135 |
<expanded>0</expanded>
|
136 |
<frontend_type>text</frontend_type>
|
137 |
<sort_order>10</sort_order>
|
@@ -140,7 +174,7 @@
|
|
140 |
<show_in_store>1</show_in_store>
|
141 |
<fields>
|
142 |
<enabled translate="label" module="abandonment">
|
143 |
-
<label>Second Email
|
144 |
<frontend_type>select</frontend_type>
|
145 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
146 |
<sort_order>10</sort_order>
|
@@ -149,15 +183,16 @@
|
|
149 |
<show_in_store>1</show_in_store>
|
150 |
</enabled>
|
151 |
<delay translate="label" module="abandonment">
|
152 |
-
<label>Second Email
|
153 |
<frontend_type>text</frontend_type>
|
|
|
154 |
<sort_order>20</sort_order>
|
155 |
<show_in_default>1</show_in_default>
|
156 |
<show_in_website>1</show_in_website>
|
157 |
<show_in_store>1</show_in_store>
|
158 |
</delay>
|
159 |
<template translate="label" module="abandonment">
|
160 |
-
<label>Second Email Template</label>
|
161 |
<frontend_type>select</frontend_type>
|
162 |
<source_model>adminhtml/system_config_source_email_template</source_model>
|
163 |
<sort_order>30</sort_order>
|
@@ -168,7 +203,7 @@
|
|
168 |
</fields>
|
169 |
</second_alert_config>
|
170 |
<third_alert_config translate="label" module="abandonment">
|
171 |
-
<label>Third
|
172 |
<expanded>0</expanded>
|
173 |
<frontend_type>text</frontend_type>
|
174 |
<sort_order>20</sort_order>
|
@@ -177,8 +212,9 @@
|
|
177 |
<show_in_store>1</show_in_store>
|
178 |
<fields>
|
179 |
<enabled translate="label" module="abandonment">
|
180 |
-
<label>Third Email
|
181 |
<frontend_type>select</frontend_type>
|
|
|
182 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
183 |
<sort_order>10</sort_order>
|
184 |
<show_in_default>1</show_in_default>
|
@@ -186,7 +222,7 @@
|
|
186 |
<show_in_store>1</show_in_store>
|
187 |
</enabled>
|
188 |
<delay translate="label" module="abandonment">
|
189 |
-
<label>Third Email
|
190 |
<frontend_type>text</frontend_type>
|
191 |
<sort_order>20</sort_order>
|
192 |
<show_in_default>1</show_in_default>
|
@@ -194,7 +230,7 @@
|
|
194 |
<show_in_store>1</show_in_store>
|
195 |
</delay>
|
196 |
<template translate="label" module="abandonment">
|
197 |
-
<label>Third Email
|
198 |
<frontend_type>select</frontend_type>
|
199 |
<source_model>adminhtml/system_config_source_email_template</source_model>
|
200 |
<sort_order>30</sort_order>
|
2 |
<config>
|
3 |
<sections>
|
4 |
<abandonment translate="label" module="abandonment">
|
5 |
+
<label>Abandoned Cart Reminders</label>
|
6 |
<tab>emailvision</tab>
|
7 |
<frontend_type>text</frontend_type>
|
8 |
<sort_order>50</sort_order>
|
10 |
<show_in_website>1</show_in_website>
|
11 |
<show_in_store>1</show_in_store>
|
12 |
<groups>
|
13 |
+
<extension_status translate="label">
|
14 |
+
<label>Plugin Status</label>
|
15 |
+
<frontend_model>emvcore/adminhtml_config_extensionStatus</frontend_model>
|
16 |
+
<sort_order>0</sort_order>
|
17 |
+
<frontend_type>text</frontend_type>
|
18 |
+
<show_in_default>1</show_in_default>
|
19 |
+
<show_in_website>1</show_in_website>
|
20 |
+
<show_in_store>1</show_in_store>
|
21 |
+
</extension_status>
|
22 |
<general translate="label" module="abandonment">
|
23 |
<label>General</label>
|
24 |
<expanded>0</expanded>
|
25 |
<frontend_type>text</frontend_type>
|
26 |
+
<sort_order>1</sort_order>
|
27 |
<show_in_default>1</show_in_default>
|
28 |
<show_in_website>1</show_in_website>
|
29 |
<show_in_store>1</show_in_store>
|
30 |
<fields>
|
31 |
+
<test_mode translate="label" module="abandonment">
|
32 |
+
<label>Enable test mode (the calculation will be in minutes)</label>
|
33 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
34 |
+
<frontend_type>select</frontend_type>
|
35 |
+
<sort_order>1</sort_order>
|
36 |
+
<show_in_default>1</show_in_default>
|
37 |
+
<show_in_website>0</show_in_website>
|
38 |
+
<show_in_store>0</show_in_store>
|
39 |
+
</test_mode>
|
40 |
+
<limit translate="label" module="abandonment">
|
41 |
+
<label>Maximum Abandoned Carts per One Run</label>
|
42 |
+
<frontend_type>text</frontend_type>
|
43 |
+
<sort_order>2</sort_order>
|
44 |
+
<show_in_default>1</show_in_default>
|
45 |
+
<show_in_website>0</show_in_website>
|
46 |
+
<show_in_store>0</show_in_store>
|
47 |
+
</limit>
|
48 |
+
<lifetime translate="label" module="abandonment">
|
49 |
+
<label>Cart Lifetime (in hours)</label>
|
50 |
+
<frontend_type>text</frontend_type>
|
51 |
+
<sort_order>3</sort_order>
|
52 |
+
<show_in_default>1</show_in_default>
|
53 |
+
<show_in_website>0</show_in_website>
|
54 |
+
<show_in_store>0</show_in_store>
|
55 |
+
</lifetime>
|
56 |
<email_identity translate="label" module="abandonment">
|
57 |
<label>Email Sender</label>
|
58 |
<frontend_type>select</frontend_type>
|
59 |
<source_model>adminhtml/system_config_source_email_identity</source_model>
|
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>
|
65 |
<image_size translate="label" module="abandonment">
|
66 |
<label>Image Size</label>
|
67 |
<frontend_type>text</frontend_type>
|
68 |
+
<sort_order>8</sort_order>
|
69 |
<show_in_default>1</show_in_default>
|
70 |
<show_in_website>1</show_in_website>
|
71 |
<show_in_store>1</show_in_store>
|
72 |
<frontend_class>validate-digits</frontend_class>
|
73 |
</image_size>
|
74 |
<cart_rule translate="label comment" module="abandonment">
|
75 |
+
<label>Shopping Cart Prices Rule</label>
|
76 |
+
<frontend_model>abandonment/adminhtml_system_config_promoRule</frontend_model>
|
77 |
<sort_order>12</sort_order>
|
78 |
<show_in_default>1</show_in_default>
|
79 |
<show_in_website>1</show_in_website>
|
80 |
<show_in_store>1</show_in_store>
|
|
|
81 |
</cart_rule>
|
82 |
<length translate="label comment" module="abandonment">
|
83 |
<label>Coupon Code Length</label>
|
127 |
</fields>
|
128 |
</general>
|
129 |
<first_alert_config translate="label" module="abandonment">
|
130 |
+
<label>First Reminder Configuration</label>
|
131 |
<expanded>0</expanded>
|
132 |
<frontend_type>text</frontend_type>
|
133 |
<sort_order>5</sort_order>
|
136 |
<show_in_store>1</show_in_store>
|
137 |
<fields>
|
138 |
<enabled translate="label" module="abandonment">
|
139 |
+
<label>First Email Reminder Enable</label>
|
140 |
<frontend_type>select</frontend_type>
|
141 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
142 |
<sort_order>10</sort_order>
|
145 |
<show_in_store>1</show_in_store>
|
146 |
</enabled>
|
147 |
<delay translate="label" module="abandonment">
|
148 |
+
<label>First Email Reminder Delay (in hours)</label>
|
149 |
<frontend_type>text</frontend_type>
|
150 |
+
<comment>By default, the calculation will be done in hours. If test mode enabled, it will be in minutes instead.</comment>
|
151 |
<sort_order>20</sort_order>
|
152 |
<show_in_default>1</show_in_default>
|
153 |
<show_in_website>1</show_in_website>
|
154 |
<show_in_store>1</show_in_store>
|
155 |
</delay>
|
156 |
<template translate="label" module="abandonment">
|
157 |
+
<label>First Email Reminder Template</label>
|
158 |
<frontend_type>select</frontend_type>
|
159 |
<source_model>adminhtml/system_config_source_email_template</source_model>
|
160 |
<sort_order>30</sort_order>
|
165 |
</fields>
|
166 |
</first_alert_config>
|
167 |
<second_alert_config translate="label" module="abandonment">
|
168 |
+
<label>Second Reminder Configuration</label>
|
169 |
<expanded>0</expanded>
|
170 |
<frontend_type>text</frontend_type>
|
171 |
<sort_order>10</sort_order>
|
174 |
<show_in_store>1</show_in_store>
|
175 |
<fields>
|
176 |
<enabled translate="label" module="abandonment">
|
177 |
+
<label>Second Email Reminder Enable</label>
|
178 |
<frontend_type>select</frontend_type>
|
179 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
180 |
<sort_order>10</sort_order>
|
183 |
<show_in_store>1</show_in_store>
|
184 |
</enabled>
|
185 |
<delay translate="label" module="abandonment">
|
186 |
+
<label>Second Email Reminder Delay (in hours)</label>
|
187 |
<frontend_type>text</frontend_type>
|
188 |
+
<comment>By default, the calculation will be done in hours. If test mode enabled, it will be in minutes instead.</comment>
|
189 |
<sort_order>20</sort_order>
|
190 |
<show_in_default>1</show_in_default>
|
191 |
<show_in_website>1</show_in_website>
|
192 |
<show_in_store>1</show_in_store>
|
193 |
</delay>
|
194 |
<template translate="label" module="abandonment">
|
195 |
+
<label>Second Email Reminder Template</label>
|
196 |
<frontend_type>select</frontend_type>
|
197 |
<source_model>adminhtml/system_config_source_email_template</source_model>
|
198 |
<sort_order>30</sort_order>
|
203 |
</fields>
|
204 |
</second_alert_config>
|
205 |
<third_alert_config translate="label" module="abandonment">
|
206 |
+
<label>Third Reminder Configuration</label>
|
207 |
<expanded>0</expanded>
|
208 |
<frontend_type>text</frontend_type>
|
209 |
<sort_order>20</sort_order>
|
212 |
<show_in_store>1</show_in_store>
|
213 |
<fields>
|
214 |
<enabled translate="label" module="abandonment">
|
215 |
+
<label>Third Email Reminder Enable</label>
|
216 |
<frontend_type>select</frontend_type>
|
217 |
+
<comment>By default, the calculation will be done in hours. If test mode enabled, it will be in minutes instead.</comment>
|
218 |
<source_model>adminhtml/system_config_source_yesno</source_model>
|
219 |
<sort_order>10</sort_order>
|
220 |
<show_in_default>1</show_in_default>
|
222 |
<show_in_store>1</show_in_store>
|
223 |
</enabled>
|
224 |
<delay translate="label" module="abandonment">
|
225 |
+
<label>Third Email Reminder Delay (in hours)</label>
|
226 |
<frontend_type>text</frontend_type>
|
227 |
<sort_order>20</sort_order>
|
228 |
<show_in_default>1</show_in_default>
|
230 |
<show_in_store>1</show_in_store>
|
231 |
</delay>
|
232 |
<template translate="label" module="abandonment">
|
233 |
+
<label>Third Email Reminder Template</label>
|
234 |
<frontend_type>select</frontend_type>
|
235 |
<source_model>adminhtml/system_config_source_email_template</source_model>
|
236 |
<sort_order>30</sort_order>
|
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/* @var $this Emv_CartAlert_Model_Resource_Setup */
|
3 |
+
|
4 |
+
$this->startSetup();
|
5 |
+
|
6 |
+
$this->getConnection()
|
7 |
+
->addColumn($this->getTable('abandonment/abandonment'), 'updated_at', 'DATETIME NULL');
|
8 |
+
|
9 |
+
$gmtDate = Mage::getModel('core/date')->gmtDate();
|
10 |
+
// update the existing abandonments
|
11 |
+
$sql = "UPDATE {$this->getTable('abandonment/abandonment')} AS aband"
|
12 |
+
. " SET aband.updated_at = '{$gmtDate}'";
|
13 |
+
$this->run($sql);
|
14 |
+
|
15 |
+
$this->endSetup();
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/* @var $this Emv_CartAlert_Model_Resource_Setup */
|
3 |
+
|
4 |
+
$this->startSetup();
|
5 |
+
|
6 |
+
$this->run("
|
7 |
+
ALTER TABLE {$this->getTable('abandonment')}
|
8 |
+
MODIFY COLUMN entity_id INT(10) NOT NULL,
|
9 |
+
|
10 |
+
ADD INDEX `IDX_ABANDONMENT_ENTITY_ID` (`entity_id`),
|
11 |
+
ADD INDEX `IDX_ABANDONMENT_TEMPLATE` (`template`)
|
12 |
+
");
|
13 |
+
|
14 |
+
$this->run("
|
15 |
+
ALTER TABLE {$this->getTable('abandonment/stats')}
|
16 |
+
ADD INDEX `IDX_ABANDONMENT_STAT_REMINDER_ID` (`reminder_id`),
|
17 |
+
ADD INDEX `IDX_ABANDONMENT_STAT_QUOTE_ID` (`quote_id`)
|
18 |
+
");
|
19 |
+
|
20 |
+
$this->run("
|
21 |
+
ALTER TABLE {$this->getTable('abandonment/order_flag')}
|
22 |
+
ADD INDEX `IDX_ABANDONMENT_ORDER_FLAG_ENTITY_ID` (`entity_id`),
|
23 |
+
ADD INDEX `IDX_ABANDONMENT_ORDER_FLAG_FLAG` (`flag`)
|
24 |
+
");
|
25 |
+
$this->endSetup();
|
@@ -19,7 +19,7 @@ class Emv_Core_Block_Adminhtml_Account_Edit_AssociatedUrls extends Mage_Adminhtm
|
|
19 |
*/
|
20 |
public function __construct()
|
21 |
{
|
22 |
-
$this->setTemplate('
|
23 |
}
|
24 |
|
25 |
/**
|
19 |
*/
|
20 |
public function __construct()
|
21 |
{
|
22 |
+
$this->setTemplate('smartfocus/account/associated_urls.phtml');
|
23 |
}
|
24 |
|
25 |
/**
|
@@ -0,0 +1,434 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Extension status block
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Core_Block_Adminhtml_Config_ExtensionStatus
|
11 |
+
extends Mage_Adminhtml_Block_Abstract
|
12 |
+
implements Varien_Data_Form_Element_Renderer_Interface
|
13 |
+
{
|
14 |
+
const BASE_EXTENSION_DIR = 'Emv';
|
15 |
+
const BASE_CODE_POOL = 'community';
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Custom template
|
19 |
+
*
|
20 |
+
* @var string
|
21 |
+
*/
|
22 |
+
protected $_template = 'smartfocus/config/extension_status.phtml';
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Help Link Url
|
26 |
+
* @var string
|
27 |
+
*/
|
28 |
+
protected $_helpLink = '';
|
29 |
+
|
30 |
+
/**
|
31 |
+
* PHP minimum version
|
32 |
+
*
|
33 |
+
* @var string
|
34 |
+
*/
|
35 |
+
protected $_minPhpVersion = '5.2.6';
|
36 |
+
|
37 |
+
/**
|
38 |
+
* List of call back functions to test
|
39 |
+
* @var array
|
40 |
+
*/
|
41 |
+
protected $_callbackList = array();
|
42 |
+
|
43 |
+
/**
|
44 |
+
* By default, we require soap, openssl, and curl extensions
|
45 |
+
*
|
46 |
+
* @var array
|
47 |
+
*/
|
48 |
+
protected $_defaultRequired = array('soap', 'openssl', 'curl');
|
49 |
+
|
50 |
+
/**
|
51 |
+
* You can include more PHP extensions by modifying this array
|
52 |
+
*
|
53 |
+
* @var array
|
54 |
+
*/
|
55 |
+
protected $_required = array();
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Minimum of memory size in MB
|
59 |
+
*
|
60 |
+
* @var int
|
61 |
+
*/
|
62 |
+
protected $_minMemory = 512;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Allowed time difference in Hours
|
66 |
+
*
|
67 |
+
* @var int
|
68 |
+
*/
|
69 |
+
protected $_allowedTimeDiffJob = 1;
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Render fieldset html
|
73 |
+
*
|
74 |
+
* @param Varien_Data_Form_Element_Abstract $fieldset
|
75 |
+
* @return string
|
76 |
+
*/
|
77 |
+
public function render(Varien_Data_Form_Element_Abstract $fieldset)
|
78 |
+
{
|
79 |
+
return $this->toHtml();
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* @return string
|
84 |
+
*/
|
85 |
+
protected function _getTickImageLink() {
|
86 |
+
return sprintf('<img src="%s" width="11" height="11" />',$this->getSkinUrl('images/smartfocus/tick.png'));
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* @return string
|
91 |
+
*/
|
92 |
+
protected function _getUnTickImageLink() {
|
93 |
+
return sprintf('<img src="%s" width="11" height="11" />',$this->getSkinUrl('images/smartfocus/untick.gif'));
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* @return string
|
98 |
+
*/
|
99 |
+
protected function _getWarningTickImageLink() {
|
100 |
+
return sprintf('<img src="%s" width="18" height="18" />',$this->getSkinUrl('images/smartfocus/warning.png'));
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* Get status of all installed Emv Modules
|
105 |
+
* @return string
|
106 |
+
*/
|
107 |
+
public function getEmvModulesVersionStatus()
|
108 |
+
{
|
109 |
+
$namespacePath = mage::getBaseDir('base') . DS . 'app' . DS . 'code'
|
110 |
+
. DS . self::BASE_CODE_POOL . DS . self::BASE_EXTENSION_DIR . DS;
|
111 |
+
|
112 |
+
$message = '';
|
113 |
+
$namespaceDir = @opendir($namespacePath);
|
114 |
+
$moduleVersion = array();
|
115 |
+
while ($subModule = readdir($namespaceDir)) {
|
116 |
+
if ($this->_directoryIsValid($subModule)) {
|
117 |
+
//parse modules within namespace
|
118 |
+
$modulePath = $namespacePath . $subModule . DS;
|
119 |
+
if (is_dir($modulePath)) {
|
120 |
+
$configXmlPath = $modulePath . 'etc/config.xml';
|
121 |
+
if (file_exists($configXmlPath)) {
|
122 |
+
$config = new Varien_Simplexml_Config();
|
123 |
+
$config->loadFile($configXmlPath);
|
124 |
+
$path = $config->getNode('modules');
|
125 |
+
foreach ($path->asArray() as $subModuleName => $version) {
|
126 |
+
$moduleVersion[] = $subModuleName . ' : ' . $version['version'];
|
127 |
+
}
|
128 |
+
}
|
129 |
+
}
|
130 |
+
}
|
131 |
+
}
|
132 |
+
closedir($namespaceDir);
|
133 |
+
|
134 |
+
$message = Mage::helper('emvcore')->__(
|
135 |
+
'<span class="icon-status">%s</span> List of installed modules <strong>%s</strong>.',
|
136 |
+
$this->_getWarningTickImageLink(),
|
137 |
+
implode(', ', $moduleVersion)
|
138 |
+
);
|
139 |
+
|
140 |
+
return $message;
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Check if directory name is valid
|
145 |
+
*
|
146 |
+
* @param string $dirName
|
147 |
+
* @return boolean
|
148 |
+
*/
|
149 |
+
private function _directoryIsValid($dirName) {
|
150 |
+
switch ($dirName) {
|
151 |
+
case '.':
|
152 |
+
case '..':
|
153 |
+
case '.DS_Store':
|
154 |
+
case '':
|
155 |
+
return false;
|
156 |
+
break;
|
157 |
+
default:
|
158 |
+
return true;
|
159 |
+
break;
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Get directory permission status
|
166 |
+
*
|
167 |
+
* @return string
|
168 |
+
*/
|
169 |
+
public function getDirectoryPermissionStatus()
|
170 |
+
{
|
171 |
+
$ok = true;
|
172 |
+
try {
|
173 |
+
$mageFile = new Varien_Io_File();
|
174 |
+
$mageFile->checkAndCreateFolder(Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER));
|
175 |
+
$mageFile->checkAndCreateFolder(
|
176 |
+
Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
177 |
+
. DS . Emv_Core_Helper_Data::BASE_WORKING_DIR
|
178 |
+
);
|
179 |
+
} catch (Exception $e) {
|
180 |
+
$ok = false;
|
181 |
+
}
|
182 |
+
|
183 |
+
$message = '';
|
184 |
+
if ($ok) {
|
185 |
+
$image = $this->_getTickImageLink();
|
186 |
+
$message = Mage::helper('emvcore')->__(
|
187 |
+
'<span class="icon-status">%s</span> Write permission is correctly set to <strong>%s</strong>.',
|
188 |
+
$image,
|
189 |
+
Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
190 |
+
);
|
191 |
+
} else {
|
192 |
+
$image = $this->_getUnTickImageLink();
|
193 |
+
$message = Mage::helper('emvcore')->__(
|
194 |
+
'<span class="icon-status">%s</span> Write permission is not correctly set to <strong>%s</strong>.',
|
195 |
+
$image,
|
196 |
+
Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
197 |
+
);
|
198 |
+
}
|
199 |
+
return $message;
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Get other test list (callable functions)
|
204 |
+
*
|
205 |
+
* @return array
|
206 |
+
*/
|
207 |
+
public function getOtherTestList()
|
208 |
+
{
|
209 |
+
return $this->_callbackList;
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Get status for a given test
|
214 |
+
*
|
215 |
+
* @param $testToHandle
|
216 |
+
* @return string / boolean - false
|
217 |
+
*/
|
218 |
+
public function getStatusForTest($testToHandle)
|
219 |
+
{
|
220 |
+
$status = '';
|
221 |
+
if (method_exists($this, $testToHandle)) {
|
222 |
+
$status = call_user_func(array($this,$testToHandle));
|
223 |
+
}
|
224 |
+
return $status;
|
225 |
+
}
|
226 |
+
|
227 |
+
/**
|
228 |
+
* @return string
|
229 |
+
*/
|
230 |
+
public function getHelpLink()
|
231 |
+
{
|
232 |
+
return $this->_helpLink;
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Get extension version
|
237 |
+
*
|
238 |
+
* @return string
|
239 |
+
*/
|
240 |
+
public function getExtensionVersion()
|
241 |
+
{
|
242 |
+
return Mage::helper('emvcore')->__("SmartFocus Connector Status (Version %s)", Emv_Core_Helper_Data::getVersion());
|
243 |
+
}
|
244 |
+
|
245 |
+
/**
|
246 |
+
* @return string
|
247 |
+
*/
|
248 |
+
public function getMagentoVersionStatus()
|
249 |
+
{
|
250 |
+
$magentoLabel = '';
|
251 |
+
if (method_exists('Mage', "getEdition")) {
|
252 |
+
$magentoLabel = Mage::getEdition() . ' ';
|
253 |
+
}
|
254 |
+
$magentoLabel .= Mage::getVersion();
|
255 |
+
return Mage::helper('emvcore')->__(
|
256 |
+
'<span class="icon-status">%s</span> Your Magento version is <strong>%s</strong>.',
|
257 |
+
$this->_getTickImageLink(),
|
258 |
+
$magentoLabel
|
259 |
+
);
|
260 |
+
}
|
261 |
+
|
262 |
+
/**
|
263 |
+
* Check and get PHP environment status
|
264 |
+
*
|
265 |
+
* @return string
|
266 |
+
*/
|
267 |
+
public function getPhpEnvironmentStatus()
|
268 |
+
{
|
269 |
+
$ok = true;
|
270 |
+
|
271 |
+
if (!version_compare(PHP_VERSION, $this->_minPhpVersion, ">=")) {
|
272 |
+
$phpCheck = Mage::helper('emvcore')->__(
|
273 |
+
'Required PHP version is <strong>%s</strong> - current version <strong>%s</strong>.',
|
274 |
+
$this->_minPhpVersion,
|
275 |
+
PHP_VERSION
|
276 |
+
);
|
277 |
+
$ok = false;
|
278 |
+
} else {
|
279 |
+
$phpCheck = Mage::helper('emvcore')->__('Your PHP version (<strong>%s</strong>) is satisfied.', PHP_VERSION);
|
280 |
+
}
|
281 |
+
|
282 |
+
$required = array_merge($this->_defaultRequired, $this->_required);
|
283 |
+
$missing = array();
|
284 |
+
$loaded = array();
|
285 |
+
/*
|
286 |
+
* Run through PHP extensions to see if they are loaded
|
287 |
+
* if no, add them to the list of missing
|
288 |
+
*/
|
289 |
+
foreach ($required as $extName) {
|
290 |
+
if (!extension_loaded($extName)) {
|
291 |
+
$missing[] = $extName;
|
292 |
+
}
|
293 |
+
}
|
294 |
+
|
295 |
+
if (count($missing)) {
|
296 |
+
$ok = false;
|
297 |
+
$extensionCheck = Mage::helper('emvcore')->__(
|
298 |
+
'Required Php Extensions are <strong>%s</strong>.',
|
299 |
+
implode(', ', $required)
|
300 |
+
);
|
301 |
+
$extensionCheck .= ' ' . Mage::helper('emvcore')->__(
|
302 |
+
'The followings are missing : <strong>%s</strong>.',
|
303 |
+
implode(', ', $missing)
|
304 |
+
);
|
305 |
+
} else {
|
306 |
+
$extensionCheck = Mage::helper('emvcore')->__(
|
307 |
+
'All the required Php Extensions (<strong>%s</strong>) are correctly installed.',
|
308 |
+
implode(', ', $required)
|
309 |
+
);
|
310 |
+
}
|
311 |
+
|
312 |
+
if ($ok) {
|
313 |
+
$image = $this->_getTickImageLink();
|
314 |
+
} else {
|
315 |
+
$image = $this->_getUnTickImageLink();
|
316 |
+
}
|
317 |
+
|
318 |
+
return Mage::helper('emvcore')->__(
|
319 |
+
'<span class="icon-status">%s</span> %s',
|
320 |
+
$image,
|
321 |
+
$phpCheck . ' ' . $extensionCheck
|
322 |
+
);
|
323 |
+
}
|
324 |
+
|
325 |
+
/**
|
326 |
+
* Check and get Cron status
|
327 |
+
*
|
328 |
+
* @return string
|
329 |
+
*/
|
330 |
+
public function getCronStatus()
|
331 |
+
{
|
332 |
+
// get the last job with status pending or running
|
333 |
+
$lastJob = Mage::getModel('cron/schedule')->getCollection()
|
334 |
+
->addFieldToFilter('status', array(
|
335 |
+
'in' => array(
|
336 |
+
Mage_Cron_Model_Schedule::STATUS_PENDING,
|
337 |
+
Mage_Cron_Model_Schedule::STATUS_RUNNING,
|
338 |
+
)
|
339 |
+
)
|
340 |
+
)
|
341 |
+
->setOrder('scheduled_at', Varien_Data_Collection_Db::SORT_ORDER_DESC)
|
342 |
+
->setPageSize(1)
|
343 |
+
->getFirstItem();
|
344 |
+
|
345 |
+
// check if last job has been scheduled within allowed interval
|
346 |
+
$ok = true;
|
347 |
+
if ($lastJob && $lastJob->getId()) {
|
348 |
+
$locale = Mage::app()->getLocale();
|
349 |
+
|
350 |
+
$scheduledAt = $locale->date($lastJob->getScheduledAt(), Varien_Date::DATETIME_INTERNAL_FORMAT);
|
351 |
+
$scheduledAt = $locale->utcDate(null, $scheduledAt);
|
352 |
+
|
353 |
+
// now
|
354 |
+
$now = $locale->date(null, Varien_Date::DATETIME_INTERNAL_FORMAT);
|
355 |
+
$now = $locale->utcDate(null, $now);
|
356 |
+
|
357 |
+
// if last job was scheduled before the current time
|
358 |
+
if ($now->isLater($scheduledAt)) {
|
359 |
+
$allowedTime = $now->subHour($this->_allowedTimeDiffJob);
|
360 |
+
if ($allowedTime->isLater($scheduledAt)) {
|
361 |
+
$ok = false;
|
362 |
+
}
|
363 |
+
}
|
364 |
+
} else {
|
365 |
+
$ok = false;
|
366 |
+
}
|
367 |
+
|
368 |
+
$message = '';
|
369 |
+
if ($ok) {
|
370 |
+
$image = $this->_getTickImageLink();
|
371 |
+
$message = Mage::helper('emvcore')->__(
|
372 |
+
'<span class="icon-status">%s</span> Magento Cron Process has been correctly configured!',
|
373 |
+
$image
|
374 |
+
);
|
375 |
+
} else {
|
376 |
+
$image = $this->_getUnTickImageLink();
|
377 |
+
$message = Mage::helper('emvcore')->__(
|
378 |
+
'<span class="icon-status">%s</span> Magento Cron Process has not been correctly activated!',
|
379 |
+
$image
|
380 |
+
);
|
381 |
+
}
|
382 |
+
|
383 |
+
return $message;
|
384 |
+
}
|
385 |
+
|
386 |
+
/**
|
387 |
+
* Check and get memory status
|
388 |
+
*
|
389 |
+
* @return string
|
390 |
+
*/
|
391 |
+
public function getMemoryStatus()
|
392 |
+
{
|
393 |
+
$memoryLimit = trim(strtoupper(ini_get('memory_limit')));
|
394 |
+
|
395 |
+
$ok = true;
|
396 |
+
if ($memoryLimit != -1) {
|
397 |
+
$memoryLimitInBytes = $memoryLimit;
|
398 |
+
if (substr($memoryLimit, -1) == 'K') {
|
399 |
+
$memoryLimitInBytes = substr($memoryLimit, 0, -1) * 1024;
|
400 |
+
}
|
401 |
+
if (substr($memoryLimit, -1) == 'M') {
|
402 |
+
$memoryLimitInBytes = substr($memoryLimit, 0, -1) * 1024 * 1024;
|
403 |
+
}
|
404 |
+
if (substr($memoryLimit, -1) == 'G') {
|
405 |
+
$memoryLimitInBytes = substr($memoryLimit, 0, -1) * 1024 * 1024 * 1024;
|
406 |
+
}
|
407 |
+
|
408 |
+
$allowedLimit = $this->_minMemory * 1024 * 1024;
|
409 |
+
if ($memoryLimitInBytes < $allowedLimit) {
|
410 |
+
$ok = false;
|
411 |
+
}
|
412 |
+
}
|
413 |
+
|
414 |
+
$message = '';
|
415 |
+
if ($ok) {
|
416 |
+
$image = $this->_getTickImageLink();
|
417 |
+
$message = Mage::helper('emvcore')->__(
|
418 |
+
'<span class="icon-status">%s</span> memory_limit is set to <strong>%s</strong>.',
|
419 |
+
$image,
|
420 |
+
$memoryLimit
|
421 |
+
);
|
422 |
+
} else {
|
423 |
+
$image = $this->_getWarningTickImageLink();
|
424 |
+
$message = Mage::helper('emvcore')->__(
|
425 |
+
'<span class="icon-status">%s</span> memory_limit should be set to at least <strong>%s M</strong> (currently %s).',
|
426 |
+
$image,
|
427 |
+
$this->_minMemory,
|
428 |
+
$memoryLimit
|
429 |
+
);
|
430 |
+
}
|
431 |
+
return $message;
|
432 |
+
}
|
433 |
+
|
434 |
+
}
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Data Processing Process Grid Container
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Core_Block_Adminhtml_DataProcessing_Process extends Mage_Adminhtml_Block_Widget_Grid_Container
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Construct data process menu
|
14 |
+
* @see Mage_Adminhtml_Block_Widget_Grid_Container::__construct()
|
15 |
+
*/
|
16 |
+
public function __construct()
|
17 |
+
{
|
18 |
+
parent::__construct();
|
19 |
+
$this->_blockGroup = 'emvcore';
|
20 |
+
$this->_controller = 'adminhtml_dataProcessing_process';
|
21 |
+
$this->_headerText = Mage::helper('emvcore')->__('SmartFocus Data Process List');
|
22 |
+
$this->_removeButton('add');
|
23 |
+
|
24 |
+
}
|
25 |
+
}
|
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Data Processing Process Grid
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Core_Block_Adminhtml_DataProcessing_Process_Grid extends Mage_Adminhtml_Block_Widget_Grid
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Constructor
|
14 |
+
*
|
15 |
+
* Set main configuration of grid
|
16 |
+
*/
|
17 |
+
public function __construct()
|
18 |
+
{
|
19 |
+
parent::__construct();
|
20 |
+
$this->setId('dataProcessingGrid');
|
21 |
+
$this->setUseAjax(true);
|
22 |
+
$this->setDefaultSort('id', 'desc');
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Prepare collection for grid
|
27 |
+
*
|
28 |
+
* @return Mage_Adminhtml_Block_Widget_Grid
|
29 |
+
*/
|
30 |
+
protected function _prepareCollection()
|
31 |
+
{
|
32 |
+
$collection = Mage::getResourceSingleton('emvcore/dataProcessing_process_collection');
|
33 |
+
$this->setCollection($collection);
|
34 |
+
|
35 |
+
return parent::_prepareCollection();
|
36 |
+
}
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Define grid columns
|
40 |
+
*
|
41 |
+
* @return void
|
42 |
+
*/
|
43 |
+
protected function _prepareColumns()
|
44 |
+
{
|
45 |
+
$this->addColumn('id', array(
|
46 |
+
'header' => Mage::helper('newsletter')->__('ID'),
|
47 |
+
'index' => 'id',
|
48 |
+
'width' => '40',
|
49 |
+
));
|
50 |
+
|
51 |
+
$this->addColumn('type', array(
|
52 |
+
'header' => Mage::helper('newsletter')->__('Type'),
|
53 |
+
'index' => 'type',
|
54 |
+
'type' => 'options',
|
55 |
+
'options' => array(
|
56 |
+
Emv_Core_Model_DataProcessing_Process::TYPE_DATA_SYNC => Mage::helper('emvcore')->__('Data Sync')
|
57 |
+
)
|
58 |
+
));
|
59 |
+
|
60 |
+
$this->addColumn('title', array(
|
61 |
+
'header' => Mage::helper('emvcore')->__('Title'),
|
62 |
+
'index' => 'title'
|
63 |
+
));
|
64 |
+
|
65 |
+
$this->addColumn('state', array(
|
66 |
+
'header' => Mage::helper('emvcore')->__('State'),
|
67 |
+
'index' => 'state',
|
68 |
+
'width' => '80px',
|
69 |
+
'type' => 'options',
|
70 |
+
'options' => array(
|
71 |
+
Emv_Core_Model_DataProcessing_Process::STATE_NEW => Mage::helper('emvcore')->__('New'),
|
72 |
+
Emv_Core_Model_DataProcessing_Process::STATE_PROCESSING => Mage::helper('emvcore')->__('Processing'),
|
73 |
+
Emv_Core_Model_DataProcessing_Process::STATE_FAILED => Mage::helper('emvcore')->__('Failed'),
|
74 |
+
Emv_Core_Model_DataProcessing_Process::STATE_SUCCESS => Mage::helper('emvcore')->__('Success'),
|
75 |
+
)
|
76 |
+
));
|
77 |
+
|
78 |
+
$this->addColumn('status', array(
|
79 |
+
'header' => Mage::helper('emvcore')->__('Status (%)'),
|
80 |
+
'index' => 'status',
|
81 |
+
'width' => '40px',
|
82 |
+
));
|
83 |
+
|
84 |
+
$this->addColumn('created_at', array(
|
85 |
+
'header' => Mage::helper('reports')->__('Created At'),
|
86 |
+
'type' => 'datetime',
|
87 |
+
'align' => 'center',
|
88 |
+
'index' => 'created_at',
|
89 |
+
));
|
90 |
+
$this->addColumn('updated_at', array(
|
91 |
+
'header' => Mage::helper('reports')->__('Updated At'),
|
92 |
+
'type' => 'datetime',
|
93 |
+
'align' => 'center',
|
94 |
+
'index' => 'updated_at',
|
95 |
+
));
|
96 |
+
$this->addColumn('terminated_at', array(
|
97 |
+
'header' => Mage::helper('emvcore')->__('Terminated At'),
|
98 |
+
'type' => 'datetime',
|
99 |
+
'align' => 'center',
|
100 |
+
'index' => 'terminated_at',
|
101 |
+
));
|
102 |
+
|
103 |
+
$this->addColumn('output', array(
|
104 |
+
'index' => 'output_information',
|
105 |
+
'filter' => false,
|
106 |
+
'sortable' => false,
|
107 |
+
'renderer' => 'emvcore/adminhtml_dataProcessing_process_grid_column_renderer_output',
|
108 |
+
'header' => Mage::helper('emvcore')->__('Output'),
|
109 |
+
));
|
110 |
+
|
111 |
+
$this->addColumn(
|
112 |
+
'links',
|
113 |
+
array(
|
114 |
+
'header' => Mage::helper('emvcore')->__('Action'),
|
115 |
+
'type' => 'text',
|
116 |
+
'width' => '100px',
|
117 |
+
'filter' => false,
|
118 |
+
'sortable' => false,
|
119 |
+
'renderer' => 'emvcore/adminhtml_dataProcessing_process_grid_column_renderer_links'
|
120 |
+
)
|
121 |
+
);
|
122 |
+
|
123 |
+
return parent::_prepareColumns();
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Prepare mass action for grid
|
128 |
+
*
|
129 |
+
* (non-PHPdoc)
|
130 |
+
* @see Mage_Adminhtml_Block_Newsletter_Subscriber_Grid::_prepareMassaction()
|
131 |
+
*/
|
132 |
+
protected function _prepareMassaction()
|
133 |
+
{
|
134 |
+
$this->setMassactionIdField('id');
|
135 |
+
$this->getMassactionBlock()->setFormFieldName('ids');
|
136 |
+
|
137 |
+
$this->getMassactionBlock()->addItem('remove_queue', array(
|
138 |
+
'label' => Mage::helper('newsletter')->__('Delete'),
|
139 |
+
'url' => $this->getUrl('*/*/massDelete'),
|
140 |
+
'confirm' => $this->__('Are you sure?')
|
141 |
+
)
|
142 |
+
);
|
143 |
+
|
144 |
+
return $this;
|
145 |
+
}
|
146 |
+
|
147 |
+
/**
|
148 |
+
* Get row class - determine the row class according to state information
|
149 |
+
*
|
150 |
+
* @param Varien_Object $emvEmt
|
151 |
+
* @return string
|
152 |
+
*/
|
153 |
+
public function getRowClass(Varien_Object $row)
|
154 |
+
{
|
155 |
+
$class = "";
|
156 |
+
if ($row->getData('state') == Emv_Core_Model_DataProcessing_Process::STATE_FAILED) {
|
157 |
+
$class= "invalid";
|
158 |
+
}
|
159 |
+
if ($row->getData('state') == Emv_Core_Model_DataProcessing_Process::STATE_PROCESSING) {
|
160 |
+
$class= "on-progress";
|
161 |
+
}
|
162 |
+
return $class;
|
163 |
+
}
|
164 |
+
}
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Links renderer
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Core_Block_Adminhtml_DataProcessing_Process_Grid_Column_Renderer_Links
|
11 |
+
extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
|
12 |
+
{
|
13 |
+
/**
|
14 |
+
* Render a link to the log/report/exception files
|
15 |
+
*
|
16 |
+
* @param Varien_Object $row
|
17 |
+
*
|
18 |
+
* @return string
|
19 |
+
*/
|
20 |
+
public function render(Varien_Object $row)
|
21 |
+
{
|
22 |
+
if (!$row instanceof Emv_Core_Model_DataProcessing_Process) {
|
23 |
+
return '';
|
24 |
+
}
|
25 |
+
|
26 |
+
$output = '';
|
27 |
+
if ($row->checkLogData()) {
|
28 |
+
$url = Mage::helper('emvcore')->getLogUrlForProcess($row);
|
29 |
+
$output .= sprintf('<a href="%s">%s</a>', $url, $this->helper('emvcore')->__('View Log'));
|
30 |
+
}
|
31 |
+
return $output;
|
32 |
+
}
|
33 |
+
}
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Input / output information renderer
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Core_Block_Adminhtml_DataProcessing_Process_Grid_Column_Renderer_Output
|
11 |
+
extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract
|
12 |
+
{
|
13 |
+
/**
|
14 |
+
* Retrieve an URL for 'file' function
|
15 |
+
*
|
16 |
+
* @param array $params
|
17 |
+
*
|
18 |
+
* @return string
|
19 |
+
*/
|
20 |
+
protected function _getFileDownloadUrl($params)
|
21 |
+
{
|
22 |
+
return $this->getUrl('*/*/getOutputFile', $params);
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Render a input / output text
|
27 |
+
*
|
28 |
+
* @param Varien_Object $row
|
29 |
+
*
|
30 |
+
* @return string
|
31 |
+
*/
|
32 |
+
public function render(Varien_Object $row)
|
33 |
+
{
|
34 |
+
$index = $this->getColumn()->getIndex();
|
35 |
+
$data = $row->getData($index);
|
36 |
+
|
37 |
+
$label = '';
|
38 |
+
if ($data) {
|
39 |
+
$data = unserialize($data);
|
40 |
+
if (is_array($data) && count($data)) {
|
41 |
+
foreach ($data as $output) {
|
42 |
+
if (is_readable($output['path'])) {
|
43 |
+
$params = array('path' => base64_encode($output['path']),
|
44 |
+
'filename' => base64_encode($output['filename'])
|
45 |
+
);
|
46 |
+
$downloadUrl = $this->getUrl('*/*/getOutputFile', $params);
|
47 |
+
|
48 |
+
$label .= '<a href="'.$downloadUrl.'" title="'.htmlentities($output['label']).'">'
|
49 |
+
.htmlentities($output['label']).'</a>' . '<br/>';
|
50 |
+
} else {
|
51 |
+
$label .= htmlentities($output['label']) . '<br/>';
|
52 |
+
}
|
53 |
+
}
|
54 |
+
}
|
55 |
+
}
|
56 |
+
|
57 |
+
return $label;
|
58 |
+
}
|
59 |
+
}
|
@@ -9,12 +9,65 @@
|
|
9 |
*/
|
10 |
class Emv_Core_Helper_Data extends Mage_Core_Helper_Abstract
|
11 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
/**
|
13 |
* List of accounts
|
14 |
* @var array
|
15 |
*/
|
16 |
protected $_accountList = array();
|
17 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
/**
|
19 |
* Get account for a given id
|
20 |
*
|
@@ -40,7 +93,8 @@ class Emv_Core_Helper_Data extends Mage_Core_Helper_Abstract
|
|
40 |
*/
|
41 |
public static function getLockPathDir()
|
42 |
{
|
43 |
-
return Mage::getBaseDir(
|
|
|
44 |
}
|
45 |
|
46 |
/**
|
@@ -60,7 +114,7 @@ class Emv_Core_Helper_Data extends Mage_Core_Helper_Abstract
|
|
60 |
}
|
61 |
|
62 |
/**
|
63 |
-
* Create a lock file
|
64 |
*
|
65 |
* @param string $content
|
66 |
* @return number | boolean - false
|
@@ -68,25 +122,50 @@ class Emv_Core_Helper_Data extends Mage_Core_Helper_Abstract
|
|
68 |
public function createLockFile($fileName, $content = '')
|
69 |
{
|
70 |
if (!$content) {
|
71 |
-
$content = Mage::getModel('core/date')->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
72 |
}
|
|
|
|
|
73 |
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
}
|
76 |
|
77 |
/**
|
78 |
-
* Remove a lock file
|
79 |
*
|
80 |
* @param string $fileName
|
81 |
* @return boolean
|
82 |
*/
|
83 |
public function removeLockFile($fileName)
|
84 |
{
|
85 |
-
|
|
|
|
|
|
|
|
|
86 |
}
|
87 |
|
88 |
/**
|
89 |
* Check if lock file exists
|
|
|
90 |
* @param string $fileName
|
91 |
* @return boolean
|
92 |
*/
|
@@ -95,6 +174,33 @@ class Emv_Core_Helper_Data extends Mage_Core_Helper_Abstract
|
|
95 |
return $this->_getLockHandler()->fileExists($fileName, true);
|
96 |
}
|
97 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
98 |
/**
|
99 |
* @param string $path
|
100 |
* @param mixed $store
|
@@ -110,23 +216,46 @@ class Emv_Core_Helper_Data extends Mage_Core_Helper_Abstract
|
|
110 |
return $website->getConfig($path);
|
111 |
}
|
112 |
|
113 |
-
$
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
-
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
$website = Mage::app()->getGroup($groupCode)->getWebsite();
|
123 |
-
return $website->getConfig($path);
|
124 |
-
}
|
125 |
}
|
126 |
|
127 |
return Mage::getStoreConfig($path);
|
128 |
}
|
129 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
130 |
/**
|
131 |
* Format number in a given locale
|
132 |
*
|
@@ -153,4 +282,38 @@ class Emv_Core_Helper_Data extends Mage_Core_Helper_Abstract
|
|
153 |
return $number;
|
154 |
}
|
155 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
156 |
}
|
9 |
*/
|
10 |
class Emv_Core_Helper_Data extends Mage_Core_Helper_Abstract
|
11 |
{
|
12 |
+
/**
|
13 |
+
* Gets the detailed Extension version information
|
14 |
+
*
|
15 |
+
* @return array
|
16 |
+
*/
|
17 |
+
public static function getVersionInfo()
|
18 |
+
{
|
19 |
+
return array(
|
20 |
+
'major' => '3',
|
21 |
+
'minor' => '1',
|
22 |
+
'revision' => '0',
|
23 |
+
'patch' => '',
|
24 |
+
'stability' => '',
|
25 |
+
'number' => '',
|
26 |
+
);
|
27 |
+
}
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Gets the current Extension version string
|
31 |
+
*
|
32 |
+
* @return string
|
33 |
+
*/
|
34 |
+
public static function getVersion()
|
35 |
+
{
|
36 |
+
$i = self::getVersionInfo();
|
37 |
+
return trim("{$i['major']}.{$i['minor']}.{$i['revision']}" . ($i['patch'] != '' ? ".{$i['patch']}" : "")
|
38 |
+
. "-{$i['stability']}{$i['number']}", '.-');
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Different constant relative to working directory path
|
43 |
+
*/
|
44 |
+
const BASE_CONTAINER = 'export';
|
45 |
+
const BASE_WORKING_DIR = 'emailvision';
|
46 |
+
const UPLOADED_FILE_DIR = 'uploaded';
|
47 |
+
const TEMPORARY_DIR = 'tmp';
|
48 |
+
const LOCK_DIR = 'locks';
|
49 |
+
|
50 |
/**
|
51 |
* List of accounts
|
52 |
* @var array
|
53 |
*/
|
54 |
protected $_accountList = array();
|
55 |
|
56 |
+
/**
|
57 |
+
* Custom error handler
|
58 |
+
*/
|
59 |
+
const CUSTOM_ERROR_HANDLER = 'smartFocusErrorHandler';
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Custom shutdown handler
|
63 |
+
*/
|
64 |
+
const CUSTOM_SHUTDOWN_HANDLER = 'smartFocusShutDownPhpHandler';
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Lock file registry name
|
68 |
+
*/
|
69 |
+
const CREATED_LOCK_FILE_REGISTRY = 'smartfocus_lock_file';
|
70 |
+
|
71 |
/**
|
72 |
* Get account for a given id
|
73 |
*
|
93 |
*/
|
94 |
public static function getLockPathDir()
|
95 |
{
|
96 |
+
return Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
97 |
+
. DS . Emv_Core_Helper_Data::BASE_WORKING_DIR . DS . Emv_Core_Helper_Data::LOCK_DIR;
|
98 |
}
|
99 |
|
100 |
/**
|
114 |
}
|
115 |
|
116 |
/**
|
117 |
+
* Create a lock file. Your created lock file path can be found in Emv_Core_Helper_Data::CREATED_LOCK_FILE_REGISTRY
|
118 |
*
|
119 |
* @param string $content
|
120 |
* @return number | boolean - false
|
122 |
public function createLockFile($fileName, $content = '')
|
123 |
{
|
124 |
if (!$content) {
|
125 |
+
$content = Mage::getModel('core/date')->gmtDate('Y-m-d H:i:s');
|
126 |
+
}
|
127 |
+
|
128 |
+
$sucess = $this->_getLockHandler()->write($fileName, $content);
|
129 |
+
if ($sucess) {
|
130 |
+
$fullpathFileName = self::getLockPathDir() . DS . $fileName;
|
131 |
+
// register the created file name in order to remove after
|
132 |
+
Mage::register(self::CREATED_LOCK_FILE_REGISTRY, $fullpathFileName);
|
133 |
+
} else {
|
134 |
+
Mage::unregister(self::CREATED_LOCK_FILE_REGISTRY);
|
135 |
}
|
136 |
+
return $sucess;
|
137 |
+
}
|
138 |
|
139 |
+
/**
|
140 |
+
* Remove the last lock file from registry
|
141 |
+
*/
|
142 |
+
public function removeLastLockFileFromRegistry()
|
143 |
+
{
|
144 |
+
$fullPath = Mage::registry(Emv_Core_Helper_Data::CREATED_LOCK_FILE_REGISTRY);
|
145 |
+
if ($fullPath) {
|
146 |
+
@unlink($fullPath);
|
147 |
+
}
|
148 |
+
Mage::unregister(Emv_Core_Helper_Data::CREATED_LOCK_FILE_REGISTRY);
|
149 |
}
|
150 |
|
151 |
/**
|
152 |
+
* Remove a lock file. Empty this registry Emv_Core_Helper_Data::CREATED_LOCK_FILE_REGISTRY
|
153 |
*
|
154 |
* @param string $fileName
|
155 |
* @return boolean
|
156 |
*/
|
157 |
public function removeLockFile($fileName)
|
158 |
{
|
159 |
+
$sucess = $this->_getLockHandler()->rm($fileName);
|
160 |
+
if ($sucess) {
|
161 |
+
Mage::unregister(self::CREATED_LOCK_FILE_REGISTRY);
|
162 |
+
};
|
163 |
+
return $sucess;
|
164 |
}
|
165 |
|
166 |
/**
|
167 |
* Check if lock file exists
|
168 |
+
*
|
169 |
* @param string $fileName
|
170 |
* @return boolean
|
171 |
*/
|
174 |
return $this->_getLockHandler()->fileExists($fileName, true);
|
175 |
}
|
176 |
|
177 |
+
/**
|
178 |
+
* Set SmartFocus Error Handler
|
179 |
+
*
|
180 |
+
* @return string previous error handler
|
181 |
+
*/
|
182 |
+
public function setSmartFocusErrorHandler()
|
183 |
+
{
|
184 |
+
include_once Mage::getBaseDir('code') . DS . 'community'
|
185 |
+
. DS . 'Emv' . DS . 'Core' . DS . 'functions.php';
|
186 |
+
|
187 |
+
// set register shutdown function in order to remove lock file
|
188 |
+
register_shutdown_function(self::CUSTOM_SHUTDOWN_HANDLER);
|
189 |
+
return set_error_handler(self::CUSTOM_ERROR_HANDLER);
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* Reset Error Handler to Magento default one
|
194 |
+
*
|
195 |
+
* @return string previous error handler
|
196 |
+
*/
|
197 |
+
public function resetErrorHandler()
|
198 |
+
{
|
199 |
+
// reset shut down function
|
200 |
+
register_shutdown_function(function(){});
|
201 |
+
return set_error_handler(Mage_Core_Model_App::DEFAULT_ERROR_HANDLER);
|
202 |
+
}
|
203 |
+
|
204 |
/**
|
205 |
* @param string $path
|
206 |
* @param mixed $store
|
216 |
return $website->getConfig($path);
|
217 |
}
|
218 |
|
219 |
+
if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
|
220 |
+
$store = Mage::app()->getStore($storeCode);
|
221 |
+
return $store->getConfig($path);
|
222 |
+
} elseif ($websiteCode = Mage::app()->getRequest()->getParam('website')){
|
223 |
+
$website = Mage::app()->getWebsite($websiteCode);
|
224 |
+
return $website->getConfig($path);
|
225 |
+
} else if ($groupCode = Mage::app()->getRequest()->getParam('group')){
|
226 |
+
$website = Mage::app()->getGroup($groupCode)->getWebsite();
|
227 |
+
return $website->getConfig($path);
|
|
|
|
|
|
|
228 |
}
|
229 |
|
230 |
return Mage::getStoreConfig($path);
|
231 |
}
|
232 |
|
233 |
+
/**
|
234 |
+
* Get admin scope in order to store config data
|
235 |
+
*
|
236 |
+
* @return array admin scope
|
237 |
+
* - scope
|
238 |
+
* - scope_id
|
239 |
+
* - scope_code
|
240 |
+
*/
|
241 |
+
public function getAdminScope()
|
242 |
+
{
|
243 |
+
$scope = 'default';
|
244 |
+
$scopeId = 0;
|
245 |
+
$scopeCode = '';
|
246 |
+
if ($storeCode = Mage::app()->getRequest()->getParam('store')) {
|
247 |
+
$scope = 'stores';
|
248 |
+
$scopeId = (int)Mage::getConfig()->getNode('stores/' . $storeCode . '/system/store/id');
|
249 |
+
$scopeCode = $storeCode;
|
250 |
+
} elseif ($websiteCode = Mage::app()->getRequest()->getParam('website')) {
|
251 |
+
$scope = 'websites';
|
252 |
+
$scopeId = (int)Mage::getConfig()->getNode('websites/' . $websiteCode . '/system/website/id');
|
253 |
+
$scopeCode = $websiteCode;
|
254 |
+
}
|
255 |
+
|
256 |
+
return array('scope' => $scope, 'scope_id' => $scopeId, 'scope_code' => $scopeCode);
|
257 |
+
}
|
258 |
+
|
259 |
/**
|
260 |
* Format number in a given locale
|
261 |
*
|
282 |
return $number;
|
283 |
}
|
284 |
|
285 |
+
/**
|
286 |
+
* Check and get url for a given url type.
|
287 |
+
*
|
288 |
+
* @param Emv_Core_Model_Account $account
|
289 |
+
* @param string $type
|
290 |
+
* @throws Mage_Core_Exception if we can't find a corresponding url
|
291 |
+
* @return string
|
292 |
+
*/
|
293 |
+
public function checkAndGetUrlForType(Emv_Core_Model_Account $account, $type)
|
294 |
+
{
|
295 |
+
// get service label
|
296 |
+
$labels = Emv_Core_Model_Account::getUrlTypesAndLabels();
|
297 |
+
$serviceLabel = $type;
|
298 |
+
if (isset($labels[$type])) {
|
299 |
+
$serviceLabel = $labels[$type];
|
300 |
+
}
|
301 |
+
|
302 |
+
// check url
|
303 |
+
$url = $account->getUrlForType($type);
|
304 |
+
if (!$url) {
|
305 |
+
Mage::throwException(Mage::helper('emvcore')->__('Please define a valid url for %s !', $serviceLabel));
|
306 |
+
}
|
307 |
+
|
308 |
+
return $url;
|
309 |
+
}
|
310 |
+
|
311 |
+
/**
|
312 |
+
* @param Emv_Core_Model_DataProcessing_Process $process
|
313 |
+
* @return string
|
314 |
+
*/
|
315 |
+
public function getLogUrlForProcess(Emv_Core_Model_DataProcessing_Process $process)
|
316 |
+
{
|
317 |
+
return Mage::getModel('adminhtml/url')->getUrl('emv_core/dataProcessing/log', array('id' => $process->getId()));
|
318 |
+
}
|
319 |
}
|
@@ -18,6 +18,22 @@ class Emv_Core_Model_Account extends Mage_Core_Model_Abstract
|
|
18 |
const URL_BATCH_MEMBER_SERVICE_TYPE = 'batch_member';
|
19 |
const URL_MEMBER_SERVICE_TYPE = 'member';
|
20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
/**
|
22 |
* Constructor
|
23 |
*
|
18 |
const URL_BATCH_MEMBER_SERVICE_TYPE = 'batch_member';
|
19 |
const URL_MEMBER_SERVICE_TYPE = 'member';
|
20 |
|
21 |
+
/**
|
22 |
+
* Prefix of model events names
|
23 |
+
*
|
24 |
+
* @var string
|
25 |
+
*/
|
26 |
+
protected $_eventPrefix = 'emv_account';
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Parameter name in event
|
30 |
+
*
|
31 |
+
* In observe method you can use $observer->getEvent()->getObject() in this case
|
32 |
+
*
|
33 |
+
* @var string
|
34 |
+
*/
|
35 |
+
protected $_eventObject = 'emv_account';
|
36 |
+
|
37 |
/**
|
38 |
* Constructor
|
39 |
*
|
@@ -89,19 +89,6 @@ abstract class Emv_Core_Model_Adminhtml_System_Config_Backend_Account_Abstract e
|
|
89 |
*/
|
90 |
protected function _checkAndGetUrlForType(Emv_Core_Model_Account $account, $type)
|
91 |
{
|
92 |
-
|
93 |
-
$labels = Emv_Core_Model_Account::getUrlTypesAndLabels();
|
94 |
-
$serviceLabel = $type;
|
95 |
-
if (isset($labels[$type])) {
|
96 |
-
$serviceLabel = $labels[$type];
|
97 |
-
}
|
98 |
-
|
99 |
-
// check url
|
100 |
-
$url = $account->getUrlForType($type);
|
101 |
-
if (!$url) {
|
102 |
-
Mage::throwException(Mage::helper('emvcore')->__('Please define a valid url for %s !', $serviceLabel));
|
103 |
-
}
|
104 |
-
|
105 |
-
return $url;
|
106 |
}
|
107 |
}
|
89 |
*/
|
90 |
protected function _checkAndGetUrlForType(Emv_Core_Model_Account $account, $type)
|
91 |
{
|
92 |
+
return Mage::helper('emvcore')->checkAndGetUrlForType($account, $type);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
93 |
}
|
94 |
}
|
@@ -0,0 +1,87 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Cron Expression Backend Model
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
+
*/
|
9 |
+
class Emv_Core_Model_Adminhtml_System_Config_Backend_Cron extends Mage_Core_Model_Config_Data
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Crontab expression path - please define an appropriate path in order to make this backend work
|
13 |
+
* @var string
|
14 |
+
*/
|
15 |
+
protected $_crontabPath = '';
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Save a formated crontime in core_config_data
|
19 |
+
*
|
20 |
+
* @see Mage_Core_Model_Abstract::_afterSave()
|
21 |
+
*/
|
22 |
+
protected function _afterSave()
|
23 |
+
{
|
24 |
+
if ($this->_crontabPath) {
|
25 |
+
$cronConfigModel = Mage::getModel('core/config_data')
|
26 |
+
->load($this->_crontabPath, 'path');
|
27 |
+
|
28 |
+
// if the cron is disabled, we remove the cron expression to avoid launching it again
|
29 |
+
$enabled = (bool)$this->getFieldsetDataValue('enabled');
|
30 |
+
if (!$enabled) {
|
31 |
+
if ($cronConfigModel->getConfigId()) {
|
32 |
+
$cronConfigModel->delete();
|
33 |
+
}
|
34 |
+
return false;
|
35 |
+
}
|
36 |
+
|
37 |
+
$frequencyDaily = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_DAILY;
|
38 |
+
$frequencyWeekly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_WEEKLY;
|
39 |
+
$frequencyMonthly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_MONTHLY;
|
40 |
+
|
41 |
+
// get time and frequency
|
42 |
+
$time = $this->getFieldsetDataValue('time');
|
43 |
+
$frequency = $this->getFieldsetDataValue('frequency');
|
44 |
+
|
45 |
+
$monthlySetting = '*';
|
46 |
+
if ($frequency == $frequencyMonthly) {
|
47 |
+
$dateSetting = (int)$this->getFieldsetDataValue('date');
|
48 |
+
if ($dateSetting) {
|
49 |
+
$monthlySetting = $dateSetting;
|
50 |
+
} else {
|
51 |
+
// trigger cron process at the first day of the month
|
52 |
+
$monthlySetting = 1;
|
53 |
+
}
|
54 |
+
}
|
55 |
+
|
56 |
+
$weeklySetting = '*';
|
57 |
+
if ($frequency == $frequencyWeekly) {
|
58 |
+
$daySetting = (int)$this->getFieldsetDataValue('day');
|
59 |
+
if ($daySetting) {
|
60 |
+
$weeklySetting = $daySetting;
|
61 |
+
} else {
|
62 |
+
// trigger cron process at the first day of the week
|
63 |
+
$weeklySetting = 1;
|
64 |
+
}
|
65 |
+
}
|
66 |
+
|
67 |
+
// build cron expression string
|
68 |
+
$cronExprArray = array(
|
69 |
+
intval($time[1]), // Minute
|
70 |
+
intval($time[0]), // Hour
|
71 |
+
$monthlySetting, // Day of the Month
|
72 |
+
'*', // Month of the Year
|
73 |
+
$weeklySetting, // Day of the Week
|
74 |
+
);
|
75 |
+
$cronExprString = join(' ', $cronExprArray);
|
76 |
+
|
77 |
+
try {
|
78 |
+
$cronConfigModel
|
79 |
+
->setValue($cronExprString)
|
80 |
+
->setPath($this->_crontabPath)
|
81 |
+
->save();
|
82 |
+
} catch (Exception $e) {
|
83 |
+
Mage::throwException(Mage::helper('emvdatasync')->__('Unable to save the cron expression for scheduled exports'));
|
84 |
+
}
|
85 |
+
}
|
86 |
+
}
|
87 |
+
}
|
@@ -7,7 +7,7 @@
|
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
*/
|
10 |
-
class
|
11 |
{
|
12 |
public function toOptionArray()
|
13 |
{
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
*/
|
10 |
+
class Emv_Core_Model_Adminhtml_System_Config_Source_Account
|
11 |
{
|
12 |
public function toOptionArray()
|
13 |
{
|
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Date of the month source for Cron configuration
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
class Emv_Core_Model_Adminhtml_System_Config_Source_CronDate
|
12 |
+
{
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
protected static $_options;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @return array
|
21 |
+
*/
|
22 |
+
public function toOptionArray()
|
23 |
+
{
|
24 |
+
if (!self::$_options) {
|
25 |
+
self::$_options = array();
|
26 |
+
|
27 |
+
for ($i = 1; $i < 32; $i++) {
|
28 |
+
self::$_options[] = array(
|
29 |
+
'label' => $i,
|
30 |
+
'value' => $i,
|
31 |
+
);
|
32 |
+
}
|
33 |
+
}
|
34 |
+
return self::$_options;
|
35 |
+
}
|
36 |
+
}
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Day of the week source for cron configuration
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*
|
10 |
+
*/
|
11 |
+
class Emv_Core_Model_Adminhtml_System_Config_Source_CronDay
|
12 |
+
{
|
13 |
+
|
14 |
+
/**
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
protected static $_options;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @return array
|
21 |
+
*/
|
22 |
+
public function toOptionArray()
|
23 |
+
{
|
24 |
+
if (!self::$_options) {
|
25 |
+
self::$_options = array(
|
26 |
+
array(
|
27 |
+
'label' => Mage::helper('cron')->__('Monday'),
|
28 |
+
'value' => 1,
|
29 |
+
),
|
30 |
+
array(
|
31 |
+
'label' => Mage::helper('cron')->__('Tuesday'),
|
32 |
+
'value' => 2,
|
33 |
+
),
|
34 |
+
array(
|
35 |
+
'label' => Mage::helper('cron')->__('Wednesday'),
|
36 |
+
'value' => 3,
|
37 |
+
),
|
38 |
+
array(
|
39 |
+
'label' => Mage::helper('cron')->__('Thursday'),
|
40 |
+
'value' => 4,
|
41 |
+
),
|
42 |
+
array(
|
43 |
+
'label' => Mage::helper('cron')->__('Friday'),
|
44 |
+
'value' => 5,
|
45 |
+
),
|
46 |
+
array(
|
47 |
+
'label' => Mage::helper('cron')->__('Saturday'),
|
48 |
+
'value' => 6,
|
49 |
+
),
|
50 |
+
array(
|
51 |
+
'label' => Mage::helper('cron')->__('Sunday'),
|
52 |
+
'value' => 0,
|
53 |
+
),
|
54 |
+
);
|
55 |
+
}
|
56 |
+
return self::$_options;
|
57 |
+
}
|
58 |
+
}
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Data Process Exception
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Core_Model_DataProcessing_Exception extends Zend_Exception
|
11 |
+
{
|
12 |
+
}
|
@@ -0,0 +1,335 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Process Model
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Core_Model_DataProcessing_Process extends Mage_Core_Model_Abstract
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* State constants
|
14 |
+
*/
|
15 |
+
const STATE_NEW = 0;
|
16 |
+
const STATE_PROCESSING = 3;
|
17 |
+
const STATE_FAILED = 5;
|
18 |
+
const STATE_SUCCESS = 10;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Working dir constant
|
22 |
+
*/
|
23 |
+
const DATAPROCESSING_DIR = 'dataprocessing';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Type Constant
|
27 |
+
*/
|
28 |
+
const TYPE_DATA_SYNC = 'data_sync';
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Process log
|
32 |
+
* @var Emv_Core_Model_DataProcessing_Process_Log
|
33 |
+
*/
|
34 |
+
protected $_log = null;
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Get base directory for the module
|
38 |
+
*
|
39 |
+
* @return string
|
40 |
+
*/
|
41 |
+
public static function getBaseDir()
|
42 |
+
{
|
43 |
+
$path = Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
44 |
+
. DS . Emv_Core_Helper_Data::BASE_WORKING_DIR
|
45 |
+
. DS . self::DATAPROCESSING_DIR;
|
46 |
+
|
47 |
+
$args = array(
|
48 |
+
'path' => $path,
|
49 |
+
);
|
50 |
+
$mageFile = new Varien_Io_File();
|
51 |
+
$mageFile->setAllowCreateFolders(true);
|
52 |
+
$mageFile->open($args);
|
53 |
+
|
54 |
+
return $path;
|
55 |
+
}
|
56 |
+
|
57 |
+
/**
|
58 |
+
* Retrieve relative path by given file name
|
59 |
+
*
|
60 |
+
* @param string $fileName file name
|
61 |
+
*
|
62 |
+
* @return string
|
63 |
+
*/
|
64 |
+
public static function getRelativePath($fileName)
|
65 |
+
{
|
66 |
+
$baseDir = self::getBaseDir();
|
67 |
+
if (substr($fileName, 0, strlen($baseDir)) == $baseDir) {
|
68 |
+
$fileName = substr($fileName, strlen($baseDir) - strlen($fileName));
|
69 |
+
}
|
70 |
+
return $fileName;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* Init resource model
|
75 |
+
*
|
76 |
+
* @return void
|
77 |
+
*/
|
78 |
+
protected function _construct()
|
79 |
+
{
|
80 |
+
$this->_init('emvcore/dataProcessing_process');
|
81 |
+
$this->setState(self::STATE_NEW);
|
82 |
+
$this->setCreatedAt(Mage::getModel('core/date')->gmtDate());
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Update status of the process
|
87 |
+
*
|
88 |
+
* @param int $status
|
89 |
+
*
|
90 |
+
* @return void
|
91 |
+
*/
|
92 |
+
public function updateStatus($status)
|
93 |
+
{
|
94 |
+
$this->setStatus($status);
|
95 |
+
$this->setUpdatedAt(Mage::getModel('core/date')->gmtDate());
|
96 |
+
$this->save();
|
97 |
+
}
|
98 |
+
|
99 |
+
/**
|
100 |
+
* Change state of the process
|
101 |
+
*
|
102 |
+
* @param int $state
|
103 |
+
*
|
104 |
+
* @return void
|
105 |
+
*/
|
106 |
+
public function changeState($state)
|
107 |
+
{
|
108 |
+
if (in_array($state, array_keys($this->getStatesArray()))) {
|
109 |
+
$this->setState($state);
|
110 |
+
$this->setUpdatedAt(Mage::getModel('core/date')->gmtDate());
|
111 |
+
$this->save();
|
112 |
+
}
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Run process
|
117 |
+
*
|
118 |
+
* @return void
|
119 |
+
*/
|
120 |
+
public function run()
|
121 |
+
{
|
122 |
+
$this->setState(self::STATE_PROCESSING);
|
123 |
+
$this->setStatus(0);
|
124 |
+
$this->save();
|
125 |
+
}
|
126 |
+
|
127 |
+
/**
|
128 |
+
* Finalize process
|
129 |
+
*
|
130 |
+
* @param Exception $exception
|
131 |
+
* @param int $state
|
132 |
+
*
|
133 |
+
* @return void
|
134 |
+
*/
|
135 |
+
public function finalize(Exception $exception = null, $state = null)
|
136 |
+
{
|
137 |
+
if (is_null($state) || !in_array($state, array_keys($this->getStatesArray()))) {
|
138 |
+
if (is_null($exception)) {
|
139 |
+
$this->setState(self::STATE_SUCCESS);
|
140 |
+
} else {
|
141 |
+
$this->setState(self::STATE_FAILED);
|
142 |
+
}
|
143 |
+
} else {
|
144 |
+
$this->setState($state);
|
145 |
+
}
|
146 |
+
$this->setTerminatedAt(Mage::getModel('core/date')->gmtDate());
|
147 |
+
$this->setStatus(100);
|
148 |
+
$this->save();
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Kill process in case of exception
|
153 |
+
*
|
154 |
+
* @return void
|
155 |
+
*/
|
156 |
+
public function kill()
|
157 |
+
{
|
158 |
+
$this->setState(self::STATE_FAILED);
|
159 |
+
$this->setTerminatedAt(Mage::getModel('core/date')->gmtDate());
|
160 |
+
$this->setStatus(100);
|
161 |
+
$this->save();
|
162 |
+
}
|
163 |
+
|
164 |
+
/**
|
165 |
+
* Get states array
|
166 |
+
*
|
167 |
+
* @return array
|
168 |
+
*/
|
169 |
+
public function getStatesArray()
|
170 |
+
{
|
171 |
+
return array(
|
172 |
+
self::STATE_NEW => Mage::helper('emvcore')->__('New'),
|
173 |
+
self::STATE_PROCESSING => Mage::helper('emvcore')->__('Processing'),
|
174 |
+
self::STATE_FAILED => Mage::helper('emvcore')->__('Failed'),
|
175 |
+
self::STATE_SUCCESS => Mage::helper('emvcore')->__('Success')
|
176 |
+
);
|
177 |
+
}
|
178 |
+
|
179 |
+
/**
|
180 |
+
* Get base process dir
|
181 |
+
*
|
182 |
+
* @return string
|
183 |
+
*/
|
184 |
+
public function getProcessDir()
|
185 |
+
{
|
186 |
+
$processDir = self::getBaseDir() . DS . $this->getId();
|
187 |
+
if (!is_dir($processDir)) {
|
188 |
+
mkdir($processDir);
|
189 |
+
}
|
190 |
+
return $processDir;
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* Get log file name
|
195 |
+
*
|
196 |
+
* @return string
|
197 |
+
*/
|
198 |
+
public function getLogFileName()
|
199 |
+
{
|
200 |
+
return $this->getProcessDir().DS.'log.txt';
|
201 |
+
}
|
202 |
+
|
203 |
+
/**
|
204 |
+
* Set log object
|
205 |
+
*
|
206 |
+
* @param Emv_Core_Model_DataProcessing_Process_Log $log
|
207 |
+
*
|
208 |
+
* @return void
|
209 |
+
*/
|
210 |
+
protected function _setLog(Emv_Core_Model_DataProcessing_Process_Log $log)
|
211 |
+
{
|
212 |
+
$this->_log = $log;
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* Get report log object
|
217 |
+
*
|
218 |
+
* @return Emv_Core_Model_DataProcessing_Process_Log
|
219 |
+
*/
|
220 |
+
public function getLog()
|
221 |
+
{
|
222 |
+
return $this->_log;
|
223 |
+
}
|
224 |
+
|
225 |
+
/**
|
226 |
+
* Get log content
|
227 |
+
*
|
228 |
+
* @return string
|
229 |
+
*/
|
230 |
+
public function getLogContent()
|
231 |
+
{
|
232 |
+
return file_get_contents($this->getLogFileName());
|
233 |
+
}
|
234 |
+
|
235 |
+
/**
|
236 |
+
* Init log object
|
237 |
+
*
|
238 |
+
* @param string $className
|
239 |
+
*
|
240 |
+
* @return void
|
241 |
+
* @throws Emv_Core_Model_DataProcessing_Exception
|
242 |
+
*/
|
243 |
+
public function initLog($className = null)
|
244 |
+
{
|
245 |
+
if (is_null($className)) {
|
246 |
+
$className = 'emvcore/dataProcessing_process_log';
|
247 |
+
}
|
248 |
+
$log = Mage::getModel($className);
|
249 |
+
if (!($log instanceof Emv_Core_Model_DataProcessing_Process_Log)) {
|
250 |
+
throw new Emv_Core_Model_DataProcessing_Exception('Can not initialize a log');
|
251 |
+
}
|
252 |
+
$logFileName = $this->getLogFileName();
|
253 |
+
file_put_contents($logFileName, '');
|
254 |
+
$log->init($logFileName);
|
255 |
+
$this->_setLog($log);
|
256 |
+
}
|
257 |
+
|
258 |
+
/**
|
259 |
+
* Check if log data can be retrieved
|
260 |
+
*
|
261 |
+
* @return boolean
|
262 |
+
*/
|
263 |
+
public function checkLogData()
|
264 |
+
{
|
265 |
+
return is_readable($this->getLogFileName());
|
266 |
+
}
|
267 |
+
|
268 |
+
/**
|
269 |
+
* Delete process with related resources
|
270 |
+
*
|
271 |
+
* @return void
|
272 |
+
* @see Mage_Core_Model_Abstract::delete()
|
273 |
+
*/
|
274 |
+
public function delete()
|
275 |
+
{
|
276 |
+
try {
|
277 |
+
$resources = array(
|
278 |
+
$this->getLogFileName(),
|
279 |
+
$this->getProcessDir()
|
280 |
+
);
|
281 |
+
|
282 |
+
foreach ($resources as $resource) {
|
283 |
+
if (file_exists($resource)) {
|
284 |
+
if (is_dir($resource)) {
|
285 |
+
rmdir($resource);
|
286 |
+
} else {
|
287 |
+
unlink($resource);
|
288 |
+
}
|
289 |
+
}
|
290 |
+
}
|
291 |
+
} catch (Exception $e) {
|
292 |
+
Mage::logException($e);
|
293 |
+
Mage::throwException(
|
294 |
+
Mage::helper('emvcore')->__(
|
295 |
+
'Unable to delete resources related to the process'
|
296 |
+
)
|
297 |
+
);
|
298 |
+
}
|
299 |
+
|
300 |
+
parent::delete();
|
301 |
+
}
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Set output information
|
305 |
+
* @param array $output
|
306 |
+
* @return Emv_Core_Model_DataProcessing_Process
|
307 |
+
*/
|
308 |
+
public function setOutputInformation(array $output)
|
309 |
+
{
|
310 |
+
foreach ($output as $dataInfo) {
|
311 |
+
$this->addOutputInformation($output);
|
312 |
+
}
|
313 |
+
return $this;
|
314 |
+
}
|
315 |
+
|
316 |
+
/**
|
317 |
+
* @param array $output
|
318 |
+
* @throws Emv_Core_Model_DataProcessing_Exception
|
319 |
+
* @return Emv_Core_Model_DataProcessing_Process
|
320 |
+
*/
|
321 |
+
public function addOutputInformation(array $output)
|
322 |
+
{
|
323 |
+
if (!isset($output['filename']) || !isset($output['path']) || !isset($output['label']) ) {
|
324 |
+
throw new Emv_Core_Model_DataProcessing_Exception('Your output information is not correct');
|
325 |
+
}
|
326 |
+
|
327 |
+
if (!isset($this->_data['output_information'])) {
|
328 |
+
$this->_data['output_information'] = array();
|
329 |
+
}
|
330 |
+
|
331 |
+
$this->_data['output_information'][] = $output;
|
332 |
+
|
333 |
+
return $this;
|
334 |
+
}
|
335 |
+
}
|
@@ -0,0 +1,102 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Process Log Model
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Core_Model_DataProcessing_Process_Log
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Log filename
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
protected $_filename;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Log object
|
20 |
+
* @var Zend_Log
|
21 |
+
*/
|
22 |
+
private $_log = null;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Init log with a name for a log file
|
26 |
+
*
|
27 |
+
* @param string $filename
|
28 |
+
*
|
29 |
+
* @return void
|
30 |
+
* @throws Exception
|
31 |
+
*/
|
32 |
+
public function init($filename)
|
33 |
+
{
|
34 |
+
if (empty($filename) || !is_writeable($filename)) {
|
35 |
+
throw new Exception('Log file is empty or not writeable');
|
36 |
+
}
|
37 |
+
$this->_filename = $filename;
|
38 |
+
$format = '%timestamp% %priorityName% : %message%' . PHP_EOL;
|
39 |
+
$writer = new Zend_Log_Writer_Stream($this->_filename);
|
40 |
+
$writer->setFormatter(new Zend_Log_Formatter_Simple($format));
|
41 |
+
$this->_log = new Zend_Log($writer);
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Get filename
|
46 |
+
*
|
47 |
+
* @return string
|
48 |
+
*/
|
49 |
+
public function getFileName()
|
50 |
+
{
|
51 |
+
return $this->_filename;
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Put log message
|
56 |
+
*
|
57 |
+
* @param string $message
|
58 |
+
* @param int $level
|
59 |
+
*
|
60 |
+
* @return void
|
61 |
+
*/
|
62 |
+
public function log($message, $level = null)
|
63 |
+
{
|
64 |
+
$this->_log->log(print_r($message, 1), $level, $this->_filename);
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Put error message
|
69 |
+
*
|
70 |
+
* @param string $message
|
71 |
+
*
|
72 |
+
* @return void
|
73 |
+
*/
|
74 |
+
public function error($message)
|
75 |
+
{
|
76 |
+
$this->log($message, Zend_Log::ERR);
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Put warning message
|
81 |
+
*
|
82 |
+
* @param string $message
|
83 |
+
*
|
84 |
+
* @return void
|
85 |
+
*/
|
86 |
+
public function warning($message)
|
87 |
+
{
|
88 |
+
$this->log($message, Zend_Log::WARN);
|
89 |
+
}
|
90 |
+
|
91 |
+
/**
|
92 |
+
* Put info message
|
93 |
+
*
|
94 |
+
* @param string $message
|
95 |
+
*
|
96 |
+
* @return void
|
97 |
+
*/
|
98 |
+
public function info($message)
|
99 |
+
{
|
100 |
+
$this->log($message, Zend_Log::INFO);
|
101 |
+
}
|
102 |
+
}
|
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Abstract Profile
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
abstract class Emv_Core_Model_DataProcessing_Profile
|
11 |
+
implements Emv_Core_Model_DataProcessing_Profile_Interface
|
12 |
+
{
|
13 |
+
/**
|
14 |
+
* Profile type
|
15 |
+
* @var string
|
16 |
+
*/
|
17 |
+
protected $_type = 'profile';
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Profile title
|
21 |
+
* @var string
|
22 |
+
*/
|
23 |
+
protected $_title = 'Profile';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Current process
|
27 |
+
* @var Emv_Core_Model_DataProcessing_Process
|
28 |
+
*/
|
29 |
+
protected $_process = null;
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Process class name
|
33 |
+
* @var string
|
34 |
+
*/
|
35 |
+
protected $_processClassName = 'emvcore/dataProcessing_process';
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Class name for log
|
39 |
+
* @var string
|
40 |
+
*/
|
41 |
+
protected $_logClassName = null;
|
42 |
+
|
43 |
+
protected $_inputData = array();
|
44 |
+
|
45 |
+
protected $_isInitialized = false;
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Init profile
|
49 |
+
*
|
50 |
+
* @param Emv_Core_Model_DataProcessing_Process $process
|
51 |
+
*
|
52 |
+
* @return void
|
53 |
+
* @throws Exception
|
54 |
+
*/
|
55 |
+
public function init(Emv_Core_Model_DataProcessing_Process $process = null)
|
56 |
+
{
|
57 |
+
$this->_validateInit($process);
|
58 |
+
$process->initLog($this->_logClassName);
|
59 |
+
$this->_process = $process;
|
60 |
+
$this->_isInitialized = true;
|
61 |
+
Mage::dispatchEvent('smartfocus_dataprocessing_profile_after_init', array('profile' => $this));
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* (non-PHPdoc)
|
66 |
+
* @see Emv_Core_Model_DataProcessing_Profile_Interface::getInputData()
|
67 |
+
*/
|
68 |
+
public function getInputData()
|
69 |
+
{
|
70 |
+
return $this->_inputData;
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* (non-PHPdoc)
|
75 |
+
* @see Emv_Core_Model_DataProcessing_Profile_Interface::setInputData()
|
76 |
+
*/
|
77 |
+
public function setInputData(array $input)
|
78 |
+
{
|
79 |
+
$this->_inputData = $input;
|
80 |
+
return $this;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* (non-PHPdoc)
|
85 |
+
* @see Emv_Core_Model_DataProcessing_Profile_Interface::getProcess()
|
86 |
+
*/
|
87 |
+
public function getProcess()
|
88 |
+
{
|
89 |
+
return $this->_process;
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Validate process used to profile init
|
94 |
+
*
|
95 |
+
* @param Emv_Core_Model_DataProcessing_Process $process
|
96 |
+
*
|
97 |
+
* @return void
|
98 |
+
* @throws Emv_Core_Model_DataProcessing_Exception
|
99 |
+
*/
|
100 |
+
private function _validateInit(Emv_Core_Model_DataProcessing_Process $process = null)
|
101 |
+
{
|
102 |
+
if ($this->_isInitialized) {
|
103 |
+
throw new Emv_Core_Model_DataProcessing_Exception('Profile is already intialized');
|
104 |
+
}
|
105 |
+
if (is_null($process)) {
|
106 |
+
throw new Emv_Core_Model_DataProcessing_Exception('Process can not be null');
|
107 |
+
}
|
108 |
+
if (!($process instanceof Varien_Object)) {
|
109 |
+
throw new Emv_Core_Model_DataProcessing_Exception('Process must be an instance of Varien_Object class');
|
110 |
+
}
|
111 |
+
if (($process instanceof Emv_Core_Model_DataProcessing_Process) && (!$process->getId())) {
|
112 |
+
throw new Emv_Core_Model_DataProcessing_Exception('Process should be registered before profile execution');
|
113 |
+
}
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Get default profile process
|
118 |
+
*
|
119 |
+
* @return Emv_Core_Model_DataProcessing_Process $process
|
120 |
+
*/
|
121 |
+
public function initProcess()
|
122 |
+
{
|
123 |
+
$process = Mage::getModel($this->_processClassName);
|
124 |
+
$process->setTitle($this->_title);
|
125 |
+
$process->setType($this->_type);
|
126 |
+
|
127 |
+
$process->save();
|
128 |
+
return $process;
|
129 |
+
}
|
130 |
+
|
131 |
+
/**
|
132 |
+
* Run profile
|
133 |
+
*
|
134 |
+
* @return void
|
135 |
+
* @throws Emv_Core_Model_DataProcessing_Exception
|
136 |
+
*/
|
137 |
+
public function run()
|
138 |
+
{
|
139 |
+
Mage::dispatchEvent('smartfocus_dataprocessing_profile_before_run', array('profile' => $this));
|
140 |
+
$this->checkLocks();
|
141 |
+
try {
|
142 |
+
if (!$this->_isInitialized) {
|
143 |
+
$this->init($this->getDefaultProcess());
|
144 |
+
}
|
145 |
+
} catch (Exception $e) {
|
146 |
+
$this->_finalize($e);
|
147 |
+
throw $e;
|
148 |
+
}
|
149 |
+
|
150 |
+
try {
|
151 |
+
$this->getProcess()->run();
|
152 |
+
$this->_run();
|
153 |
+
} catch (Exception $e) {
|
154 |
+
$this->_finalize($e);
|
155 |
+
Mage::dispatchEvent('smartfocus_dataprocessing_profile_after_failure', array('profile' => $this));
|
156 |
+
throw $e;
|
157 |
+
}
|
158 |
+
$this->_finalize();
|
159 |
+
Mage::dispatchEvent('smartfocus_dataprocessing_profile_after_success', array('profile' => $this));
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* General finalize function
|
164 |
+
*
|
165 |
+
* @param Exception $exception
|
166 |
+
*
|
167 |
+
* @return void
|
168 |
+
*/
|
169 |
+
protected function _finalize(Exception $exception = null)
|
170 |
+
{
|
171 |
+
$this->getProcess()->finalize($exception);
|
172 |
+
$this->_afterFinalize($exception);
|
173 |
+
Mage::dispatchEvent('smartfocus_dataprocessing_profile_after_finalize', array('profile' => $this));
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Custom _finalization function.
|
178 |
+
* Allows to add some logic or manage the exception in some special way.
|
179 |
+
* Implementation is not required.
|
180 |
+
*
|
181 |
+
* @param Exception $exception
|
182 |
+
*
|
183 |
+
* @return void
|
184 |
+
*/
|
185 |
+
protected function _afterFinalize(Exception $exception = null)
|
186 |
+
{
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Main profile function. Launch a profile
|
191 |
+
*
|
192 |
+
* @return void
|
193 |
+
*/
|
194 |
+
abstract protected function _run();
|
195 |
+
}
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Data Processing Profile interface
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
interface Emv_Core_Model_DataProcessing_Profile_Interface
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Intialize Process
|
14 |
+
* @return Emv_Core_Model_DataProcessing_Process
|
15 |
+
*/
|
16 |
+
public function initProcess();
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Initialize Profile
|
20 |
+
* @param Emv_Core_Model_DataProcessing_Process $process
|
21 |
+
*/
|
22 |
+
public function init(Emv_Core_Model_DataProcessing_Process $process = null);
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Get input data has been set up
|
26 |
+
* @return array
|
27 |
+
*/
|
28 |
+
public function getInputData();
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Set input data for profile
|
32 |
+
* @param array $input
|
33 |
+
*/
|
34 |
+
public function setInputData(array $input);
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Get associated process
|
38 |
+
* @return null | Emv_Core_Model_DataProcessing_Process
|
39 |
+
*/
|
40 |
+
public function getProcess();
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Run Profile
|
44 |
+
*/
|
45 |
+
public function run();
|
46 |
+
}
|
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Process Resource Model
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Core_Model_Mysql4_DataProcessing_Process extends Mage_Core_Model_Mysql4_Abstract
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Serializeable field: output_information
|
14 |
+
*
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
protected $_serializableFields = array(
|
18 |
+
'output_information' => array(array(), array())
|
19 |
+
);
|
20 |
+
|
21 |
+
/**
|
22 |
+
* (non-PHPdoc)
|
23 |
+
* @see Mage_Core_Model_Resource_Abstract::_construct()
|
24 |
+
*/
|
25 |
+
protected function _construct()
|
26 |
+
{
|
27 |
+
$this->_init('emvcore/dataprocessing_process','id');
|
28 |
+
}
|
29 |
+
}
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Process Resource Collection
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Core_Model_Mysql4_DataProcessing_Process_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
|
11 |
+
{
|
12 |
+
protected function _construct()
|
13 |
+
{
|
14 |
+
$this->_init('emvcore/dataProcessing_process','emvcore/dataProcessing_process');
|
15 |
+
}
|
16 |
+
}
|
@@ -119,6 +119,7 @@ abstract class Emv_Core_Model_Service_Abstract extends Mage_Core_Model_Abstract
|
|
119 |
/**
|
120 |
* Check if API credential is valid. Return the token if success
|
121 |
*
|
|
|
122 |
* @throws Exception - in case of errors
|
123 |
* @return string
|
124 |
*/
|
119 |
/**
|
120 |
* Check if API credential is valid. Return the token if success
|
121 |
*
|
122 |
+
* @throws EmailVision_Api_Exception $exception api error
|
123 |
* @throws Exception - in case of errors
|
124 |
* @return string
|
125 |
*/
|
@@ -54,7 +54,7 @@ class Emv_Core_Model_Service_Notification extends Mage_Core_Model_Abstract
|
|
54 |
}
|
55 |
|
56 |
/**
|
57 |
-
* Send Email with given template.
|
58 |
*
|
59 |
* @param string $encrypt
|
60 |
* @param string $notificationId
|
54 |
}
|
55 |
|
56 |
/**
|
57 |
+
* Send Email with given template. The rest api will be used
|
58 |
*
|
59 |
* @param string $encrypt
|
60 |
* @param string $notificationId
|
@@ -42,9 +42,9 @@ class Emv_Core_Model_Service_Transactional extends Emv_Core_Model_Service_Abstra
|
|
42 |
public function getTemplateById($templateId)
|
43 |
{
|
44 |
$emvTemplate = null;
|
45 |
-
$
|
46 |
try {
|
47 |
-
$emvTemplate = $
|
48 |
} catch (Exception $e) {
|
49 |
// log errors
|
50 |
Mage::logException($e);
|
42 |
public function getTemplateById($templateId)
|
43 |
{
|
44 |
$emvTemplate = null;
|
45 |
+
$service = $this->getApiService();
|
46 |
try {
|
47 |
+
$emvTemplate = $service->getTemplateById($templateId);
|
48 |
} catch (Exception $e) {
|
49 |
// log errors
|
50 |
Mage::logException($e);
|
@@ -3,7 +3,7 @@
|
|
3 |
* This controller is used to manage all account view (grid list, edit/new form)
|
4 |
*
|
5 |
* @category Emv
|
6 |
-
* @package
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
*/
|
3 |
* This controller is used to manage all account view (grid list, edit/new form)
|
4 |
*
|
5 |
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
*/
|
@@ -0,0 +1,175 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* This controller is used to manage all Data Processing Process view (grid list, edit/new form)
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Core
|
7 |
+
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Core_Adminhtml_DataProcessingController extends Mage_Adminhtml_Controller_Action
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Current process
|
14 |
+
* @var Emv_Core_Model_DataProcessing_Process
|
15 |
+
*/
|
16 |
+
protected $_process = null;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Initialise action
|
20 |
+
* - load all layout
|
21 |
+
* - set active menu SmartFocus
|
22 |
+
*/
|
23 |
+
protected function _initAction()
|
24 |
+
{
|
25 |
+
$this->loadLayout();
|
26 |
+
$this->_setActiveMenu('emailvision/emvcore');
|
27 |
+
// Define module dependent translate
|
28 |
+
$this->setUsedModuleName('Emv_Core');
|
29 |
+
$this->_title(Mage::helper('emvcore')->__('SmartFocus'))
|
30 |
+
->_title(Mage::helper('emvcore')->__('Data Process'));
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Action to display Data Processing Porcess grid
|
35 |
+
*/
|
36 |
+
public function indexAction()
|
37 |
+
{
|
38 |
+
if ($this->getRequest()->getParam('ajax')) {
|
39 |
+
$this->_forward('grid');
|
40 |
+
return;
|
41 |
+
}
|
42 |
+
|
43 |
+
// save all messages from session
|
44 |
+
$this->getLayout()->getMessagesBlock()->setMessages(
|
45 |
+
$this->_getSession()->getMessages()
|
46 |
+
);
|
47 |
+
|
48 |
+
$this->_initAction();
|
49 |
+
$this->_addContent(
|
50 |
+
$this->getLayout()->createBlock('emvcore/adminhtml_dataProcessing_process','process')
|
51 |
+
);
|
52 |
+
$this->renderLayout();
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Data Processing Process Grid action for ajax request
|
57 |
+
*/
|
58 |
+
public function gridAction()
|
59 |
+
{
|
60 |
+
$this->loadLayout();
|
61 |
+
$this->getResponse()->setBody(
|
62 |
+
$this->getLayout()->createBlock('emvcore/adminhtml_dataProcessing_process_grid')->toHtml()
|
63 |
+
);
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Get output file content
|
68 |
+
*
|
69 |
+
* @return void
|
70 |
+
*/
|
71 |
+
public function getOutputFileAction()
|
72 |
+
{
|
73 |
+
try {
|
74 |
+
$fullFileName = base64_decode($this->getRequest()->get('path'));
|
75 |
+
$fileName = base64_decode($this->getRequest()->get('filename'));
|
76 |
+
if (is_readable($fullFileName)) {
|
77 |
+
$content = file_get_contents($fullFileName);
|
78 |
+
return $this->_prepareDownloadResponse($fileName, $content);
|
79 |
+
}
|
80 |
+
} catch (Exception $e) {
|
81 |
+
$this->_getSession()->addError(Mage::helper('emvcore')->__('Error during get output file'));
|
82 |
+
Mage::logException($e);
|
83 |
+
}
|
84 |
+
$this->_redirect('*/dataProcessing/');
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Get log content
|
89 |
+
*
|
90 |
+
* @return void
|
91 |
+
*/
|
92 |
+
public function logAction()
|
93 |
+
{
|
94 |
+
try {
|
95 |
+
$content = $this->_getProcess()->getLogContent();
|
96 |
+
return $this->_prepareDownloadResponse($this->_getProcess()->getId().'-log.txt', $content);
|
97 |
+
} catch (Exception $e) {
|
98 |
+
$this->_getSession()->addError(Mage::helper('emvcore')->__('Error during get process log'));
|
99 |
+
Mage::logException($e);
|
100 |
+
}
|
101 |
+
$this->_redirect('*/dataProcessing/');
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Get current process
|
106 |
+
*
|
107 |
+
* @return Emv_Core_Model_DataProcessing_Process
|
108 |
+
*/
|
109 |
+
protected function _getProcess()
|
110 |
+
{
|
111 |
+
if (is_null($this->_process)) {
|
112 |
+
$processId = $this->getRequest()->get('id');
|
113 |
+
if (empty($processId)) {
|
114 |
+
Mage::throwException('Process is empty');
|
115 |
+
}
|
116 |
+
$process = Mage::getModel('emvcore/dataProcessing_process')->load($processId);
|
117 |
+
if (!$process->getId()) {
|
118 |
+
Mage::throwException('Process does not exist : ' . $processId);
|
119 |
+
}
|
120 |
+
$this->_process = $process;
|
121 |
+
}
|
122 |
+
return $this->_process;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Delete mass action
|
127 |
+
*
|
128 |
+
* @return void
|
129 |
+
*/
|
130 |
+
public function massDeleteAction()
|
131 |
+
{
|
132 |
+
$processIds = $this->getRequest()->getParam('ids');
|
133 |
+
if (!is_array($processIds)) {
|
134 |
+
$this->_getSession()->addError(Mage::helper('emvcore')->__('Please select something!'));
|
135 |
+
} else {
|
136 |
+
$deleted = 0;
|
137 |
+
foreach ($processIds as $processId) {
|
138 |
+
try {
|
139 |
+
$process = Mage::getSingleton('emvcore/dataProcessing_process')->load($processId);
|
140 |
+
$process->delete();
|
141 |
+
$deleted++;
|
142 |
+
} catch (Mage_Core_Exception $e) {
|
143 |
+
$this->_getSession()->addError(
|
144 |
+
Mage::helper('emvcore')->__('Unable to delete the process #%s. Reason: %s', $processId, $e->getMessage())
|
145 |
+
);
|
146 |
+
} catch (Exception $e) {
|
147 |
+
$this->_getSession()->addError(
|
148 |
+
Mage::helper('emvcore')->__('Unable to delete the process #%s', $processId)
|
149 |
+
);
|
150 |
+
Mage::logException($e);
|
151 |
+
}
|
152 |
+
}
|
153 |
+
}
|
154 |
+
if ($deleted > 1) {
|
155 |
+
$this->_getSession()->addSuccess(
|
156 |
+
Mage::helper('emvcore')->__('%s records were successfully deleted', $deleted)
|
157 |
+
);
|
158 |
+
} elseif ($deleted == 1) {
|
159 |
+
$this->_getSession()->addSuccess(
|
160 |
+
Mage::helper('emvcore')->__('One record was successfully deleted')
|
161 |
+
);
|
162 |
+
}
|
163 |
+
$this->_redirect('*/*/');
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Check if having a correct permission
|
168 |
+
*
|
169 |
+
* @return boolean
|
170 |
+
*/
|
171 |
+
protected function _isallowed()
|
172 |
+
{
|
173 |
+
return Mage::getSingleton('admin/session')->isAllowed('emailvision/emvdataprocessing');
|
174 |
+
}
|
175 |
+
}
|
@@ -1,7 +1,7 @@
|
|
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<config>
|
3 |
<menu>
|
4 |
-
<!--
|
5 |
<emailvision translate="title" module="adminhtml">
|
6 |
<title>SmartFocus</title>
|
7 |
<sort_order>999</sort_order>
|
@@ -11,6 +11,11 @@
|
|
11 |
<sort_order>10</sort_order>
|
12 |
<action>emv_core/account</action>
|
13 |
</emvcore>
|
|
|
|
|
|
|
|
|
|
|
14 |
</children>
|
15 |
</emailvision>
|
16 |
</menu>
|
@@ -19,15 +24,19 @@
|
|
19 |
<resources>
|
20 |
<admin>
|
21 |
<children>
|
22 |
-
<!--
|
23 |
<emailvision translate="title" module="emvcore">
|
24 |
<title>SmartFocus</title>
|
25 |
<sort_order>90</sort_order>
|
26 |
<children>
|
27 |
<emvcore translate="title" module="emvcore">
|
28 |
<title>Accounts</title>
|
29 |
-
<sort_order>
|
30 |
</emvcore>
|
|
|
|
|
|
|
|
|
31 |
</children>
|
32 |
</emailvision>
|
33 |
</children>
|
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<config>
|
3 |
<menu>
|
4 |
+
<!-- SmartFocus menu in the back office -->
|
5 |
<emailvision translate="title" module="adminhtml">
|
6 |
<title>SmartFocus</title>
|
7 |
<sort_order>999</sort_order>
|
11 |
<sort_order>10</sort_order>
|
12 |
<action>emv_core/account</action>
|
13 |
</emvcore>
|
14 |
+
<emvdataprocessing translate="title" module="emvcore">
|
15 |
+
<title>Data Process List</title>
|
16 |
+
<sort_order>15</sort_order>
|
17 |
+
<action>emv_core/dataProcessing</action>
|
18 |
+
</emvdataprocessing>
|
19 |
</children>
|
20 |
</emailvision>
|
21 |
</menu>
|
24 |
<resources>
|
25 |
<admin>
|
26 |
<children>
|
27 |
+
<!-- SmartFocus acl -->
|
28 |
<emailvision translate="title" module="emvcore">
|
29 |
<title>SmartFocus</title>
|
30 |
<sort_order>90</sort_order>
|
31 |
<children>
|
32 |
<emvcore translate="title" module="emvcore">
|
33 |
<title>Accounts</title>
|
34 |
+
<sort_order>100</sort_order>
|
35 |
</emvcore>
|
36 |
+
<emvdataprocessing>
|
37 |
+
<title>Data Process List</title>
|
38 |
+
<sort_order>200</sort_order>
|
39 |
+
</emvdataprocessing>
|
40 |
</children>
|
41 |
</emailvision>
|
42 |
</children>
|
@@ -2,7 +2,7 @@
|
|
2 |
<config>
|
3 |
<modules>
|
4 |
<Emv_Core>
|
5 |
-
<version>0.
|
6 |
</Emv_Core>
|
7 |
</modules>
|
8 |
<global>
|
@@ -27,6 +27,9 @@
|
|
27 |
<account>
|
28 |
<table>emv_account</table>
|
29 |
</account>
|
|
|
|
|
|
|
30 |
</entities>
|
31 |
</emvcore_mysql4>
|
32 |
</models>
|
@@ -54,6 +57,13 @@
|
|
54 |
</Emv_Core>
|
55 |
</modules>
|
56 |
</translate>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
57 |
</adminhtml>
|
58 |
<admin>
|
59 |
<routers>
|
2 |
<config>
|
3 |
<modules>
|
4 |
<Emv_Core>
|
5 |
+
<version>0.3.0</version>
|
6 |
</Emv_Core>
|
7 |
</modules>
|
8 |
<global>
|
27 |
<account>
|
28 |
<table>emv_account</table>
|
29 |
</account>
|
30 |
+
<dataprocessing_process>
|
31 |
+
<table>emv_dataprocessing_process</table>
|
32 |
+
</dataprocessing_process>
|
33 |
</entities>
|
34 |
</emvcore_mysql4>
|
35 |
</models>
|
57 |
</Emv_Core>
|
58 |
</modules>
|
59 |
</translate>
|
60 |
+
<layout>
|
61 |
+
<updates>
|
62 |
+
<emvcore>
|
63 |
+
<file>smartfocus/core.xml</file>
|
64 |
+
</emvcore>
|
65 |
+
</updates>
|
66 |
+
</layout>
|
67 |
</adminhtml>
|
68 |
<admin>
|
69 |
<routers>
|
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Custom error handler
|
4 |
+
* Overwrite Magento standard error handler in order to remove lock file in case of fatal error
|
5 |
+
*
|
6 |
+
* @param integer $errno
|
7 |
+
* @param string $errstr
|
8 |
+
* @param string $errfile
|
9 |
+
* @param integer $errline
|
10 |
+
* @throws Exception
|
11 |
+
*/
|
12 |
+
function smartFocusErrorHandler($errno, $errstr, $errfile, $errline){
|
13 |
+
if (strpos($errstr, 'DateTimeZone::__construct')!==false) {
|
14 |
+
// there's no way to distinguish between caught system exceptions and warnings
|
15 |
+
return false;
|
16 |
+
}
|
17 |
+
|
18 |
+
$errno = $errno & error_reporting();
|
19 |
+
if ($errno == 0) {
|
20 |
+
return false;
|
21 |
+
}
|
22 |
+
if (!defined('E_STRICT')) {
|
23 |
+
define('E_STRICT', 2048);
|
24 |
+
}
|
25 |
+
if (!defined('E_RECOVERABLE_ERROR')) {
|
26 |
+
define('E_RECOVERABLE_ERROR', 4096);
|
27 |
+
}
|
28 |
+
if (!defined('E_DEPRECATED')) {
|
29 |
+
define('E_DEPRECATED', 8192);
|
30 |
+
}
|
31 |
+
|
32 |
+
// PEAR specific message handling
|
33 |
+
if (stripos($errfile.$errstr, 'pear') !== false) {
|
34 |
+
// ignore strict and deprecated notices
|
35 |
+
if (($errno == E_STRICT) || ($errno == E_DEPRECATED)) {
|
36 |
+
return true;
|
37 |
+
}
|
38 |
+
// ignore attempts to read system files when open_basedir is set
|
39 |
+
if ($errno == E_WARNING && stripos($errstr, 'open_basedir') !== false) {
|
40 |
+
return true;
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
$errorMessage = '';
|
45 |
+
|
46 |
+
switch($errno){
|
47 |
+
case E_ERROR:
|
48 |
+
$errorMessage .= "Error";
|
49 |
+
break;
|
50 |
+
case E_WARNING:
|
51 |
+
$errorMessage .= "Warning";
|
52 |
+
break;
|
53 |
+
case E_PARSE:
|
54 |
+
$errorMessage .= "Parse Error";
|
55 |
+
break;
|
56 |
+
case E_NOTICE:
|
57 |
+
$errorMessage .= "Notice";
|
58 |
+
break;
|
59 |
+
case E_CORE_ERROR:
|
60 |
+
$errorMessage .= "Core Error";
|
61 |
+
break;
|
62 |
+
case E_CORE_WARNING:
|
63 |
+
$errorMessage .= "Core Warning";
|
64 |
+
break;
|
65 |
+
case E_COMPILE_ERROR:
|
66 |
+
$errorMessage .= "Compile Error";
|
67 |
+
break;
|
68 |
+
case E_COMPILE_WARNING:
|
69 |
+
$errorMessage .= "Compile Warning";
|
70 |
+
break;
|
71 |
+
case E_USER_ERROR:
|
72 |
+
$errorMessage .= "User Error";
|
73 |
+
break;
|
74 |
+
case E_USER_WARNING:
|
75 |
+
$errorMessage .= "User Warning";
|
76 |
+
break;
|
77 |
+
case E_USER_NOTICE:
|
78 |
+
$errorMessage .= "User Notice";
|
79 |
+
break;
|
80 |
+
case E_STRICT:
|
81 |
+
$errorMessage .= "Strict Notice";
|
82 |
+
break;
|
83 |
+
case E_RECOVERABLE_ERROR:
|
84 |
+
$errorMessage .= "Recoverable Error";
|
85 |
+
break;
|
86 |
+
case E_DEPRECATED:
|
87 |
+
$errorMessage .= "Deprecated functionality";
|
88 |
+
break;
|
89 |
+
default:
|
90 |
+
$errorMessage .= "Unknown error ($errno)";
|
91 |
+
break;
|
92 |
+
}
|
93 |
+
|
94 |
+
$errorMessage .= ": {$errstr} in {$errfile} on line {$errline}";
|
95 |
+
if (Mage::getIsDeveloperMode()) {
|
96 |
+
throw new Exception($errorMessage);
|
97 |
+
} else {
|
98 |
+
Mage::log($errorMessage, Zend_Log::ERR);
|
99 |
+
|
100 |
+
// this is specifically to our connector
|
101 |
+
Mage::helper('emvcore')->removeLastLockFileFromRegistry();
|
102 |
+
}
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Customer shut down PHP handler in order to remove lock file
|
107 |
+
*/
|
108 |
+
function smartFocusShutDownPhpHandler()
|
109 |
+
{
|
110 |
+
$error = error_get_last();
|
111 |
+
if (null !== $error)
|
112 |
+
{
|
113 |
+
Mage::log($error, Zend_Log::ERR);
|
114 |
+
|
115 |
+
// this is specifically to our connector
|
116 |
+
Mage::helper('emvcore')->removeLastLockFileFromRegistry();
|
117 |
+
}
|
118 |
+
}
|
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/* @var $this Emv_Emt_Model_Resource_Setup */
|
3 |
+
$this->startSetup();
|
4 |
+
|
5 |
+
$this->run("
|
6 |
+
DROP TABLE IF EXISTS `{$this->getTable('emvcore/dataprocessing_process')}`;
|
7 |
+
CREATE TABLE `{$this->getTable('emvcore/dataprocessing_process')}` (
|
8 |
+
|
9 |
+
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
|
10 |
+
`type` varchar(255) NOT NULL,
|
11 |
+
`title` TEXT NOT NULL,
|
12 |
+
`created_at` datetime NOT NULL,
|
13 |
+
`updated_at` datetime NULL,
|
14 |
+
`terminated_at` datetime NULL,
|
15 |
+
`state` int(10) DEFAULT '0',
|
16 |
+
`status` int(1) DEFAULT '0',
|
17 |
+
`output_information` TEXT NULL,
|
18 |
+
|
19 |
+
PRIMARY KEY (`id`),
|
20 |
+
INDEX `IDX_PROCESS_STATE` (`state`),
|
21 |
+
INDEX `IDX_PROCESS_TYPE` (`type`)
|
22 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
23 |
+
|
24 |
+
");
|
25 |
+
|
26 |
+
$this->endSetup();
|
@@ -9,48 +9,14 @@
|
|
9 |
class Emv_DataSync_Block_Adminhtml_Form_Field_CustomerAttributes extends Mage_Core_Block_Html_Select
|
10 |
{
|
11 |
/**
|
12 |
-
*
|
|
|
|
|
13 |
*/
|
14 |
-
protected
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Get customer attributes array
|
18 |
-
* @param string $attributeId
|
19 |
-
* @return NULL|Ambigous <multitype:, string>
|
20 |
-
*/
|
21 |
-
protected function _getCustomerAttributes($attributeId = null)
|
22 |
{
|
23 |
-
|
24 |
-
|
25 |
-
$customerEntityTypeId = Mage::getModel('eav/entity')->setType('customer')->getTypeId();
|
26 |
-
$customerAddressEntityTypeId = Mage::getModel('eav/entity')->setType('customer_address')->getTypeId();
|
27 |
-
$collection = Mage::getResourceModel('eav/entity_attribute_collection')
|
28 |
-
->addFieldToFilter(
|
29 |
-
'entity_type_id',
|
30 |
-
array(
|
31 |
-
'in' => array($customerEntityTypeId, $customerAddressEntityTypeId)
|
32 |
-
)
|
33 |
-
);
|
34 |
-
|
35 |
-
if ($collection && $collection->count()>0) {
|
36 |
-
foreach ($collection as $item) {
|
37 |
-
if ($item->getEntityTypeId() == $customerAddressEntityTypeId) {
|
38 |
-
$this->_customerAttributes[$item->getAttributeId()] = 'customer_address_'
|
39 |
-
. $item->getAttributeCode();
|
40 |
-
}
|
41 |
-
else {
|
42 |
-
$this->_customerAttributes[$item->getAttributeId()] = $item->getAttributeCode();
|
43 |
-
}
|
44 |
-
}
|
45 |
-
asort($this->_customerAttributes);
|
46 |
-
}
|
47 |
-
}
|
48 |
-
|
49 |
-
if (!is_null($attributeId)) {
|
50 |
-
return isset($this->_customerAttributes[$attributeId]) ? $this->_customerAttributes[$attributeId] : null;
|
51 |
-
}
|
52 |
-
|
53 |
-
return $this->_customerAttributes;
|
54 |
}
|
55 |
|
56 |
/**
|
@@ -69,8 +35,8 @@ class Emv_DataSync_Block_Adminhtml_Form_Field_CustomerAttributes extends Mage_Co
|
|
69 |
public function _toHtml()
|
70 |
{
|
71 |
if (!$this->getOptions()) {
|
72 |
-
foreach ($this->_getCustomerAttributes() as $
|
73 |
-
$this->addOption($
|
74 |
}
|
75 |
}
|
76 |
|
9 |
class Emv_DataSync_Block_Adminhtml_Form_Field_CustomerAttributes extends Mage_Core_Block_Html_Select
|
10 |
{
|
11 |
/**
|
12 |
+
* Get available attributes array
|
13 |
+
*
|
14 |
+
* @return array
|
15 |
*/
|
16 |
+
protected function _getCustomerAttributes()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
{
|
18 |
+
$config = Mage::getModel('emvdatasync/attributeProcessing_config');
|
19 |
+
return $config->toOptionArray();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
}
|
21 |
|
22 |
/**
|
35 |
public function _toHtml()
|
36 |
{
|
37 |
if (!$this->getOptions()) {
|
38 |
+
foreach ($this->_getCustomerAttributes() as $type => $optionValue) {
|
39 |
+
$this->addOption($optionValue['value'], addslashes($optionValue['label']));
|
40 |
}
|
41 |
}
|
42 |
|
@@ -0,0 +1,24 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Subscriber Queue grid container
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
+
*/
|
10 |
+
class Emv_DataSync_Block_Adminhtml_Newsletter_Subscriber extends Mage_Adminhtml_Block_Widget_Grid_Container
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Construct Newsletter Subscriber Queue menu
|
14 |
+
* @see Mage_Adminhtml_Block_Widget_Grid_Container::__construct()
|
15 |
+
*/
|
16 |
+
public function __construct()
|
17 |
+
{
|
18 |
+
parent::__construct();
|
19 |
+
$this->_blockGroup = 'emvdatasync';
|
20 |
+
$this->_controller = 'adminhtml_newsletter_subscriber';
|
21 |
+
$this->_headerText = Mage::helper('emvdatasync')->__('Newsletter Subscriber Queue');
|
22 |
+
$this->_removeButton('add');
|
23 |
+
}
|
24 |
+
}
|
@@ -0,0 +1,255 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Block to manage the subscriber queue
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
+
*/
|
10 |
+
class Emv_DataSync_Block_Adminhtml_Newsletter_Subscriber_Grid extends Mage_Adminhtml_Block_Newsletter_Subscriber_Grid
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Constructor
|
14 |
+
*
|
15 |
+
* Set main configuration of grid
|
16 |
+
*/
|
17 |
+
public function __construct()
|
18 |
+
{
|
19 |
+
Mage_Adminhtml_Block_Widget_Grid::__construct();
|
20 |
+
$this->setId('subscriberGrid');
|
21 |
+
$this->setUseAjax(true);
|
22 |
+
$this->setDefaultSort('queued', 'desc');
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Prepare collection for grid
|
27 |
+
*
|
28 |
+
* @return Mage_Adminhtml_Block_Widget_Grid
|
29 |
+
*/
|
30 |
+
protected function _prepareCollection()
|
31 |
+
{
|
32 |
+
$collection = Mage::getResourceSingleton('newsletter/subscriber_collection');
|
33 |
+
/* @var $collection Mage_Newsletter_Model_Mysql4_Subscriber_Collection */
|
34 |
+
$collection
|
35 |
+
->showCustomerInfo(true)
|
36 |
+
->addSubscriberTypeField()
|
37 |
+
->showStoreInfo();
|
38 |
+
|
39 |
+
if (Mage::getSingleton('emvdatasync/service_dataProcess')->enabledPurchaseInformation()) {
|
40 |
+
$expression = sprintf("IF(%s, %s, %s)", 'purchase.updated_at > main_table.date_last_purchase', 1, 0);
|
41 |
+
$checkSql = new Zend_Db_Expr($expression);
|
42 |
+
|
43 |
+
$tableName = Mage::getSingleton('core/resource')->getTableName('emvdatasync/purchase_info');
|
44 |
+
|
45 |
+
$collection->getSelect()
|
46 |
+
->joinLeft(
|
47 |
+
array('purchase' => $tableName),
|
48 |
+
'purchase.customer_id = main_table.customer_id',
|
49 |
+
array('purchase_validity' => $checkSql)
|
50 |
+
)
|
51 |
+
;
|
52 |
+
$collection->addFilterToMap('purchase_validity', $checkSql);
|
53 |
+
}
|
54 |
+
|
55 |
+
$this->setCollection($collection);
|
56 |
+
|
57 |
+
Mage_Adminhtml_Block_Widget_Grid::_prepareCollection();
|
58 |
+
return $this;
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* Prepare columns for grid
|
63 |
+
* (non-PHPdoc)
|
64 |
+
* @see Mage_Adminhtml_Block_Newsletter_Subscriber_Grid::_prepareColumns()
|
65 |
+
*/
|
66 |
+
protected function _prepareColumns()
|
67 |
+
{
|
68 |
+
$this->addColumn('subscriber_id', array(
|
69 |
+
'header' => Mage::helper('newsletter')->__('ID'),
|
70 |
+
'index' => 'subscriber_id',
|
71 |
+
'width' => '10px',
|
72 |
+
'type' => 'number'
|
73 |
+
));
|
74 |
+
|
75 |
+
$this->addColumn('queued', array(
|
76 |
+
'header' => Mage::helper('emvdatasync')->__('Scheduled'),
|
77 |
+
'width' => '10',
|
78 |
+
'index' => 'queued',
|
79 |
+
'default' => Mage::helper('core')->__('No'),
|
80 |
+
'type' => 'options',
|
81 |
+
'options' => array(
|
82 |
+
1 => Mage::helper('core')->__('Yes'),
|
83 |
+
0 => Mage::helper('core')->__('No'),
|
84 |
+
),
|
85 |
+
));
|
86 |
+
|
87 |
+
$this->addColumn('email', array(
|
88 |
+
'header' => Mage::helper('newsletter')->__('Email'),
|
89 |
+
'index' => 'subscriber_email',
|
90 |
+
'width' => '30',
|
91 |
+
));
|
92 |
+
|
93 |
+
$this->addColumn('type', array(
|
94 |
+
'header' => Mage::helper('newsletter')->__('Type'),
|
95 |
+
'index' => 'type',
|
96 |
+
'type' => 'options',
|
97 |
+
'options' => array(
|
98 |
+
1 => Mage::helper('newsletter')->__('Guest'),
|
99 |
+
2 => Mage::helper('newsletter')->__('Customer')
|
100 |
+
),
|
101 |
+
'width' => '30',
|
102 |
+
));
|
103 |
+
|
104 |
+
$this->addColumn('firstname', array(
|
105 |
+
'header' => Mage::helper('newsletter')->__('Customer First Name'),
|
106 |
+
'index' => 'customer_firstname',
|
107 |
+
'default' => '----'
|
108 |
+
));
|
109 |
+
|
110 |
+
$this->addColumn('lastname', array(
|
111 |
+
'header' => Mage::helper('newsletter')->__('Customer Last Name'),
|
112 |
+
'index' => 'customer_lastname',
|
113 |
+
'default' => '----'
|
114 |
+
));
|
115 |
+
|
116 |
+
$this->addColumn('status', array(
|
117 |
+
'header' => Mage::helper('newsletter')->__('Status'),
|
118 |
+
'index' => 'subscriber_status',
|
119 |
+
'type' => 'options',
|
120 |
+
'options' => array(
|
121 |
+
Mage_Newsletter_Model_Subscriber::STATUS_NOT_ACTIVE => Mage::helper('newsletter')->__('Not Activated'),
|
122 |
+
Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED => Mage::helper('newsletter')->__('Subscribed'),
|
123 |
+
Mage_Newsletter_Model_Subscriber::STATUS_UNSUBSCRIBED => Mage::helper('newsletter')->__('Unsubscribed'),
|
124 |
+
Mage_Newsletter_Model_Subscriber::STATUS_UNCONFIRMED => Mage::helper('newsletter')->__('Unconfirmed'),
|
125 |
+
)
|
126 |
+
));
|
127 |
+
|
128 |
+
$this->addColumn('member_last_update_date', array(
|
129 |
+
'header' => Mage::helper('emvdatasync')->__('Last Sync'),
|
130 |
+
'type' => 'datetime',
|
131 |
+
'width' => '120',
|
132 |
+
'align' => 'center',
|
133 |
+
'index' => Emv_DataSync_Helper_Service::FIELD_MEMBER_LAST_UPDATE,
|
134 |
+
));
|
135 |
+
$this->addColumn('data_last_update_date', array(
|
136 |
+
'header' => Mage::helper('emvdatasync')->__('Last Data Update'),
|
137 |
+
'type' => 'datetime',
|
138 |
+
'width' => '120',
|
139 |
+
'align' => 'center',
|
140 |
+
'index' => Emv_DataSync_Helper_Service::FIELD_DATA_LAST_UPDATE,
|
141 |
+
));
|
142 |
+
|
143 |
+
$this->addColumn('date_unjoin', array(
|
144 |
+
'header' => Mage::helper('emvdatasync')->__('Last Unsubscription'),
|
145 |
+
'type' => 'datetime',
|
146 |
+
'width' => '120',
|
147 |
+
'align' => 'center',
|
148 |
+
'index' => Emv_DataSync_Helper_Service::FIELD_DATE_UNJOIN,
|
149 |
+
));
|
150 |
+
|
151 |
+
$this->addColumn('store', array(
|
152 |
+
'header' => Mage::helper('newsletter')->__('Store View'),
|
153 |
+
'index' => 'store_id',
|
154 |
+
'type' => 'options',
|
155 |
+
'options' => $this->_getStoreOptions()
|
156 |
+
));
|
157 |
+
$this->addColumn('group', array(
|
158 |
+
'header' => Mage::helper('newsletter')->__('Store'),
|
159 |
+
'index' => 'group_id',
|
160 |
+
'type' => 'options',
|
161 |
+
'options' => $this->_getStoreGroupOptions()
|
162 |
+
));
|
163 |
+
|
164 |
+
$this->addColumn('website', array(
|
165 |
+
'header' => Mage::helper('newsletter')->__('Website'),
|
166 |
+
'index' => 'website_id',
|
167 |
+
'type' => 'options',
|
168 |
+
'options' => $this->_getWebsiteOptions()
|
169 |
+
));
|
170 |
+
|
171 |
+
if (Mage::getSingleton('emvdatasync/service_dataProcess')->enabledPurchaseInformation()) {
|
172 |
+
$this->addColumn(
|
173 |
+
'links',
|
174 |
+
array(
|
175 |
+
'header' => Mage::helper('emvcore')->__('Purchase History'),
|
176 |
+
'width' => '100px',
|
177 |
+
'type' => 'options',
|
178 |
+
'sortable' => false,
|
179 |
+
'index' => 'purchase_validity',
|
180 |
+
'options' => array(
|
181 |
+
1 => Mage::helper('emvdatasync')->__('Yes'),
|
182 |
+
0 => Mage::helper('emvdatasync')->__('No')
|
183 |
+
)
|
184 |
+
)
|
185 |
+
);
|
186 |
+
}
|
187 |
+
|
188 |
+
$this->addExportType('*/*/exportCsv', Mage::helper('customer')->__('CSV'));
|
189 |
+
$this->addExportType('*/*/exportXml', Mage::helper('customer')->__('Excel XML'));
|
190 |
+
return Mage_Adminhtml_Block_Widget_Grid::_prepareColumns();
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* Prepare mass action for grid
|
195 |
+
*
|
196 |
+
* (non-PHPdoc)
|
197 |
+
* @see Mage_Adminhtml_Block_Newsletter_Subscriber_Grid::_prepareMassaction()
|
198 |
+
*/
|
199 |
+
protected function _prepareMassaction()
|
200 |
+
{
|
201 |
+
$this->setMassactionIdField('subscriber_id');
|
202 |
+
$this->getMassactionBlock()->setFormFieldName('subscriber');
|
203 |
+
|
204 |
+
$this->getMassactionBlock()->addItem('queue', array(
|
205 |
+
'label' => Mage::helper('emvdatasync')->__('Schedule'),
|
206 |
+
'confirm' => $this->__('Are you sure?'),
|
207 |
+
'url' => $this->getUrl(
|
208 |
+
'*/*/massQueue',
|
209 |
+
array(
|
210 |
+
'scheduled' => Emv_DataSync_Helper_Service::SCHEDULED_VALUE)
|
211 |
+
)
|
212 |
+
)
|
213 |
+
);
|
214 |
+
|
215 |
+
$this->getMassactionBlock()->addItem('remove_queue', array(
|
216 |
+
'label' => Mage::helper('newsletter')->__('Stop'),
|
217 |
+
'confirm' => $this->__('Are you sure?'),
|
218 |
+
'url' => $this->getUrl(
|
219 |
+
'*/*/massQueue',
|
220 |
+
array(
|
221 |
+
'scheduled' => Emv_DataSync_Helper_Service::NOT_SCHEDULED_VALUE)
|
222 |
+
)
|
223 |
+
)
|
224 |
+
);
|
225 |
+
$this->getMassactionBlock()->addItem('dry_test',
|
226 |
+
array(
|
227 |
+
'label' => Mage::helper('emvdatasync')->__('Get Csv File(s)'),
|
228 |
+
'url' => $this->getUrl('*/*/massDryTest')
|
229 |
+
)
|
230 |
+
);
|
231 |
+
$this->getMassactionBlock()->addItem('send_test',
|
232 |
+
array(
|
233 |
+
'label' => Mage::helper('emvdatasync')->__('Manual Sync'),
|
234 |
+
'confirm' => $this->__('Are you sure?'),
|
235 |
+
'url' => $this->getUrl('*/*/sendTest')
|
236 |
+
)
|
237 |
+
);
|
238 |
+
return $this;
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Get row class - determine the row class according to state information
|
243 |
+
*
|
244 |
+
* @param Varien_Object $emvEmt
|
245 |
+
* @return string
|
246 |
+
*/
|
247 |
+
public function getRowClass(Varien_Object $row)
|
248 |
+
{
|
249 |
+
$class = "";
|
250 |
+
if ($row->getData('purchase_validity') == 1) {
|
251 |
+
$class= "on-progress";
|
252 |
+
}
|
253 |
+
return $class;
|
254 |
+
}
|
255 |
+
}
|
@@ -21,7 +21,7 @@ class Emv_DataSync_Block_Adminhtml_System_Config_CustomerAttributes
|
|
21 |
|
22 |
public function __construct()
|
23 |
{
|
24 |
-
$this->setTemplate('
|
25 |
parent::__construct();
|
26 |
}
|
27 |
|
21 |
|
22 |
public function __construct()
|
23 |
{
|
24 |
+
$this->setTemplate('smartfocus/datasync/system/config/form/field/array.phtml');
|
25 |
parent::__construct();
|
26 |
}
|
27 |
|
@@ -11,13 +11,13 @@ class Emv_DataSync_Block_Adminhtml_System_Config_GetFields extends Mage_Adminhtm
|
|
11 |
/**
|
12 |
* Set template to itself
|
13 |
*
|
14 |
-
* @return
|
15 |
*/
|
16 |
protected function _prepareLayout()
|
17 |
{
|
18 |
parent::_prepareLayout();
|
19 |
if (!$this->getTemplate()) {
|
20 |
-
$this->setTemplate('
|
21 |
}
|
22 |
return $this;
|
23 |
}
|
@@ -33,4 +33,21 @@ class Emv_DataSync_Block_Adminhtml_System_Config_GetFields extends Mage_Adminhtm
|
|
33 |
{
|
34 |
return $this->_toHtml();
|
35 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
}
|
11 |
/**
|
12 |
* Set template to itself
|
13 |
*
|
14 |
+
* @return Emv_DataSync_Block_Adminhtml_System_Config_GetFields
|
15 |
*/
|
16 |
protected function _prepareLayout()
|
17 |
{
|
18 |
parent::_prepareLayout();
|
19 |
if (!$this->getTemplate()) {
|
20 |
+
$this->setTemplate('smartfocus/datasync/system/config/getfields.phtml');
|
21 |
}
|
22 |
return $this;
|
23 |
}
|
33 |
{
|
34 |
return $this->_toHtml();
|
35 |
}
|
36 |
+
|
37 |
+
/**
|
38 |
+
* Get field url
|
39 |
+
*
|
40 |
+
* @return string
|
41 |
+
*/
|
42 |
+
public function getGetFieldsUrl()
|
43 |
+
{
|
44 |
+
$website = $this->getRequest()->getParam('website');
|
45 |
+
$store = $this->getRequest()->getParam('store');
|
46 |
+
$url = Mage::getSingleton('adminhtml/url')->getUrl(
|
47 |
+
'emv_datasync/dataSync/getMemberFields',
|
48 |
+
array('website'=>$website, 'store'=>$store)
|
49 |
+
);
|
50 |
+
|
51 |
+
return $url;
|
52 |
+
}
|
53 |
}
|
@@ -4,7 +4,8 @@
|
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_DataSync
|
7 |
-
* @
|
|
|
8 |
*/
|
9 |
class Emv_DataSync_Helper_Data extends Mage_Core_Helper_Abstract
|
10 |
{
|
@@ -13,8 +14,16 @@ class Emv_DataSync_Helper_Data extends Mage_Core_Helper_Abstract
|
|
13 |
const XML_PATH_EMAIL_SYNC = 'emvdatasync/customer_mapping/email_enabled';
|
14 |
|
15 |
const XML_PATH_ACCOUNT_FOR_MEMBER = 'emvdatasync/apimember/account';
|
|
|
|
|
16 |
const XML_PATH_ACCOUNT_FOR_BATCH_MEMBER = 'emvdatasync/batchmember/account';
|
|
|
|
|
17 |
const XML_PATH_CUSTOMER_MAPPING_ATTRIBUTES = 'emvdatasync/customer_mapping/attributes';
|
|
|
|
|
|
|
|
|
18 |
|
19 |
/**
|
20 |
* Is created folder for export data
|
@@ -25,7 +34,14 @@ class Emv_DataSync_Helper_Data extends Mage_Core_Helper_Abstract
|
|
25 |
/**
|
26 |
* Lock file name pattern
|
27 |
*/
|
28 |
-
const LOCK_FILE_NAME_PATTERN = '
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
/**
|
31 |
* Check and create need folders
|
@@ -35,10 +51,23 @@ class Emv_DataSync_Helper_Data extends Mage_Core_Helper_Abstract
|
|
35 |
public function checkAndCreatFolder()
|
36 |
{
|
37 |
if ($this->_createdFolder == false) {
|
38 |
-
$mageFile = new Varien_Io_File();
|
39 |
-
|
40 |
-
$mageFile->checkAndCreateFolder(Mage::getBaseDir(
|
41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
$this->_createdFolder = true;
|
43 |
}
|
44 |
}
|
@@ -109,66 +138,132 @@ class Emv_DataSync_Helper_Data extends Mage_Core_Helper_Abstract
|
|
109 |
*/
|
110 |
public function saveEmailVisionFieldsInConfig($fields = array())
|
111 |
{
|
|
|
|
|
112 |
$config = Mage::getModel('core/config');
|
113 |
$config->saveConfig(
|
114 |
-
self::XML_PATH_EMAILVISION_FIELDS,
|
|
|
|
|
|
|
115 |
);
|
|
|
116 |
return $this;
|
117 |
}
|
118 |
|
119 |
/**
|
|
|
|
|
120 |
* @return array
|
121 |
*/
|
122 |
-
public function getEmailVisionFieldsFromConfig()
|
123 |
{
|
124 |
$fields = array();
|
125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
if ($encodedString) {
|
|
|
127 |
$fields = Mage::helper('core')->jsonDecode($encodedString);
|
128 |
}
|
129 |
return $fields;
|
130 |
}
|
131 |
|
132 |
/**
|
133 |
-
*
|
134 |
*
|
135 |
-
* @param string $
|
136 |
-
* @return Emv_DataSync_Helper_Data
|
137 |
-
*/
|
138 |
-
public function saveMappedEntityId($field)
|
139 |
-
{
|
140 |
-
$config = Mage::getModel('core/config');
|
141 |
-
$config->saveConfig(self::XML_PATH_MAPPED_ENTITY_ID, $field);
|
142 |
-
return $this;
|
143 |
-
}
|
144 |
-
|
145 |
-
/**
|
146 |
* @return string
|
147 |
*/
|
148 |
-
public function getMappedEntityId()
|
149 |
{
|
150 |
-
return Mage::getStoreConfig(self::XML_PATH_MAPPED_ENTITY_ID);
|
151 |
}
|
152 |
|
153 |
/**
|
|
|
|
|
154 |
* @param string $type
|
155 |
* @param string $storeId
|
156 |
* @return Emv_Core_Model_Account
|
157 |
*/
|
158 |
-
public function getEmvAccountForStore($type =
|
159 |
{
|
160 |
$path = self::XML_PATH_ACCOUNT_FOR_MEMBER;
|
|
|
161 |
if ($type == 'batch') {
|
162 |
$path = self::XML_PATH_ACCOUNT_FOR_BATCH_MEMBER;
|
|
|
163 |
}
|
164 |
|
165 |
-
$accountId = Mage::getStoreConfig($path, $storeId);
|
166 |
$account = Mage::getModel('emvcore/account');
|
167 |
-
|
|
|
|
|
|
|
168 |
|
169 |
return $account;
|
170 |
}
|
171 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
172 |
/**
|
173 |
* Get mapped attributes from config
|
174 |
*
|
@@ -190,4 +285,89 @@ class Emv_DataSync_Helper_Data extends Mage_Core_Helper_Abstract
|
|
190 |
{
|
191 |
return (bool)Mage::getStoreConfig(self::XML_PATH_EMAIL_SYNC, $storeId);
|
192 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
}
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_DataSync
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
*/
|
10 |
class Emv_DataSync_Helper_Data extends Mage_Core_Helper_Abstract
|
11 |
{
|
14 |
const XML_PATH_EMAIL_SYNC = 'emvdatasync/customer_mapping/email_enabled';
|
15 |
|
16 |
const XML_PATH_ACCOUNT_FOR_MEMBER = 'emvdatasync/apimember/account';
|
17 |
+
const XML_PATH_ENABLED_FOR_MEMBER = 'emvdatasync/apimember/enabled';
|
18 |
+
|
19 |
const XML_PATH_ACCOUNT_FOR_BATCH_MEMBER = 'emvdatasync/batchmember/account';
|
20 |
+
const XML_PATH_ENABLED_FOR_BATCH_MEMBER = 'emvdatasync/batchmember/enabled';
|
21 |
+
|
22 |
const XML_PATH_CUSTOMER_MAPPING_ATTRIBUTES = 'emvdatasync/customer_mapping/attributes';
|
23 |
+
const XML_PATH_ALLOWED_NUMBER_TEST = 'emvdatasync/general/test_members';
|
24 |
+
|
25 |
+
const TYPE_BATCH = 'batch';
|
26 |
+
const TYPE_MEMBER = 'member';
|
27 |
|
28 |
/**
|
29 |
* Is created folder for export data
|
34 |
/**
|
35 |
* Lock file name pattern
|
36 |
*/
|
37 |
+
const LOCK_FILE_NAME_PATTERN = 'data_sync_process';
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Array of accounts sorted by stores
|
41 |
+
*
|
42 |
+
* @var array
|
43 |
+
*/
|
44 |
+
protected $_storesAndAccounts = array();
|
45 |
|
46 |
/**
|
47 |
* Check and create need folders
|
51 |
public function checkAndCreatFolder()
|
52 |
{
|
53 |
if ($this->_createdFolder == false) {
|
54 |
+
$mageFile = new Varien_Io_File();
|
55 |
+
// check and create base container dir
|
56 |
+
$mageFile->checkAndCreateFolder(Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER));
|
57 |
+
|
58 |
+
// check and create base working dir
|
59 |
+
$mageFile->checkAndCreateFolder(
|
60 |
+
Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
61 |
+
. DS . Emv_Core_Helper_Data::BASE_WORKING_DIR
|
62 |
+
);
|
63 |
+
|
64 |
+
// check and create uploaded dir
|
65 |
+
$mageFile->checkAndCreateFolder(
|
66 |
+
Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
67 |
+
. DS . Emv_Core_Helper_Data::BASE_WORKING_DIR
|
68 |
+
. DS . Emv_Core_Helper_Data::UPLOADED_FILE_DIR
|
69 |
+
);
|
70 |
+
|
71 |
$this->_createdFolder = true;
|
72 |
}
|
73 |
}
|
138 |
*/
|
139 |
public function saveEmailVisionFieldsInConfig($fields = array())
|
140 |
{
|
141 |
+
$scopeData = Mage::helper('emvcore')->getAdminScope();
|
142 |
+
|
143 |
$config = Mage::getModel('core/config');
|
144 |
$config->saveConfig(
|
145 |
+
self::XML_PATH_EMAILVISION_FIELDS,
|
146 |
+
Mage::helper('core')->jsonEncode($fields),
|
147 |
+
$scopeData['scope'],
|
148 |
+
$scopeData['scope_id']
|
149 |
);
|
150 |
+
|
151 |
return $this;
|
152 |
}
|
153 |
|
154 |
/**
|
155 |
+
* Get SmartFocus fields from configuration
|
156 |
+
*
|
157 |
* @return array
|
158 |
*/
|
159 |
+
public function getEmailVisionFieldsFromConfig($fromAdminScopeConfig = true, $storeId = null)
|
160 |
{
|
161 |
$fields = array();
|
162 |
+
|
163 |
+
if ($fromAdminScopeConfig) {
|
164 |
+
$encodedString = Mage::helper('emvcore')->getAdminScopedConfig(self::XML_PATH_EMAILVISION_FIELDS);
|
165 |
+
} else {
|
166 |
+
$encodedString = Mage::getStoreConfig(self::XML_PATH_EMAILVISION_FIELDS, $storeId);
|
167 |
+
}
|
168 |
+
|
169 |
if ($encodedString) {
|
170 |
+
// the fields are serialized in JSON format
|
171 |
$fields = Mage::helper('core')->jsonDecode($encodedString);
|
172 |
}
|
173 |
return $fields;
|
174 |
}
|
175 |
|
176 |
/**
|
177 |
+
* Get mapped entity id
|
178 |
*
|
179 |
+
* @param string $storeId
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
180 |
* @return string
|
181 |
*/
|
182 |
+
public function getMappedEntityId($storeId = null)
|
183 |
{
|
184 |
+
return Mage::getStoreConfig(self::XML_PATH_MAPPED_ENTITY_ID, $storeId);
|
185 |
}
|
186 |
|
187 |
/**
|
188 |
+
* Get only activate account for store (if enabled is set to yes) for a type
|
189 |
+
*
|
190 |
* @param string $type
|
191 |
* @param string $storeId
|
192 |
* @return Emv_Core_Model_Account
|
193 |
*/
|
194 |
+
public function getEmvAccountForStore($type = self::TYPE_MEMBER, $storeId = null)
|
195 |
{
|
196 |
$path = self::XML_PATH_ACCOUNT_FOR_MEMBER;
|
197 |
+
$enabledPath = self::XML_PATH_ENABLED_FOR_MEMBER;
|
198 |
if ($type == 'batch') {
|
199 |
$path = self::XML_PATH_ACCOUNT_FOR_BATCH_MEMBER;
|
200 |
+
$enabledPath = self::XML_PATH_ENABLED_FOR_BATCH_MEMBER;
|
201 |
}
|
202 |
|
|
|
203 |
$account = Mage::getModel('emvcore/account');
|
204 |
+
if (Mage::getStoreConfig($enabledPath, $storeId)) {
|
205 |
+
$accountId = Mage::getStoreConfig($path, $storeId);
|
206 |
+
$account->load($accountId);
|
207 |
+
}
|
208 |
|
209 |
return $account;
|
210 |
}
|
211 |
|
212 |
+
/**
|
213 |
+
* Get all active SmartFocus accounts sorted by stores for a type
|
214 |
+
*
|
215 |
+
* @param string $type (member or batch)
|
216 |
+
* @return array
|
217 |
+
*/
|
218 |
+
public function getActiveEmvAccountsForStore($type = self::TYPE_MEMBER)
|
219 |
+
{
|
220 |
+
if (!isset($this->_storesAndAccounts[$type])) {
|
221 |
+
// init array
|
222 |
+
$this->_storesAndAccounts[$type] = array();
|
223 |
+
|
224 |
+
// get XML path
|
225 |
+
$path = self::XML_PATH_ACCOUNT_FOR_MEMBER;
|
226 |
+
$enabledPath = self::XML_PATH_ENABLED_FOR_MEMBER;
|
227 |
+
if ($type == 'batch') {
|
228 |
+
$path = self::XML_PATH_ACCOUNT_FOR_BATCH_MEMBER;
|
229 |
+
$enabledPath = self::XML_PATH_ENABLED_FOR_BATCH_MEMBER;
|
230 |
+
}
|
231 |
+
|
232 |
+
// also get admin store
|
233 |
+
$stores = Mage::app()->getStores(true);
|
234 |
+
$storeIds = array_keys($stores);
|
235 |
+
$treatedAccounts = array();
|
236 |
+
|
237 |
+
foreach ($storeIds as $storeId) {
|
238 |
+
// check if this account is enabled
|
239 |
+
if (Mage::getStoreConfig($enabledPath, $storeId)) {
|
240 |
+
|
241 |
+
$accountId = Mage::getStoreConfig($path, $storeId);
|
242 |
+
if (!isset($treatedAccounts[$accountId])) {
|
243 |
+
$accountId = Mage::getStoreConfig($path, $storeId);
|
244 |
+
$account = Mage::getModel('emvcore/account');
|
245 |
+
$account->load($accountId);
|
246 |
+
if ($account->getId() && $account->getId() == $accountId) {
|
247 |
+
$this->_storesAndAccounts[$type][$accountId] = array(
|
248 |
+
'model' => $account, 'stores' => array($storeId)
|
249 |
+
);
|
250 |
+
|
251 |
+
$treatedAccounts[$accountId] = true;
|
252 |
+
} else {
|
253 |
+
$treatedAccounts[$accountId] = false;
|
254 |
+
}
|
255 |
+
} else {
|
256 |
+
if ($treatedAccounts[$accountId]) {
|
257 |
+
$this->_storesAndAccounts[$type][$accountId]['stores'][] = $storeId;
|
258 |
+
}
|
259 |
+
}
|
260 |
+
}
|
261 |
+
}
|
262 |
+
}
|
263 |
+
|
264 |
+
return $this->_storesAndAccounts[$type];
|
265 |
+
}
|
266 |
+
|
267 |
/**
|
268 |
* Get mapped attributes from config
|
269 |
*
|
285 |
{
|
286 |
return (bool)Mage::getStoreConfig(self::XML_PATH_EMAIL_SYNC, $storeId);
|
287 |
}
|
288 |
+
|
289 |
+
/**
|
290 |
+
* Mass schedule a list of subscribers
|
291 |
+
*
|
292 |
+
* @param array $subscriberIds
|
293 |
+
* @param string $scheduled (take 2 values
|
294 |
+
* Emv_DataSync_Helper_Service::SCHEDULED_VALUE,
|
295 |
+
* Emv_DataSync_Helper_Service::NOT_SCHEDULED_VALUE)
|
296 |
+
* @return true
|
297 |
+
* @throws Mage_Core_Exception
|
298 |
+
*/
|
299 |
+
public function massScheduleSubscriber($subscriberIds, $scheduled = Emv_DataSync_Helper_Service::SCHEDULED_VALUE)
|
300 |
+
{
|
301 |
+
if (is_array($subscriberIds) && count($subscriberIds)) {
|
302 |
+
$resource = Mage::getModel('core/resource');
|
303 |
+
|
304 |
+
$writeConnection = $resource->getConnection(Mage_Core_Model_Resource::DEFAULT_WRITE_RESOURCE);
|
305 |
+
$condition = $writeConnection->quoteInto('IN (?)', $subscriberIds);
|
306 |
+
$queuedField = Emv_DataSync_Helper_Service::FIELD_QUEUED;
|
307 |
+
$writeConnection->query("
|
308 |
+
UPDATE {$resource->getTableName('newsletter/subscriber')}
|
309 |
+
SET {$queuedField} = {$scheduled}
|
310 |
+
WHERE subscriber_id {$condition}
|
311 |
+
");
|
312 |
+
} else {
|
313 |
+
Mage::throwException(Mage::helper('newsletter')->__('Please select subscriber(s)'));
|
314 |
+
}
|
315 |
+
|
316 |
+
return true;
|
317 |
+
}
|
318 |
+
|
319 |
+
/**
|
320 |
+
* Set last update purchase data for a given subscriber
|
321 |
+
*
|
322 |
+
* @param Mage_Newsletter_Model_Subscriber $subscriber
|
323 |
+
* @param string $time - GMT time
|
324 |
+
*/
|
325 |
+
public function setLastUpdatePurchaseDate(Mage_Newsletter_Model_Subscriber $subscriber, $time)
|
326 |
+
{
|
327 |
+
if ($subscriber->getCustomerId() && $subscriber->getId()) {
|
328 |
+
$resource = Mage::getModel('core/resource');
|
329 |
+
$writeConnection = $resource->getConnection(Mage_Core_Model_Resource::DEFAULT_WRITE_RESOURCE);
|
330 |
+
$setValue = $writeConnection->quoteInto('date_last_purchase = ?', $time);
|
331 |
+
|
332 |
+
try {
|
333 |
+
$writeConnection->query("
|
334 |
+
UPDATE {$resource->getTableName('newsletter/subscriber')} subscriber
|
335 |
+
JOIN {$resource->getTableName('sales/order')} flat_order
|
336 |
+
ON subscriber.customer_id = flat_order.customer_id
|
337 |
+
SET {$setValue}
|
338 |
+
");
|
339 |
+
} catch (Exception $e) {
|
340 |
+
Mage::logException($e);
|
341 |
+
}
|
342 |
+
}
|
343 |
+
}
|
344 |
+
|
345 |
+
/**
|
346 |
+
* Does a given customer have any order ?
|
347 |
+
*
|
348 |
+
* @param int $customerId
|
349 |
+
* @return boolean
|
350 |
+
* @throws Exception $e
|
351 |
+
*/
|
352 |
+
public function doesCustomerHaveOrder($customerId)
|
353 |
+
{
|
354 |
+
$haveOrder = false;
|
355 |
+
if ($customerId && (int)$customerId > 0) {
|
356 |
+
$resource = Mage::getModel('core/resource');
|
357 |
+
$readConnection = $resource->getConnection(Mage_Core_Model_Resource::DEFAULT_READ_RESOURCE);
|
358 |
+
$select = $readConnection->select();
|
359 |
+
|
360 |
+
$select
|
361 |
+
->from(array('main_table' => $resource->getTableName('sales/order')), array('COUNT(*)'))
|
362 |
+
->where("customer_id = ?", $customerId);
|
363 |
+
|
364 |
+
$orderCount = $readConnection->fetchCol($select);
|
365 |
+
if (is_array($orderCount) && count($orderCount) && $orderCount[0] > 0) {
|
366 |
+
$haveOrder = true;
|
367 |
+
}
|
368 |
+
}
|
369 |
+
|
370 |
+
return $haveOrder;
|
371 |
+
}
|
372 |
+
|
373 |
}
|
@@ -4,21 +4,11 @@
|
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_DataSync
|
7 |
-
* @
|
|
|
8 |
*/
|
9 |
class Emv_DataSync_Helper_Service extends Mage_Core_Helper_Abstract
|
10 |
{
|
11 |
-
/**
|
12 |
-
* @var Varien_Data_Collection_Db
|
13 |
-
*/
|
14 |
-
protected $_entityFieldsToSelect;
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Attribute Join list
|
18 |
-
* @var array
|
19 |
-
*/
|
20 |
-
protected $_joinFactory = null;
|
21 |
-
|
22 |
/**
|
23 |
* @var string
|
24 |
*/
|
@@ -29,9 +19,20 @@ class Emv_DataSync_Helper_Service extends Mage_Core_Helper_Abstract
|
|
29 |
*/
|
30 |
protected $_customerAddressTypeId = null;
|
31 |
|
32 |
-
|
33 |
-
|
34 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
35 |
|
36 |
/**
|
37 |
* Get magento attribute for the given attribute ids
|
@@ -39,7 +40,7 @@ class Emv_DataSync_Helper_Service extends Mage_Core_Helper_Abstract
|
|
39 |
* @param array $attributeIds
|
40 |
* @return Mage_Eav_Model_Resource_Entity_Attribute_Collection
|
41 |
*/
|
42 |
-
public function getMagentoAttributes($attributeIds = array())
|
43 |
{
|
44 |
$magentoAttributes = array();
|
45 |
$customerTypeId = $this->getCustomerTypeId();
|
@@ -49,189 +50,23 @@ class Emv_DataSync_Helper_Service extends Mage_Core_Helper_Abstract
|
|
49 |
->addFieldToFilter(
|
50 |
'entity_type_id',
|
51 |
array('in' => array($customerTypeId, $customerAddressEntityTypeId))
|
52 |
-
)
|
53 |
-
->addFieldToFilter(
|
54 |
-
'attribute_id',
|
55 |
-
array('in' => $attributeIds)
|
56 |
-
)
|
57 |
-
;
|
58 |
-
|
59 |
-
return $collection;
|
60 |
-
}
|
61 |
-
|
62 |
-
/**
|
63 |
-
* Prepare and get mapped customer attributes
|
64 |
-
*
|
65 |
-
* @return Varien_Data_Collection_Db
|
66 |
-
*/
|
67 |
-
public function prepareAndGetMappedCustomerAttributes()
|
68 |
-
{
|
69 |
-
if ($this->_entityFieldsToSelect == null) {
|
70 |
-
// init $this->_entityFieldsToSelect
|
71 |
-
$this->_entityFieldsToSelect = new Varien_Data_Collection_Db();
|
72 |
-
|
73 |
-
$mappedFields = Mage::helper('emvdatasync')->getEmvMappedCustomerAttributes();
|
74 |
-
if (count($mappedFields)) {
|
75 |
-
// retreive magento attribute ids
|
76 |
-
$attributeIds = array();
|
77 |
-
foreach ($mappedFields as $field) {
|
78 |
-
$attributeIds[] = $field['magento_fields'] ;
|
79 |
-
}
|
80 |
-
|
81 |
-
if (count($attributeIds)) {
|
82 |
-
$collection = $this->getMagentoAttributes($attributeIds);
|
83 |
-
if ($collection && $collection->count() > 0) {
|
84 |
-
foreach($mappedFields as $field) {
|
85 |
-
$attribute = $collection->getItemById($field['magento_fields']);
|
86 |
-
if ($attribute) {
|
87 |
-
// need to know which SmartFocus attribute has been mapped to magento one
|
88 |
-
$attribute->setEmailVisionKey($field['emailvision_fields']);
|
89 |
-
}
|
90 |
-
}
|
91 |
-
|
92 |
-
$this->_entityFieldsToSelect = $collection;
|
93 |
-
}
|
94 |
-
}
|
95 |
-
}
|
96 |
-
}
|
97 |
-
|
98 |
-
return $this->_entityFieldsToSelect;
|
99 |
-
}
|
100 |
-
|
101 |
-
/**
|
102 |
-
* Add customer and address attributes into subscriber select
|
103 |
-
*
|
104 |
-
* @param Mage_Newsletter_Model_Resource_Subscriber_Collection $collection
|
105 |
-
* @return Mage_Newsletter_Model_Resource_Subscriber_Collection
|
106 |
-
*/
|
107 |
-
public function addCustomerAndAddressAttributes(Varien_Data_Collection_Db $collection)
|
108 |
-
{
|
109 |
-
/* @var $customerModel Mage_Customer_Model_Customer */
|
110 |
-
/* @var $addressModel Mage_Customer_Model_Address */
|
111 |
-
// Get connection from collection
|
112 |
-
$adapter = $collection->getConnection();
|
113 |
-
|
114 |
-
// Prepare required table data (id, etc...)
|
115 |
-
$tablePrefix = (string)Mage::getConfig()->getTablePrefix();
|
116 |
-
$customerEntityTable = $tablePrefix . 'customer_entity';
|
117 |
-
$customerEavIntTable = $tablePrefix . 'customer_entity_int';
|
118 |
-
$addressEntityTable = $tablePrefix . 'customer_address_entity';
|
119 |
-
|
120 |
-
// Prepare Default billing attribute (customer eav, required to get only one address)
|
121 |
-
$defaultBillingAttribute = Mage::getModel('customer/customer')->getAttribute('default_billing');
|
122 |
-
|
123 |
-
// Get address entity type
|
124 |
-
$customerAddressEntityTypeId = $this->getCustomerAddressTypeId();
|
125 |
-
|
126 |
-
if (!isset($this->_joinFactory)) {
|
127 |
-
// Prepare empty joinBuilder array
|
128 |
-
// (customer entity must be joined in order to be able of getting address)
|
129 |
-
$this->_joinFactory = array(
|
130 |
-
'entity_table' => array(
|
131 |
-
$customerEntityTable => array($customerEntityTable . '.entity_id'),
|
132 |
-
$addressEntityTable => array($addressEntityTable . '.entity_id')
|
133 |
-
),
|
134 |
-
'eav_tables' => array()
|
135 |
);
|
136 |
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
if ($attribute->getEntityTypeId() == $customerAddressEntityTypeId) {
|
145 |
-
if (strpos($tableName, $addressEntityTable) !== false) {
|
146 |
-
$preparedAttributeCode = 'customer_address_' . $preparedAttributeCode;
|
147 |
-
}
|
148 |
-
} else {
|
149 |
-
// Check table type (entity or eav)
|
150 |
-
if ($tableName == $customerEntityTable) {
|
151 |
-
$tableType = 'entity_table';
|
152 |
-
$fieldPrefix = $tableName . '.';
|
153 |
-
}
|
154 |
-
|
155 |
-
// only get store_id from newsletter subscriber table
|
156 |
-
if ($attribute->getAttributeCode() == 'store_id') {
|
157 |
-
continue;
|
158 |
-
}
|
159 |
-
}
|
160 |
-
|
161 |
-
// Add current attribute as field to join
|
162 |
-
$this->_joinFactory[$tableType][$tableName][$attribute->getId()]
|
163 |
-
= $fieldPrefix . $attribute->getAttributeCode();
|
164 |
-
|
165 |
-
// !!! use final_attribute_code to get value
|
166 |
-
$attribute->setFinalAttributeCode($preparedAttributeCode);
|
167 |
-
}
|
168 |
}
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
$customerEntityTable . '.entity_id = main_table.customer_id',
|
176 |
-
$this->_joinFactory['entity_table'][$customerEntityTable]
|
177 |
-
)
|
178 |
-
// Join default billing attributes (limit address results to 1)
|
179 |
-
->joinLeft(
|
180 |
-
array('default_billing_id_table' => $customerEavIntTable),
|
181 |
-
$adapter->quoteInto(
|
182 |
-
'default_billing_id_table.entity_id = main_table.customer_id'
|
183 |
-
. ' AND default_billing_id_table.attribute_id = ?',
|
184 |
-
(int)$defaultBillingAttribute->getAttributeId()
|
185 |
-
),
|
186 |
-
array('default_billing_id' => 'default_billing_id_table.value')
|
187 |
-
)
|
188 |
-
// Add customer address entity fields
|
189 |
-
->joinLeft(
|
190 |
-
$addressEntityTable,
|
191 |
-
$adapter->quoteInto(
|
192 |
-
$customerEntityTable . '.entity_id = '. $addressEntityTable . '.parent_id'
|
193 |
-
. ' AND '. $addressEntityTable . '.entity_id = default_billing_id_table.value'
|
194 |
-
. ' AND default_billing_id_table.attribute_id = ?',
|
195 |
-
(int)$defaultBillingAttribute->getAttributeId()
|
196 |
-
),
|
197 |
-
$this->_joinFactory['entity_table'][$addressEntityTable]
|
198 |
-
);
|
199 |
-
|
200 |
-
// Join a table foreach eav attributes. Two ways, customer eav or address eav
|
201 |
-
foreach ($this->_joinFactory['eav_tables'] as $tableName => $fields) {
|
202 |
-
// Address eav attributes
|
203 |
-
if (strpos($tableName, 'customer_address') !== false) {
|
204 |
-
foreach ($fields as $fieldId => $fieldSql) {
|
205 |
-
$collection->getSelect()
|
206 |
-
->joinLeft(
|
207 |
-
array('customer_address_' . $fieldSql . '_table' => $tableName),
|
208 |
-
$adapter->quoteInto(
|
209 |
-
'customer_address_' . $fieldSql . '_table' . '.entity_id = ' . $addressEntityTable . '.entity_id'
|
210 |
-
. ' AND customer_address_' . $fieldSql . '_table' . '.attribute_id = ?',
|
211 |
-
$fieldId
|
212 |
-
),
|
213 |
-
array('customer_address_' . $fieldSql => 'customer_address_' . $fieldSql . '_table' . '.value')
|
214 |
-
);
|
215 |
-
}
|
216 |
-
} else {// Customer eav attributes
|
217 |
-
foreach ($fields as $fieldId => $fieldSql) {
|
218 |
-
$collection->getSelect()
|
219 |
-
->joinLeft(
|
220 |
-
array($fieldSql . '_table' => $tableName),
|
221 |
-
$adapter->quoteInto(
|
222 |
-
$fieldSql . '_table' . '.entity_id = main_table.customer_id'
|
223 |
-
. ' AND ' . $fieldSql . '_table' . '.attribute_id = ?',
|
224 |
-
$fieldId
|
225 |
-
),
|
226 |
-
array($fieldSql => $fieldSql . '_table' . '.value')
|
227 |
-
);
|
228 |
-
}
|
229 |
-
}
|
230 |
}
|
231 |
|
232 |
-
// dispatch a new event in order to add additional data if needed
|
233 |
-
Mage::dispatchEvent('member_collection_load_after', array('members' => $collection));
|
234 |
-
|
235 |
return $collection;
|
236 |
}
|
237 |
|
@@ -273,19 +108,27 @@ class Emv_DataSync_Helper_Service extends Mage_Core_Helper_Abstract
|
|
273 |
}
|
274 |
|
275 |
/**
|
|
|
|
|
276 |
* @param array $updatedSubscribers
|
277 |
* @param array $rejoinedSubscribers
|
278 |
* @param string $time
|
279 |
* @return boolean
|
280 |
*/
|
281 |
-
public function massSetMemberLastUpdateDate(
|
|
|
|
|
|
|
|
|
282 |
{
|
283 |
$error = true;
|
284 |
|
285 |
-
if (
|
286 |
/* @var $write Varien_Db_Adapter_Pdo_Mysql */
|
287 |
-
$
|
288 |
-
$
|
|
|
|
|
289 |
// date should be store ind GMT timezone
|
290 |
$now = Mage::helper('emvdatasync')->getFormattedGmtDateTime();
|
291 |
if ($time == null) {
|
@@ -293,22 +136,26 @@ class Emv_DataSync_Helper_Service extends Mage_Core_Helper_Abstract
|
|
293 |
}
|
294 |
|
295 |
try {
|
296 |
-
//
|
297 |
-
$
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
|
|
|
|
|
|
308 |
}
|
309 |
} catch (Exception $e) {
|
310 |
Mage::logException($e);
|
311 |
-
$error = 'Exception while processing massSetMemberLastUpdateDate with exceptionMessage:\n '
|
|
|
312 |
$error .= '\n Subscribers ids detail: ' . implode(', ', $updatedSubscribers);
|
313 |
}
|
314 |
}
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_DataSync
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
*/
|
10 |
class Emv_DataSync_Helper_Service extends Mage_Core_Helper_Abstract
|
11 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
/**
|
13 |
* @var string
|
14 |
*/
|
19 |
*/
|
20 |
protected $_customerAddressTypeId = null;
|
21 |
|
22 |
+
/**
|
23 |
+
* Newsletter Subscriber Additional Fields
|
24 |
+
*/
|
25 |
+
const FIELD_MEMBER_LAST_UPDATE = 'member_last_update_date';
|
26 |
+
const FIELD_DATA_LAST_UPDATE = 'data_last_update_date';
|
27 |
+
const FIELD_PURCHASE_LAST_UPDATE = 'date_last_purchase';
|
28 |
+
const FIELD_DATE_UNJOIN = 'date_unjoin';
|
29 |
+
const FIELD_QUEUED = 'queued';
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Values for "Queued" Field
|
33 |
+
*/
|
34 |
+
const SCHEDULED_VALUE = 1;
|
35 |
+
const NOT_SCHEDULED_VALUE = 0;
|
36 |
|
37 |
/**
|
38 |
* Get magento attribute for the given attribute ids
|
40 |
* @param array $attributeIds
|
41 |
* @return Mage_Eav_Model_Resource_Entity_Attribute_Collection
|
42 |
*/
|
43 |
+
public function getMagentoAttributes($attributeIds = array(), $attributeCodes = array())
|
44 |
{
|
45 |
$magentoAttributes = array();
|
46 |
$customerTypeId = $this->getCustomerTypeId();
|
50 |
->addFieldToFilter(
|
51 |
'entity_type_id',
|
52 |
array('in' => array($customerTypeId, $customerAddressEntityTypeId))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
53 |
);
|
54 |
|
55 |
+
if (count($attributeIds)) {
|
56 |
+
$collection->addFieldToFilter(
|
57 |
+
'attribute_id',
|
58 |
+
array('in' => $attributeIds)
|
59 |
+
)
|
60 |
+
;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
}
|
62 |
+
if (count($attributeCodes)) {
|
63 |
+
$collection->addFieldToFilter(
|
64 |
+
'attribute_code',
|
65 |
+
array('in' => $attributeCodes)
|
66 |
+
)
|
67 |
+
;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
}
|
69 |
|
|
|
|
|
|
|
70 |
return $collection;
|
71 |
}
|
72 |
|
108 |
}
|
109 |
|
110 |
/**
|
111 |
+
* Set member last update date for a list of members (perform sql query directly)
|
112 |
+
*
|
113 |
* @param array $updatedSubscribers
|
114 |
* @param array $rejoinedSubscribers
|
115 |
* @param string $time
|
116 |
* @return boolean
|
117 |
*/
|
118 |
+
public function massSetMemberLastUpdateDate(
|
119 |
+
array $updatedSubscribers = array(),
|
120 |
+
array $rejoinedSubscribers = array(),
|
121 |
+
$time = null
|
122 |
+
)
|
123 |
{
|
124 |
$error = true;
|
125 |
|
126 |
+
if (count($updatedSubscribers) > 0) {
|
127 |
/* @var $write Varien_Db_Adapter_Pdo_Mysql */
|
128 |
+
$resource = Mage::getSingleton('core/resource');
|
129 |
+
$write = $resource->getConnection('core_write');
|
130 |
+
$subscriberTable = $resource->getTableName('newsletter/subscriber');
|
131 |
+
|
132 |
// date should be store ind GMT timezone
|
133 |
$now = Mage::helper('emvdatasync')->getFormattedGmtDateTime();
|
134 |
if ($time == null) {
|
136 |
}
|
137 |
|
138 |
try {
|
139 |
+
// updated subscriber treatment
|
140 |
+
$set = array(
|
141 |
+
self::FIELD_MEMBER_LAST_UPDATE => $time,
|
142 |
+
self::FIELD_QUEUED => self::NOT_SCHEDULED_VALUE
|
143 |
+
);
|
144 |
+
$where = array('subscriber_id IN (?)' => $updatedSubscribers);
|
145 |
+
$write->update($subscriberTable, $set, $where);
|
146 |
+
|
147 |
+
if (count($rejoinedSubscribers) > 0) {
|
148 |
+
// rejoined subscriber treatment
|
149 |
+
$set = array(
|
150 |
+
self::FIELD_DATE_UNJOIN => null,
|
151 |
+
);
|
152 |
+
$where = array('subscriber_id IN (?)' => $rejoinedSubscribers);
|
153 |
+
$write->update($subscriberTable, $set, $where);
|
154 |
}
|
155 |
} catch (Exception $e) {
|
156 |
Mage::logException($e);
|
157 |
+
$error = 'Exception while processing massSetMemberLastUpdateDate with exceptionMessage:\n '
|
158 |
+
. $e->getMessage();
|
159 |
$error .= '\n Subscribers ids detail: ' . implode(', ', $updatedSubscribers);
|
160 |
}
|
161 |
}
|
@@ -6,57 +6,11 @@
|
|
6 |
* @package Emv_DataSync
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
*/
|
9 |
-
class Emv_DataSync_Model_Adminhtml_System_Config_Backend_BatchMember_Cron extends
|
10 |
{
|
11 |
/**
|
|
|
12 |
* @var string
|
13 |
*/
|
14 |
protected $_crontabPath = 'crontab/jobs/emailvision_batchmember_export/schedule/cron_expr';
|
15 |
-
|
16 |
-
/**
|
17 |
-
* Save a formated crontime in core_config_data
|
18 |
-
*
|
19 |
-
* @see Mage_Core_Model_Abstract::_afterSave()
|
20 |
-
*/
|
21 |
-
protected function _afterSave()
|
22 |
-
{
|
23 |
-
$cronConfigModel = Mage::getModel('core/config_data')
|
24 |
-
->load($this->_crontabPath, 'path');
|
25 |
-
|
26 |
-
// if the cron is disabled, we remove the cron expression to avoid launching it again
|
27 |
-
$enabled = $this->getFieldsetDataValue('enabled');
|
28 |
-
if (!$enabled) {
|
29 |
-
if ($cronConfigModel->getConfigId()) {
|
30 |
-
$cronConfigModel->delete();
|
31 |
-
}
|
32 |
-
return;
|
33 |
-
}
|
34 |
-
|
35 |
-
$frequencyDaily = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_DAILY;
|
36 |
-
$frequencyWeekly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_WEEKLY;
|
37 |
-
$frequencyMonthly = Mage_Adminhtml_Model_System_Config_Source_Cron_Frequency::CRON_MONTHLY;
|
38 |
-
|
39 |
-
// get time and frequency
|
40 |
-
$time = $this->getFieldsetDataValue('time');
|
41 |
-
$frequency = $this->getFieldsetDataValue('frequency');
|
42 |
-
|
43 |
-
// build cron expression string
|
44 |
-
$cronExprArray = array(
|
45 |
-
intval($time[1]), // Minute
|
46 |
-
intval($time[0]), // Hour
|
47 |
-
($frequency == $frequencyMonthly) ? '1' : '*', // Day of the Month
|
48 |
-
'*', // Month of the Year
|
49 |
-
($frequency == $frequencyWeekly) ? '1' : '*', // Day of the Week
|
50 |
-
);
|
51 |
-
$cronExprString = join(' ', $cronExprArray);
|
52 |
-
|
53 |
-
try {
|
54 |
-
$cronConfigModel
|
55 |
-
->setValue($cronExprString)
|
56 |
-
->setPath($this->_crontabPath)
|
57 |
-
->save();
|
58 |
-
} catch (Exception $e) {
|
59 |
-
Mage::throwException(Mage::helper('emvdatasync')->__('Unable to save the cron expression for scheduled exports'));
|
60 |
-
}
|
61 |
-
}
|
62 |
}
|
6 |
* @package Emv_DataSync
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
*/
|
9 |
+
class Emv_DataSync_Model_Adminhtml_System_Config_Backend_BatchMember_Cron extends Emv_Core_Model_Adminhtml_System_Config_Backend_Cron
|
10 |
{
|
11 |
/**
|
12 |
+
* Crontab expression path - please define an appropriate path in order to make this backend work
|
13 |
* @var string
|
14 |
*/
|
15 |
protected $_crontabPath = 'crontab/jobs/emailvision_batchmember_export/schedule/cron_expr';
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
}
|
@@ -6,10 +6,11 @@
|
|
6 |
* @package Emv_DataSync
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
*/
|
9 |
-
class Emv_DataSync_Model_Adminhtml_System_Config_Backend_Clean_Cron
|
|
|
10 |
{
|
11 |
/**
|
12 |
* @var string
|
13 |
*/
|
14 |
-
protected $_crontabPath = 'crontab/jobs/
|
15 |
}
|
6 |
* @package Emv_DataSync
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
*/
|
9 |
+
class Emv_DataSync_Model_Adminhtml_System_Config_Backend_Clean_Cron
|
10 |
+
extends Emv_Core_Model_Adminhtml_System_Config_Backend_Cron
|
11 |
{
|
12 |
/**
|
13 |
* @var string
|
14 |
*/
|
15 |
+
protected $_crontabPath = 'crontab/jobs/emailvision_batchmember_cleanning/schedule/cron_expr';
|
16 |
}
|
@@ -0,0 +1,59 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Cron Expression for Triggered Export
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
+
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
+
*/
|
9 |
+
class Emv_DataSync_Model_Adminhtml_System_Config_Backend_PurchaseProcess_Cron extends Mage_Core_Model_Config_Data
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* @var string
|
13 |
+
*/
|
14 |
+
protected $_crontabPath = 'crontab/jobs/emailvision_purchase_process/schedule/cron_expr';
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Save a formated crontime in core_config_data
|
18 |
+
*
|
19 |
+
* @see Mage_Core_Model_Abstract::_afterSave()
|
20 |
+
*/
|
21 |
+
protected function _afterSave()
|
22 |
+
{
|
23 |
+
$cronConfigModel = Mage::getModel('core/config_data')
|
24 |
+
->load($this->_crontabPath, 'path');
|
25 |
+
|
26 |
+
// if the cron is disabled, we remove the cron expression to avoid launching it again
|
27 |
+
$enabled = $this->getFieldsetDataValue('enabled');
|
28 |
+
if (!$enabled) {
|
29 |
+
if ($cronConfigModel->getConfigId()) {
|
30 |
+
$cronConfigModel->delete();
|
31 |
+
}
|
32 |
+
return;
|
33 |
+
}
|
34 |
+
|
35 |
+
$cronExprArray = array(
|
36 |
+
'quarter_hour' => '*/15 * * * *',
|
37 |
+
'half_hour' => '*/30 * * * *',
|
38 |
+
'hour' => '0 * * * *',
|
39 |
+
'two_hours' => '0 */2 * * *',
|
40 |
+
'four_hours' => '0 */4 * * *',
|
41 |
+
'six_hours' => '0 */6 * * *',
|
42 |
+
'twelve_hours' => '0 */12 * * *',
|
43 |
+
'daily' => '0 0 * * *',
|
44 |
+
);
|
45 |
+
|
46 |
+
$cronExprString = $cronExprArray[$this->getValue()];
|
47 |
+
try {
|
48 |
+
$cronConfigModel
|
49 |
+
->setValue($cronExprString)
|
50 |
+
->setPath($this->_crontabPath)
|
51 |
+
->save();
|
52 |
+
} catch (Exception $e) {
|
53 |
+
Mage::throwException(Mage::helper('emvdatasync')->__('Unable to save the cron expression for purchase process'));
|
54 |
+
}
|
55 |
+
|
56 |
+
parent::_afterSave();
|
57 |
+
}
|
58 |
+
|
59 |
+
}
|
@@ -0,0 +1,321 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Attribute handler config for data sync
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_DataSync_Model_AttributeProcessing_Config
|
11 |
+
{
|
12 |
+
const XML_PATH_ATTRIBUTE_CONFIG = 'global/smartfocus_attribute_processing';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Default attribute handler model
|
16 |
+
*/
|
17 |
+
const DEFAULT_HANDLER_MODEL = 'emvdatasync/attributeProcessing_handler_customer';
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Config node that stores available attribute handlers
|
21 |
+
*
|
22 |
+
* @var Mage_Core_Model_Config_Element
|
23 |
+
*/
|
24 |
+
protected $_configNode;
|
25 |
+
|
26 |
+
/**
|
27 |
+
* List of attribute handlers
|
28 |
+
* @var array
|
29 |
+
*/
|
30 |
+
protected $_handlerList = array();
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Attributes to be selected
|
34 |
+
*
|
35 |
+
* @var array
|
36 |
+
*/
|
37 |
+
protected $_attributesToSelect = array();
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Attributes, fields sorted by handlers
|
41 |
+
*
|
42 |
+
* @var array
|
43 |
+
*/
|
44 |
+
protected $_attributesByHandlers = array();
|
45 |
+
|
46 |
+
/**
|
47 |
+
* Store information
|
48 |
+
* @var array
|
49 |
+
*/
|
50 |
+
protected $_stores;
|
51 |
+
|
52 |
+
/**
|
53 |
+
* constructor
|
54 |
+
*
|
55 |
+
* @return void
|
56 |
+
*/
|
57 |
+
public function __construct()
|
58 |
+
{
|
59 |
+
$this->_loadHandlerConfig();
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Load all attribute handler from config xml
|
64 |
+
*/
|
65 |
+
protected function _loadHandlerConfig()
|
66 |
+
{
|
67 |
+
$this->_handlerList = array();
|
68 |
+
$this->_handlerList['default'] = Mage::getSingleton(self::DEFAULT_HANDLER_MODEL);
|
69 |
+
foreach($this->getConfigNode()->children() as $code => $modelClassName)
|
70 |
+
{
|
71 |
+
$model = Mage::getSingleton($modelClassName);
|
72 |
+
if ($model instanceof Emv_DataSync_Model_AttributeProcessing_Handler_Abstract) {
|
73 |
+
$this->_handlerList[$code] = $model;
|
74 |
+
}
|
75 |
+
}
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Get handler list
|
80 |
+
*
|
81 |
+
* @return array
|
82 |
+
*/
|
83 |
+
public function getHandlerList()
|
84 |
+
{
|
85 |
+
return $this->_handlerList;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Get config node that contains available attribute handlers from config xml
|
90 |
+
*
|
91 |
+
* @return Mage_Core_Model_Config_Element
|
92 |
+
*/
|
93 |
+
public function getConfigNode()
|
94 |
+
{
|
95 |
+
if (is_null($this->_configNode)) {
|
96 |
+
$this->_configNode = Mage::app()->getConfig()->getNode(self::XML_PATH_ATTRIBUTE_CONFIG);
|
97 |
+
}
|
98 |
+
return $this->_configNode;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Get all attribute option array
|
103 |
+
*
|
104 |
+
* @return array
|
105 |
+
*/
|
106 |
+
public function toOptionArray()
|
107 |
+
{
|
108 |
+
$arrayReturn = array();
|
109 |
+
foreach($this->getHandlerList() as $model) {
|
110 |
+
$arrayReturn = array_merge($arrayReturn, $model->toOptionArray());
|
111 |
+
}
|
112 |
+
return $arrayReturn;
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* @param string $default
|
117 |
+
* @return string
|
118 |
+
*/
|
119 |
+
public static function getArrayKey($default)
|
120 |
+
{
|
121 |
+
$arrayKey = $default;
|
122 |
+
if ($arrayKey === null) {
|
123 |
+
$arrayKey = 'undefined';
|
124 |
+
}
|
125 |
+
return $arrayKey;
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Prepare and get mapped customer attributes for a given store
|
130 |
+
*
|
131 |
+
* @param string $storeId
|
132 |
+
* @return array
|
133 |
+
*/
|
134 |
+
public function prepareAndGetMappedCustomerAttributes($storeId = null)
|
135 |
+
{
|
136 |
+
// by default the key will be store id, else will be set to undefined
|
137 |
+
$arrayKey = self::getArrayKey($storeId);
|
138 |
+
|
139 |
+
if (!isset($this->_attributesToSelect[$arrayKey])) {
|
140 |
+
// init $this->_entityFieldsToSelect
|
141 |
+
$this->_attributesToSelect[$arrayKey] = array();
|
142 |
+
$this->_attributesByHandlers[$arrayKey] = array();
|
143 |
+
|
144 |
+
$mappedAttributes = Mage::helper('emvdatasync')->getEmvMappedCustomerAttributes($storeId);
|
145 |
+
if (count($mappedAttributes)) {
|
146 |
+
$preparedArray = $this->_prepareAttributes($mappedAttributes, $storeId);
|
147 |
+
$this->_attributesToSelect[$arrayKey] = $preparedArray['mapped_attributes'];
|
148 |
+
$this->_attributesByHandlers[$arrayKey] = $preparedArray['attributes_by_handler'];
|
149 |
+
}
|
150 |
+
}
|
151 |
+
|
152 |
+
return $this->_attributesToSelect[$arrayKey];
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* @param array $mappedAttributes
|
157 |
+
* @param int $storeId
|
158 |
+
* @return array - associative array
|
159 |
+
* mapped_attributes => all mapped attributes
|
160 |
+
* attributes_by_handler => attributes sorted by handlers
|
161 |
+
*/
|
162 |
+
protected function _prepareAttributes($mappedAttributes, $storeId)
|
163 |
+
{
|
164 |
+
$attributesByHandlers = array();
|
165 |
+
|
166 |
+
foreach ($mappedAttributes as $key => $field) {
|
167 |
+
// the field follows one of these patterns :
|
168 |
+
// billing|1, shipping|2, customer|1, newsletter|subscriber_email
|
169 |
+
$info = Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::getAttributeConfigParts(
|
170 |
+
$field['magento_fields']
|
171 |
+
);
|
172 |
+
|
173 |
+
// create a new object
|
174 |
+
$fieldObject = new Varien_Object();
|
175 |
+
|
176 |
+
// !!! use final_attribute_code to get value
|
177 |
+
$fieldObject->setFinalAttributeCode($info['name']);
|
178 |
+
|
179 |
+
// need to know which SmartFocus attribute has been mapped to magento one
|
180 |
+
$fieldObject->setMappedEmailVisionKey($field['emailvision_fields']);
|
181 |
+
$fieldObject->setMappedAttributeId($info['name']);
|
182 |
+
$fieldObject->setMappedEntityType($info['prefix']);
|
183 |
+
$fieldObject->setMappedMagentoFields($field['magento_fields']);
|
184 |
+
$mappedAttributes[$key] = $fieldObject;
|
185 |
+
|
186 |
+
foreach ($this->getHandlerList() as $name => $handler) {
|
187 |
+
// test handler can handle this mapped attribute
|
188 |
+
if ($handler->canHandle($info, $storeId)) {
|
189 |
+
if (!isset($attributesByHandlers[$name])) {
|
190 |
+
$attributesByHandlers[$name] = array();
|
191 |
+
}
|
192 |
+
$attributesByHandlers[$name][$info['name']] = $fieldObject;
|
193 |
+
}
|
194 |
+
}
|
195 |
+
}
|
196 |
+
|
197 |
+
foreach ($this->getHandlerList() as $name => $handler) {
|
198 |
+
if (isset($attributesByHandlers[$name])) {
|
199 |
+
$handler->postPrepareAttribute($attributesByHandlers[$name]);
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
return array('mapped_attributes' => $mappedAttributes, 'attributes_by_handler' => $attributesByHandlers);
|
204 |
+
}
|
205 |
+
|
206 |
+
/**
|
207 |
+
* Prepare subscriber collection according to mapped attributes. A event called member_collection_load_after will
|
208 |
+
* be dispatched with collection and store id data
|
209 |
+
*
|
210 |
+
* @param Varien_Data_Collection_Db $collection
|
211 |
+
* @param string $storeId
|
212 |
+
* @return Varien_Data_Collection_Db
|
213 |
+
*/
|
214 |
+
public function prepareSubscriberCollection(
|
215 |
+
Varien_Data_Collection_Db $collection,
|
216 |
+
$storeId = null
|
217 |
+
)
|
218 |
+
{
|
219 |
+
// by default the key will be store id, else will be set to undefined
|
220 |
+
$arrayKey = self::getArrayKey($storeId);
|
221 |
+
$this->prepareAndGetMappedCustomerAttributes($storeId);
|
222 |
+
foreach ($this->getHandlerList() as $name => $handler) {
|
223 |
+
if (
|
224 |
+
isset($this->_attributesByHandlers[$arrayKey])
|
225 |
+
&& isset($this->_attributesByHandlers[$arrayKey][$name])
|
226 |
+
) {
|
227 |
+
$handler->prepareSubscriberCollection(
|
228 |
+
$collection,
|
229 |
+
$this->_attributesByHandlers[$arrayKey][$name],
|
230 |
+
$storeId
|
231 |
+
);
|
232 |
+
}
|
233 |
+
}
|
234 |
+
|
235 |
+
// dispatch a new event in order to add additional data if needed
|
236 |
+
Mage::dispatchEvent('member_collection_load_after', array('members' => $collection, 'store_id' => $storeId));
|
237 |
+
|
238 |
+
return $collection;
|
239 |
+
}
|
240 |
+
|
241 |
+
/**
|
242 |
+
* Get subscriber data according to mapped attributes
|
243 |
+
*
|
244 |
+
* @param Varien_Object $subscriber
|
245 |
+
* @param string $storeId
|
246 |
+
* @return array
|
247 |
+
*/
|
248 |
+
public function getSubscriberData(Varien_Object $subscriber, $storeId = null)
|
249 |
+
{
|
250 |
+
// Get mapped SmartFocus entity id
|
251 |
+
$entityId = strtoupper(Mage::helper('emvdatasync')->getMappedEntityId($storeId));
|
252 |
+
|
253 |
+
if (is_null($this->_stores)) {
|
254 |
+
$this->_stores = Mage::app()->getStores(true);
|
255 |
+
}
|
256 |
+
|
257 |
+
// Prepare and add a customer's data row
|
258 |
+
$subscriberData = array();
|
259 |
+
|
260 |
+
// retreive all maped attribute values from subscriber, build them into array
|
261 |
+
$fieldsToSelect = $this->prepareAndGetMappedCustomerAttributes($storeId);
|
262 |
+
|
263 |
+
foreach ($fieldsToSelect as $attribute) {
|
264 |
+
$emailVisionKey = strtoupper($attribute->getMappedEmailVisionKey());
|
265 |
+
|
266 |
+
$fieldCode = ($attribute->getFinalAttributeCode())
|
267 |
+
? $attribute->getFinalAttributeCode() : $attribute->getAttributeCode();
|
268 |
+
$fieldValue = '';
|
269 |
+
|
270 |
+
if ($attribute->getMappedDataType() == 'datetime') {
|
271 |
+
if ($subscriber->getData($fieldCode)) {
|
272 |
+
// date time should be in EmailVision format
|
273 |
+
$fieldValue = Mage::helper('emvdatasync/service')
|
274 |
+
->getEmailVisionDate($subscriber->getData($fieldCode));
|
275 |
+
}
|
276 |
+
} else {
|
277 |
+
$fieldValue = $subscriber->getData($fieldCode);
|
278 |
+
if ($fieldCode == 'store_id' && isset($stores[$fieldValue])) {
|
279 |
+
$fieldValue = $stores[$fieldValue]->getName();
|
280 |
+
}
|
281 |
+
}
|
282 |
+
|
283 |
+
$subscriberData[$emailVisionKey] = $fieldValue;
|
284 |
+
}
|
285 |
+
|
286 |
+
// entity id field
|
287 |
+
$subscriberData[$entityId] = $subscriber->getId();
|
288 |
+
|
289 |
+
// If is unjoined
|
290 |
+
$unjoinedDate = '';
|
291 |
+
if ($subscriber->getData('subscriber_status') == Mage_Newsletter_Model_Subscriber::STATUS_UNSUBSCRIBED) {
|
292 |
+
if ($subscriber->getData(Emv_DataSync_Helper_Service::FIELD_DATE_UNJOIN)) {
|
293 |
+
// date time should be in EmailVision format
|
294 |
+
$unjoinedDate = Mage::helper('emvdatasync/service')
|
295 |
+
->getEmailVisionDate($subscriber->getData(Emv_DataSync_Helper_Service::FIELD_DATE_UNJOIN));
|
296 |
+
}
|
297 |
+
}
|
298 |
+
$subscriberData[strtoupper(Emv_Core_Model_Service_Member::FIELD_UNJOIN)] = $unjoinedDate;
|
299 |
+
|
300 |
+
return $subscriberData;
|
301 |
+
}
|
302 |
+
|
303 |
+
/**
|
304 |
+
* Clean mapped customer attributes
|
305 |
+
*
|
306 |
+
* @param string $storeId
|
307 |
+
*/
|
308 |
+
public function cleanMappedCustomerAttributes($storeId = null)
|
309 |
+
{
|
310 |
+
// by default the key will be store id, else will be set to undefined
|
311 |
+
$arrayKey = $this->getArrayKey($storeId);
|
312 |
+
foreach ($this->_attributesToSelect[$arrayKey] as $key => $attribute)
|
313 |
+
{
|
314 |
+
if ($attribute->getAttributeObject()) {
|
315 |
+
$attribute->getAttributeObject()->unsetData()->unsetOldData();
|
316 |
+
}
|
317 |
+
$attribute->unsetData()->unsetOldData();
|
318 |
+
}
|
319 |
+
unset($this->_attributesToSelect[$arrayKey]);
|
320 |
+
}
|
321 |
+
}
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Attribute handler abstract
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_DataSync_Model_AttributeProcessing_Handler_Abstract
|
11 |
+
{
|
12 |
+
const SEPARATOR_ATTR = '|';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* List of customer attribute options (html select element)
|
16 |
+
* @var array
|
17 |
+
*/
|
18 |
+
protected $_optionCustomerAttributes;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Get attribute config parts
|
22 |
+
*
|
23 |
+
* @param string $mappedAttributeName
|
24 |
+
* @return array
|
25 |
+
* prefix -> prefix part
|
26 |
+
* name -> name part
|
27 |
+
*/
|
28 |
+
public static function getAttributeConfigParts($mappedAttributeName)
|
29 |
+
{
|
30 |
+
$prefixPart = '';
|
31 |
+
$name = $mappedAttributeName;
|
32 |
+
|
33 |
+
$parts = explode(self::SEPARATOR_ATTR, $mappedAttributeName);
|
34 |
+
if (is_array($parts) && count($parts) == 2) {
|
35 |
+
$prefixPart = $parts[0];
|
36 |
+
$name = $parts[1];
|
37 |
+
}
|
38 |
+
return array('prefix' => $prefixPart, 'name' => $name);
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* @param string $prefix
|
43 |
+
* @param string $name
|
44 |
+
* @return string
|
45 |
+
*/
|
46 |
+
public static function buildAttributeName($prefix, $name)
|
47 |
+
{
|
48 |
+
// the field follows one of these patterns :
|
49 |
+
// billing|1, shipping|2, customer|1, newsletter|subscriber_email
|
50 |
+
return $prefix . self::SEPARATOR_ATTR . $name;
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Generic method needs to be implemented in Child class. The method indicates whether the handler
|
55 |
+
* can treat a given attribute
|
56 |
+
*
|
57 |
+
* @param array $attributeData
|
58 |
+
* @param int $storeId
|
59 |
+
* @return boolean
|
60 |
+
*/
|
61 |
+
public function canHandle($attributeData, $storeId)
|
62 |
+
{
|
63 |
+
return false;
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Apply post treatments for a given attribute list
|
68 |
+
*
|
69 |
+
* @param array $attributeList
|
70 |
+
* @return Emv_DataSync_Model_AttributeProcessing_Handler_Abstract
|
71 |
+
*/
|
72 |
+
public function postPrepareAttribute(array $attributeList)
|
73 |
+
{
|
74 |
+
return $this;
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Return a list of customer attribute options (html select element)
|
79 |
+
* Generic method needs to be implemented in Child class.
|
80 |
+
*
|
81 |
+
* @return array
|
82 |
+
*/
|
83 |
+
public function toOptionArray()
|
84 |
+
{
|
85 |
+
$this->_optionCustomerAttributes = array();
|
86 |
+
return $this->_optionCustomerAttribute;
|
87 |
+
}
|
88 |
+
|
89 |
+
/**
|
90 |
+
* Prepare subscriber collection according to mapped attribute list
|
91 |
+
* Generic method needs to be implemented in Child class.
|
92 |
+
*
|
93 |
+
* @param Varien_Data_Collection_Db $collection
|
94 |
+
* @param array $attributeList
|
95 |
+
* @param string $storeId
|
96 |
+
* @return Varien_Data_Collection_Db
|
97 |
+
*/
|
98 |
+
public function prepareSubscriberCollection(
|
99 |
+
Varien_Data_Collection_Db $collection,
|
100 |
+
array $attributeList,
|
101 |
+
$storeId = null
|
102 |
+
)
|
103 |
+
{
|
104 |
+
return $collection;
|
105 |
+
}
|
106 |
+
}
|
@@ -0,0 +1,321 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Customer Attribute handler (customer and customer address attributes)
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_DataSync_Model_AttributeProcessing_Handler_Customer
|
11 |
+
extends Emv_DataSync_Model_AttributeProcessing_Handler_Abstract
|
12 |
+
{
|
13 |
+
/**
|
14 |
+
* List of prefixes for different support entities
|
15 |
+
*/
|
16 |
+
const PREFIX_CUSTOMER_ATTR = 'customer';
|
17 |
+
const PREFIX_SHIPPING_ATTR = 'shipping';
|
18 |
+
const PREFIX_BILLING_ATTR = 'billing';
|
19 |
+
|
20 |
+
const PREFIX_LABEL_CUSTOMER = 'Customer';
|
21 |
+
const PREFIX_LABEL_BILLING = 'Billing';
|
22 |
+
const PREFIX_LABEL_SHIPPING = 'Shipping';
|
23 |
+
const SEPARATOR_LABEL = ' - ';
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Prohibited attributes
|
27 |
+
* @var Array
|
28 |
+
*/
|
29 |
+
protected $_prohibitedAttributes = array('store_id');
|
30 |
+
protected $_joinFactory = array();
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Default billing and shipping attribute id
|
34 |
+
* @var string
|
35 |
+
*/
|
36 |
+
protected $_defaultBillingAttrId;
|
37 |
+
protected $_defaultShippingAttrId;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Prepare default billing and shipping attribute ids
|
41 |
+
*/
|
42 |
+
public function prepareDefaultBillingAndShippingAttrId()
|
43 |
+
{
|
44 |
+
if ($this->_defaultBillingAttrId == null || $this->_defaultShippingAttrId == null) {
|
45 |
+
$attributes = Mage::helper('emvdatasync/service')->getMagentoAttributes(
|
46 |
+
array(),
|
47 |
+
array('default_billing','default_shipping')
|
48 |
+
);
|
49 |
+
foreach ($attributes as $attr) {
|
50 |
+
if ($attr->getAttributeCode() == 'default_billing') {
|
51 |
+
$this->_defaultBillingAttrId = $attr->getId();
|
52 |
+
}
|
53 |
+
if ($attr->getAttributeCode() == 'default_shipping') {
|
54 |
+
$this->_defaultShippingAttrId = $attr->getId();
|
55 |
+
}
|
56 |
+
|
57 |
+
}
|
58 |
+
}
|
59 |
+
}
|
60 |
+
|
61 |
+
/**
|
62 |
+
* (non-PHPdoc)
|
63 |
+
* @see Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::toOptionArray()
|
64 |
+
*/
|
65 |
+
public function toOptionArray()
|
66 |
+
{
|
67 |
+
if (is_null($this->_optionCustomerAttributes)) {
|
68 |
+
$this->_optionCustomerAttributes = array();
|
69 |
+
|
70 |
+
$addressLabel = Mage::helper('emvdatasync')->__('Customer Billing Address');
|
71 |
+
$shippingAddressLabel = Mage::helper('emvdatasync')->__('Customer Shipping Address');
|
72 |
+
$customerLabel = Mage::helper('emvdatasync')->__('Customer');
|
73 |
+
|
74 |
+
$customerEntityTypeId = Mage::helper('emvdatasync/service')->getCustomerTypeId();
|
75 |
+
$customerAddressEntityTypeId = Mage::helper('emvdatasync/service')->getCustomerAddressTypeId();
|
76 |
+
$collection = Mage::helper('emvdatasync/service')->getMagentoAttributes();
|
77 |
+
|
78 |
+
if ($collection && $collection->count()>0) {
|
79 |
+
foreach ($collection as $item) {
|
80 |
+
// only take attribute isn't prohibited
|
81 |
+
if (in_array($item->getAttributeCode(),$this->_prohibitedAttributes)) {
|
82 |
+
continue;
|
83 |
+
}
|
84 |
+
|
85 |
+
// only display attributes that have a correct label
|
86 |
+
if ($item->getFrontendLabel() && $item->getFrontendInput() !== 'hidden') {
|
87 |
+
if ($item->getEntityTypeId() == $customerAddressEntityTypeId) {
|
88 |
+
if (!isset($this->_optionCustomerAttributes['customer_address'])) {
|
89 |
+
// initialize customer address attribute array
|
90 |
+
$this->_optionCustomerAttributes['customer_address'] = array(
|
91 |
+
'value' => array(),
|
92 |
+
'label' => $addressLabel
|
93 |
+
);
|
94 |
+
// initialize customer address attribute array
|
95 |
+
$this->_optionCustomerAttributes['customer_shipping_address'] = array(
|
96 |
+
'value' => array(),
|
97 |
+
'label' => $shippingAddressLabel
|
98 |
+
);
|
99 |
+
}
|
100 |
+
|
101 |
+
// billing address attribute
|
102 |
+
$finalAttributeId = Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::buildAttributeName(
|
103 |
+
self::PREFIX_BILLING_ATTR,
|
104 |
+
$item->getAttributeId()
|
105 |
+
);
|
106 |
+
$this->_optionCustomerAttributes['customer_address']['value'][$finalAttributeId]
|
107 |
+
= self::PREFIX_LABEL_BILLING . self::SEPARATOR_LABEL . $item->getFrontendLabel();
|
108 |
+
|
109 |
+
// shipping address attribute
|
110 |
+
$finalAttributeId = Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::buildAttributeName(
|
111 |
+
self::PREFIX_SHIPPING_ATTR,
|
112 |
+
$item->getAttributeId()
|
113 |
+
);
|
114 |
+
$this->_optionCustomerAttributes['customer_shipping_address']['value'][$finalAttributeId]
|
115 |
+
= self::PREFIX_LABEL_SHIPPING . self::SEPARATOR_LABEL . $item->getFrontendLabel();
|
116 |
+
} else {
|
117 |
+
if (!isset($this->_optionCustomerAttributes['customer'])) {
|
118 |
+
// initialize customer attribute array
|
119 |
+
$this->_optionCustomerAttributes['customer'] = array(
|
120 |
+
'value' => array(),
|
121 |
+
'label' => $customerLabel
|
122 |
+
);
|
123 |
+
}
|
124 |
+
|
125 |
+
$finalAttributeId = Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::buildAttributeName(
|
126 |
+
self::PREFIX_CUSTOMER_ATTR,
|
127 |
+
$item->getAttributeId()
|
128 |
+
);
|
129 |
+
$this->_optionCustomerAttributes['customer']['value'][$finalAttributeId]
|
130 |
+
= self::PREFIX_LABEL_CUSTOMER . self::SEPARATOR_LABEL . $item->getFrontendLabel();
|
131 |
+
}
|
132 |
+
}
|
133 |
+
}
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
return $this->_optionCustomerAttributes;
|
138 |
+
}
|
139 |
+
|
140 |
+
/**
|
141 |
+
* For each customer/customer address attribute, provide an eav attribute model
|
142 |
+
*
|
143 |
+
* (non-PHPdoc)
|
144 |
+
* @see Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::postPrepareAttribute()
|
145 |
+
*/
|
146 |
+
public function postPrepareAttribute(array $attributeList)
|
147 |
+
{
|
148 |
+
$attributeIds = array_keys($attributeList);
|
149 |
+
if (count($attributeIds)) {
|
150 |
+
$collection = Mage::helper('emvdatasync/service')->getMagentoAttributes($attributeIds);
|
151 |
+
if ($collection && $collection->count() > 0) {
|
152 |
+
foreach($attributeList as $key => $fieldObject) {
|
153 |
+
$attribute = $collection->getItemById($fieldObject->getMappedAttributeId());
|
154 |
+
if ($attribute) {
|
155 |
+
$fieldObject->setAttributeObject($attribute);
|
156 |
+
$fieldObject->setMappedDataType($attribute->getBackendType());
|
157 |
+
}
|
158 |
+
}
|
159 |
+
}
|
160 |
+
}
|
161 |
+
|
162 |
+
return $this;
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* (non-PHPdoc)
|
167 |
+
* @see Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::canHandle()
|
168 |
+
*/
|
169 |
+
public function canHandle($attributeData, $storeId)
|
170 |
+
{
|
171 |
+
$ok = false;
|
172 |
+
if (isset($attributeData['prefix'])) {
|
173 |
+
$allowedPrefix = array(self::PREFIX_BILLING_ATTR, self::PREFIX_CUSTOMER_ATTR, self::PREFIX_SHIPPING_ATTR);
|
174 |
+
if (in_array($attributeData['prefix'], $allowedPrefix)) {
|
175 |
+
$ok = true;
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
return $ok;
|
180 |
+
}
|
181 |
+
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Apply customer and customer address attribute to select
|
185 |
+
*
|
186 |
+
* (non-PHPdoc)
|
187 |
+
* @see Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::prepareSubscriberCollection()
|
188 |
+
*/
|
189 |
+
public function prepareSubscriberCollection(
|
190 |
+
Varien_Data_Collection_Db $collection,
|
191 |
+
array $attributeList,
|
192 |
+
$storeId = null
|
193 |
+
)
|
194 |
+
{
|
195 |
+
$this->prepareDefaultBillingAndShippingAttrId();
|
196 |
+
$joinFactory = array();
|
197 |
+
// Get connection from collection
|
198 |
+
$adapter = $collection->getConnection();
|
199 |
+
|
200 |
+
// Prepare required table data (id, etc...)
|
201 |
+
$tablePrefix = (string)Mage::getConfig()->getTablePrefix();
|
202 |
+
$customerEntityTable = $tablePrefix . 'customer_entity';
|
203 |
+
$customerEavIntTable = $tablePrefix . 'customer_entity_int';
|
204 |
+
|
205 |
+
// Get address entity type
|
206 |
+
$customerAddressEntityTypeId = Mage::helper('emvdatasync/service')->getCustomerAddressTypeId();
|
207 |
+
|
208 |
+
$joinFactory = array(
|
209 |
+
'entity_table' => array(
|
210 |
+
$customerEntityTable => array($customerEntityTable . '.entity_id'),
|
211 |
+
),
|
212 |
+
'eav_tables' => array(
|
213 |
+
self::PREFIX_CUSTOMER_ATTR => array(),
|
214 |
+
self::PREFIX_BILLING_ATTR => array(),
|
215 |
+
self::PREFIX_SHIPPING_ATTR => array(),
|
216 |
+
)
|
217 |
+
);
|
218 |
+
foreach ($attributeList as $mappedField) {
|
219 |
+
// the attribute needs to have a backend table
|
220 |
+
if ($mappedField->getAttributeObject() && $mappedField->getAttributeObject()->getBackend()) {
|
221 |
+
// get attribute object
|
222 |
+
$attribute = $mappedField->getAttributeObject();
|
223 |
+
$preparedAttributeCode = $attribute->getAttributeCode();
|
224 |
+
|
225 |
+
$tableName = $attribute->getBackend()->getTable();
|
226 |
+
// if the attribute value is retrieved from customer entity table
|
227 |
+
if ($tableName == $customerEntityTable) {
|
228 |
+
$joinFactory['entity_table']
|
229 |
+
[$customerEntityTable][$attribute->getId()]
|
230 |
+
= $customerEntityTable . '.' . $attribute->getAttributeCode();
|
231 |
+
} else {
|
232 |
+
$preparedAttributeCode = $mappedField->getMappedEntityType()
|
233 |
+
. '_'. $attribute->getAttributeCode();
|
234 |
+
$joinFactory['eav_tables']
|
235 |
+
[$mappedField->getMappedEntityType()][$tableName][$attribute->getId()]
|
236 |
+
= $preparedAttributeCode;
|
237 |
+
}
|
238 |
+
|
239 |
+
// !!! use final_attribute_code to get value
|
240 |
+
$mappedField->setFinalAttributeCode($preparedAttributeCode);
|
241 |
+
}
|
242 |
+
}
|
243 |
+
|
244 |
+
// Manage entities fields
|
245 |
+
$collection->getSelect()
|
246 |
+
// Add customer_entity fields (no aliases, an only call for all customer entity fields)
|
247 |
+
->joinLeft(
|
248 |
+
$customerEntityTable,
|
249 |
+
$customerEntityTable . '.entity_id = main_table.customer_id',
|
250 |
+
$joinFactory['entity_table'][$customerEntityTable]
|
251 |
+
)
|
252 |
+
// find default billing address entity id
|
253 |
+
->joinLeft(
|
254 |
+
array('default_billing_id_table' => $customerEavIntTable),
|
255 |
+
$adapter->quoteInto(
|
256 |
+
'default_billing_id_table.entity_id = main_table.customer_id'
|
257 |
+
. ' AND default_billing_id_table.attribute_id = ?',
|
258 |
+
$this->_defaultBillingAttrId
|
259 |
+
),
|
260 |
+
array('default_billing_id' => 'default_billing_id_table.value')
|
261 |
+
)
|
262 |
+
// find default shipping address entity id
|
263 |
+
->joinLeft(
|
264 |
+
array('default_shipping_id_table' => $customerEavIntTable),
|
265 |
+
$adapter->quoteInto(
|
266 |
+
'default_shipping_id_table.entity_id = main_table.customer_id'
|
267 |
+
. ' AND default_shipping_id_table.attribute_id = ?',
|
268 |
+
$this->_defaultShippingAttrId
|
269 |
+
),
|
270 |
+
array('default_shipping_id' => 'default_shipping_id_table.value')
|
271 |
+
)
|
272 |
+
;
|
273 |
+
|
274 |
+
// retrieve different attributes from different tables
|
275 |
+
foreach ($joinFactory['eav_tables'] as $type => $tables) {
|
276 |
+
if ($type == self::PREFIX_CUSTOMER_ATTR) {
|
277 |
+
foreach($tables as $tableName => $fields) {
|
278 |
+
foreach ($fields as $fieldId => $fieldSql) {
|
279 |
+
$collection->getSelect()
|
280 |
+
->joinLeft(
|
281 |
+
array($fieldSql . '_table' => $tableName),
|
282 |
+
$adapter->quoteInto(
|
283 |
+
$fieldSql . '_table' . '.entity_id = main_table.customer_id'
|
284 |
+
. ' AND ' . $fieldSql . '_table' . '.attribute_id = ?',
|
285 |
+
$fieldId
|
286 |
+
),
|
287 |
+
array($fieldSql => $fieldSql . '_table' . '.value')
|
288 |
+
);
|
289 |
+
}
|
290 |
+
}
|
291 |
+
} else {
|
292 |
+
foreach($tables as $tableName => $fields) {
|
293 |
+
foreach ($fields as $fieldId => $fieldSql) {
|
294 |
+
if ($type == self::PREFIX_SHIPPING_ATTR) {
|
295 |
+
$condition = $adapter->quoteInto(
|
296 |
+
$fieldSql . '_table' . '.entity_id = default_shipping_id_table.value'
|
297 |
+
. ' AND ' . $fieldSql . '_table' . '.attribute_id = ?',
|
298 |
+
$fieldId
|
299 |
+
);
|
300 |
+
} else {
|
301 |
+
$condition = $adapter->quoteInto(
|
302 |
+
$fieldSql . '_table' . '.entity_id = default_billing_id_table.value'
|
303 |
+
. ' AND ' . $fieldSql . '_table' . '.attribute_id = ?',
|
304 |
+
$fieldId
|
305 |
+
);
|
306 |
+
}
|
307 |
+
|
308 |
+
$collection->getSelect()
|
309 |
+
->joinLeft(
|
310 |
+
array($fieldSql . '_table' => $tableName),
|
311 |
+
$condition,
|
312 |
+
array($fieldSql => $fieldSql . '_table' . '.value')
|
313 |
+
);
|
314 |
+
}
|
315 |
+
}
|
316 |
+
}
|
317 |
+
}
|
318 |
+
|
319 |
+
return $collection;
|
320 |
+
}
|
321 |
+
}
|
@@ -0,0 +1,99 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Newslleter Attribute handler
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_DataSync_Model_AttributeProcessing_Handler_Newsletter
|
11 |
+
extends Emv_DataSync_Model_AttributeProcessing_Handler_Abstract
|
12 |
+
{
|
13 |
+
const PREFIX_NEWSLETTER_FIELD = 'newsletter';
|
14 |
+
|
15 |
+
protected $_tableName = 'newsletter/subscriber';
|
16 |
+
protected $_tableDefintion = array();
|
17 |
+
protected $_isLoaded = false;
|
18 |
+
|
19 |
+
/**
|
20 |
+
* @return array
|
21 |
+
*/
|
22 |
+
public function getTableDefinition()
|
23 |
+
{
|
24 |
+
if (!$this->_isLoaded) {
|
25 |
+
// add subscriber's column definition into array
|
26 |
+
$readAdaptator = Mage::getSingleton('core/resource')->getConnection('core_read');
|
27 |
+
$this->_tableDefintion = $readAdaptator
|
28 |
+
->describeTable(Mage::getSingleton('core/resource')->getTableName($this->_tableName));
|
29 |
+
$this->_isLoaded = true;
|
30 |
+
}
|
31 |
+
return $this->_tableDefintion;
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* (non-PHPdoc)
|
36 |
+
* @see Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::toOptionArray()
|
37 |
+
*/
|
38 |
+
public function toOptionArray()
|
39 |
+
{
|
40 |
+
if (is_null($this->_optionCustomerAttributes)) {
|
41 |
+
$this->_optionCustomerAttributes = array();
|
42 |
+
if ($this->getTableDefinition() && is_array($this->getTableDefinition())) {
|
43 |
+
foreach ($this->getTableDefinition() as $columnName => $columnDefintion) {
|
44 |
+
if (!isset($this->_optionCustomerAttributes['newsletter_subscriber'])) {
|
45 |
+
$this->_optionCustomerAttributes['newsletter_subscriber'] = array(
|
46 |
+
'value' => array(),
|
47 |
+
'label' => Mage::helper('emvdatasync')->__('Newsletter Subscriber')
|
48 |
+
);
|
49 |
+
}
|
50 |
+
$finalAttributeId = Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::buildAttributeName(
|
51 |
+
self::PREFIX_NEWSLETTER_FIELD,
|
52 |
+
$columnName
|
53 |
+
);
|
54 |
+
$this->_optionCustomerAttributes['newsletter_subscriber']['value'][$finalAttributeId] = $columnName;
|
55 |
+
}
|
56 |
+
}
|
57 |
+
}
|
58 |
+
|
59 |
+
return $this->_optionCustomerAttributes;
|
60 |
+
}
|
61 |
+
|
62 |
+
/**
|
63 |
+
* (non-PHPdoc)
|
64 |
+
* @see Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::canHandle()
|
65 |
+
*/
|
66 |
+
public function canHandle($attributeData, $storeId)
|
67 |
+
{
|
68 |
+
$ok = false;
|
69 |
+
if (isset($attributeData['prefix'])) {
|
70 |
+
$allowedPrefix = array(self::PREFIX_NEWSLETTER_FIELD);
|
71 |
+
if (in_array($attributeData['prefix'], $allowedPrefix)) {
|
72 |
+
$ok = true;
|
73 |
+
}
|
74 |
+
}
|
75 |
+
|
76 |
+
return $ok;
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* (non-PHPdoc)
|
81 |
+
* @see Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::postPrepareAttribute()
|
82 |
+
*/
|
83 |
+
public function postPrepareAttribute(array $attributeList)
|
84 |
+
{
|
85 |
+
$tableDefinition = $this->getTableDefinition();
|
86 |
+
if ($tableDefinition && is_array($tableDefinition)) {
|
87 |
+
foreach($attributeList as $key => $fieldObject) {
|
88 |
+
if (
|
89 |
+
isset($tableDefinition[$fieldObject->getMappedAttributeId()])
|
90 |
+
&& isset($tableDefinition[$fieldObject->getMappedAttributeId()]['DATA_TYPE'])
|
91 |
+
) {
|
92 |
+
$fieldObject->setMappedDataType($tableDefinition[$fieldObject->getMappedAttributeId()]['DATA_TYPE']);
|
93 |
+
}
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
return $this;
|
98 |
+
}
|
99 |
+
}
|
@@ -0,0 +1,154 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Purchase Information Attribute handler
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_DataSync_Model_AttributeProcessing_Handler_PurchaseInformation
|
11 |
+
extends Emv_DataSync_Model_AttributeProcessing_Handler_Newsletter
|
12 |
+
{
|
13 |
+
const PREFIX_PURCHASE_FIELD = 'purchase';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Table name
|
17 |
+
*
|
18 |
+
* @var string
|
19 |
+
*/
|
20 |
+
protected $_tableName = 'emvdatasync/purchase_info';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Prohibited fields (in the attribute mapping list)
|
24 |
+
* @var array
|
25 |
+
*/
|
26 |
+
protected $_prohibitedFields = array('id', 'customer_id');
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Field Labels
|
30 |
+
*
|
31 |
+
* @var array
|
32 |
+
*/
|
33 |
+
protected $_fieldLabels = array(
|
34 |
+
'email' => 'Used Email Addresses',
|
35 |
+
'order_list' => 'List of Order #' ,
|
36 |
+
|
37 |
+
'created_at' => 'Created At',
|
38 |
+
'updated_at' => 'Updated At' ,
|
39 |
+
|
40 |
+
'base_currency_code' => 'Base Currency Code',
|
41 |
+
|
42 |
+
'total_order' => 'Total Orders Purchased',
|
43 |
+
|
44 |
+
'total_ordered_item_qty' => 'Total Items Purchased',
|
45 |
+
'avg_item_qty' => 'Average Items Purchased per Order',
|
46 |
+
'order_amount_total' => 'Total Order Amount Spent',
|
47 |
+
'avg_order_amount_total' => 'Average Order Amount Spent per Purchase',
|
48 |
+
'discount_amount_total' => 'Total Discount Amount',
|
49 |
+
'avg_discount_amount_total' => 'Average Discount Amount per Purchase',
|
50 |
+
'shipping_amount_total' => 'Total Shipping Amount',
|
51 |
+
'avg_shipping_amount_total' => 'Average Shipping Amount per Purchase',
|
52 |
+
|
53 |
+
'min_order_amount_total' => 'Minimum Purchase Total',
|
54 |
+
'max_order_amount_total' => 'Maximum Purchase Total',
|
55 |
+
'first_order_date' => 'First Purchase',
|
56 |
+
'last_order_date' => 'Last Purchase',
|
57 |
+
'min_total_ordered_item_qty' => 'Minimum Items Purchased',
|
58 |
+
'max_total_ordered_item_qty' => 'Maximum Items Purchased',
|
59 |
+
|
60 |
+
'shipping_list' => 'Shipping Methods',
|
61 |
+
'payment_methods' => 'Payment Methods',
|
62 |
+
'coupon_list' => 'Used Coupons',
|
63 |
+
'nb_order_having_discount' => 'Total Purchases With Discount'
|
64 |
+
);
|
65 |
+
|
66 |
+
/**
|
67 |
+
* (non-PHPdoc)
|
68 |
+
* @see Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::toOptionArray()
|
69 |
+
*/
|
70 |
+
public function toOptionArray()
|
71 |
+
{
|
72 |
+
if (is_null($this->_optionCustomerAttributes)) {
|
73 |
+
$this->_optionCustomerAttributes = array();
|
74 |
+
|
75 |
+
if ($this->getTableDefinition() && is_array($this->getTableDefinition())) {
|
76 |
+
foreach ($this->getTableDefinition() as $columnName => $columnDefintion) {
|
77 |
+
if (!in_array($columnName, $this->_prohibitedFields)) {
|
78 |
+
if (!isset($this->_optionCustomerAttributes['purchase_information'])) {
|
79 |
+
$this->_optionCustomerAttributes['purchase_information'] = array(
|
80 |
+
'value' => array(),
|
81 |
+
'label' => Mage::helper('emvdatasync')->__('Purchase Information')
|
82 |
+
);
|
83 |
+
}
|
84 |
+
$finalAttributeId = Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::buildAttributeName(
|
85 |
+
self::PREFIX_PURCHASE_FIELD,
|
86 |
+
$columnName
|
87 |
+
);
|
88 |
+
|
89 |
+
$label = $columnName;
|
90 |
+
if (isset($this->_fieldLabels[$label])) {
|
91 |
+
$label = $this->_fieldLabels[$label];
|
92 |
+
}
|
93 |
+
$this->_optionCustomerAttributes['purchase_information']['value'][$finalAttributeId] = 'Purchase - ' . $label;
|
94 |
+
}
|
95 |
+
}
|
96 |
+
}
|
97 |
+
|
98 |
+
}
|
99 |
+
|
100 |
+
return $this->_optionCustomerAttributes;
|
101 |
+
}
|
102 |
+
|
103 |
+
/**
|
104 |
+
* (non-PHPdoc)
|
105 |
+
* @see Emv_DataSync_Model_AttributeProcessing_Handler_Abstract::canHandle()
|
106 |
+
*/
|
107 |
+
public function canHandle($attributeData, $storeId)
|
108 |
+
{
|
109 |
+
$ok = false;
|
110 |
+
if (Mage::getSingleton('emvdatasync/service_dataProcess')->enabledPurchaseInformation()) {
|
111 |
+
if (isset($attributeData['prefix'])) {
|
112 |
+
$allowedPrefix = array(self::PREFIX_PURCHASE_FIELD);
|
113 |
+
if (in_array($attributeData['prefix'], $allowedPrefix)) {
|
114 |
+
$ok = true;
|
115 |
+
}
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
return $ok;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Prepare subscriber collection according to mapped attribute list
|
124 |
+
* Generic method needs to be implemented in Child class.
|
125 |
+
*
|
126 |
+
* @param Varien_Data_Collection_Db $collection
|
127 |
+
* @param array $attributeList
|
128 |
+
* @param string $storeId
|
129 |
+
* @return Varien_Data_Collection_Db
|
130 |
+
*/
|
131 |
+
public function prepareSubscriberCollection(
|
132 |
+
Varien_Data_Collection_Db $collection,
|
133 |
+
array $attributeList,
|
134 |
+
$storeId = null
|
135 |
+
)
|
136 |
+
{
|
137 |
+
$tableName = Mage::getSingleton('core/resource')->getTableName($this->_tableName);
|
138 |
+
|
139 |
+
$collection->getSelect()
|
140 |
+
->joinLeft(
|
141 |
+
array('purchase' => $tableName),
|
142 |
+
'purchase.customer_id = main_table.customer_id'
|
143 |
+
)
|
144 |
+
->where('
|
145 |
+
main_table.date_last_purchase IS NULL
|
146 |
+
OR (
|
147 |
+
purchase.updated_at > main_table.date_last_purchase
|
148 |
+
)
|
149 |
+
')
|
150 |
+
;
|
151 |
+
|
152 |
+
return $collection;
|
153 |
+
}
|
154 |
+
}
|
@@ -4,7 +4,8 @@
|
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_DataSync
|
7 |
-
* @
|
|
|
8 |
*/
|
9 |
class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
|
10 |
{
|
@@ -71,7 +72,6 @@ class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
|
|
71 |
public function batchMemberExport()
|
72 |
{
|
73 |
$helper = Mage::helper('emvdatasync');
|
74 |
-
$exportDone = false;
|
75 |
|
76 |
if (!Mage::getStoreConfigFlag(self::XML_PATH_EMAILVISION_BATCH_ENABLED)) {
|
77 |
return $this;
|
@@ -80,6 +80,8 @@ class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
|
|
80 |
$this->_errors = array();
|
81 |
|
82 |
$startRunTime = $helper->getFormattedGmtDateTime();
|
|
|
|
|
83 |
|
84 |
$processErrors = array();
|
85 |
$createdLock = false;
|
@@ -87,14 +89,13 @@ class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
|
|
87 |
// check and create lock
|
88 |
if (!$helper->checkLockFile()) {
|
89 |
$service = Mage::getModel('emvdatasync/service_batchMember');
|
90 |
-
$account = Mage::helper('emvdatasync')->getEmvAccountForStore('batch');
|
91 |
-
$service->setAccount($account);
|
92 |
|
93 |
// create lock file => do not allow several process at the same time
|
94 |
$helper->createLockFile('Batch member synchronization cron process running at GMT timezone ' . $startRunTime);
|
95 |
$createdLock = true;
|
96 |
|
97 |
-
$
|
|
|
98 |
|
99 |
// If non-blocking errors occurs
|
100 |
$processErrors = $service->getErrors();
|
@@ -121,19 +122,20 @@ class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
|
|
121 |
}
|
122 |
}
|
123 |
|
|
|
|
|
|
|
124 |
// if some errors occur, we should inform the client
|
125 |
if (count($this->_errors)) {
|
126 |
$this->_sendCustomerExportErrors();
|
127 |
}
|
128 |
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
$config->removeCache();
|
136 |
-
}
|
137 |
|
138 |
return $this;
|
139 |
}
|
@@ -154,6 +156,8 @@ class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
|
|
154 |
|
155 |
// gmt date time
|
156 |
$startRunTime = $helper->getFormattedGmtDateTime();
|
|
|
|
|
157 |
|
158 |
$processErrors = array();
|
159 |
$createdLock = false;
|
@@ -161,8 +165,6 @@ class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
|
|
161 |
// check and create lock
|
162 |
if (!$helper->checkLockFile()) {
|
163 |
$service = Mage::getModel('emvdatasync/service_member');
|
164 |
-
$account = Mage::helper('emvdatasync')->getEmvAccountForStore();
|
165 |
-
$service->setAccount($account);
|
166 |
|
167 |
// create lock file => do not allow several process at the same time
|
168 |
$helper->createLockFile('Member synchronization cron process running at GMT timezone ' . $startRunTime);
|
@@ -178,7 +180,8 @@ class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
|
|
178 |
}
|
179 |
}
|
180 |
} catch (Exception $e) {
|
181 |
-
$this->_errors[] = 'Errors occured while running memberExport (memberApi cron), at GMT timezone '
|
|
|
182 |
$this->_errors[] = $e->getMessage();
|
183 |
foreach ($processErrors as $error) {
|
184 |
$this->_errors[] = $error;
|
@@ -194,6 +197,7 @@ class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
|
|
194 |
}
|
195 |
}
|
196 |
|
|
|
197 |
// if some errors occur, we should inform the client
|
198 |
if (count($this->_errors)) {
|
199 |
$this->_sendCustomerExportErrors();
|
@@ -203,7 +207,7 @@ class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
|
|
203 |
}
|
204 |
|
205 |
/**
|
206 |
-
* Cron method to clean files moved in uploaded folder after exporting customers
|
207 |
*
|
208 |
* @return Emv_DataSync_Model_Cron
|
209 |
*/
|
@@ -215,37 +219,128 @@ class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
|
|
215 |
|
216 |
// everything is in GMT date time
|
217 |
$startRunTime = Mage::helper('emvdatasync')->getFormattedGmtDateTime();
|
|
|
|
|
218 |
|
219 |
$this->_errors = array();
|
220 |
-
|
221 |
try {
|
222 |
// Check folders in case this method is called before any export
|
223 |
-
|
224 |
-
|
225 |
-
//
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
}
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
}
|
|
|
243 |
}
|
244 |
-
@closedir($dirHandler);
|
245 |
} catch (Exception $e) {
|
246 |
$this->_errors[] = 'Errors occured while removing exported files (cleanEmailVisionFiles cron), at GMT timezone '
|
247 |
. $startRunTime;
|
248 |
$this->_errors[] = $e->getMessage();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
249 |
$this->_sendCustomerExportErrors();
|
250 |
}
|
251 |
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_DataSync
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
*/
|
10 |
class Emv_DataSync_Model_Cron extends Mage_Core_Model_Abstract
|
11 |
{
|
72 |
public function batchMemberExport()
|
73 |
{
|
74 |
$helper = Mage::helper('emvdatasync');
|
|
|
75 |
|
76 |
if (!Mage::getStoreConfigFlag(self::XML_PATH_EMAILVISION_BATCH_ENABLED)) {
|
77 |
return $this;
|
80 |
$this->_errors = array();
|
81 |
|
82 |
$startRunTime = $helper->getFormattedGmtDateTime();
|
83 |
+
// !!! it's very important to set a custom error handler in order to remove lock file in case of fatal error
|
84 |
+
Mage::helper('emvcore')->setSmartFocusErrorHandler();
|
85 |
|
86 |
$processErrors = array();
|
87 |
$createdLock = false;
|
89 |
// check and create lock
|
90 |
if (!$helper->checkLockFile()) {
|
91 |
$service = Mage::getModel('emvdatasync/service_batchMember');
|
|
|
|
|
92 |
|
93 |
// create lock file => do not allow several process at the same time
|
94 |
$helper->createLockFile('Batch member synchronization cron process running at GMT timezone ' . $startRunTime);
|
95 |
$createdLock = true;
|
96 |
|
97 |
+
$service->init();
|
98 |
+
$service->run();
|
99 |
|
100 |
// If non-blocking errors occurs
|
101 |
$processErrors = $service->getErrors();
|
122 |
}
|
123 |
}
|
124 |
|
125 |
+
// reset to Magento error handler
|
126 |
+
Mage::helper('emvcore')->resetErrorHandler();
|
127 |
+
|
128 |
// if some errors occur, we should inform the client
|
129 |
if (count($this->_errors)) {
|
130 |
$this->_sendCustomerExportErrors();
|
131 |
}
|
132 |
|
133 |
+
$config = Mage::getModel('core/config');
|
134 |
+
$config->saveConfig(
|
135 |
+
'emvdatasync/last_successful_synchronization/customers',
|
136 |
+
Mage::helper('emvdatasync')->getFormattedGmtDateTime()
|
137 |
+
);
|
138 |
+
$config->removeCache();
|
|
|
|
|
139 |
|
140 |
return $this;
|
141 |
}
|
156 |
|
157 |
// gmt date time
|
158 |
$startRunTime = $helper->getFormattedGmtDateTime();
|
159 |
+
// !!! it's very important to set a custom error handler in order to remove lock file in case of fatal error
|
160 |
+
Mage::helper('emvcore')->setSmartFocusErrorHandler();
|
161 |
|
162 |
$processErrors = array();
|
163 |
$createdLock = false;
|
165 |
// check and create lock
|
166 |
if (!$helper->checkLockFile()) {
|
167 |
$service = Mage::getModel('emvdatasync/service_member');
|
|
|
|
|
168 |
|
169 |
// create lock file => do not allow several process at the same time
|
170 |
$helper->createLockFile('Member synchronization cron process running at GMT timezone ' . $startRunTime);
|
180 |
}
|
181 |
}
|
182 |
} catch (Exception $e) {
|
183 |
+
$this->_errors[] = 'Errors occured while running memberExport (memberApi cron), at GMT timezone '
|
184 |
+
. $startRunTime;
|
185 |
$this->_errors[] = $e->getMessage();
|
186 |
foreach ($processErrors as $error) {
|
187 |
$this->_errors[] = $error;
|
197 |
}
|
198 |
}
|
199 |
|
200 |
+
Mage::helper('emvcore')->resetErrorHandler();
|
201 |
// if some errors occur, we should inform the client
|
202 |
if (count($this->_errors)) {
|
203 |
$this->_sendCustomerExportErrors();
|
207 |
}
|
208 |
|
209 |
/**
|
210 |
+
* Cron method to clean files moved in uploaded folder after exporting customers,
|
211 |
*
|
212 |
* @return Emv_DataSync_Model_Cron
|
213 |
*/
|
219 |
|
220 |
// everything is in GMT date time
|
221 |
$startRunTime = Mage::helper('emvdatasync')->getFormattedGmtDateTime();
|
222 |
+
$createdLock = false;
|
223 |
+
$helper = Mage::helper('emvdatasync');
|
224 |
|
225 |
$this->_errors = array();
|
|
|
226 |
try {
|
227 |
// Check folders in case this method is called before any export
|
228 |
+
$helper->checkAndCreatFolder();
|
229 |
+
|
230 |
+
// check and create lock
|
231 |
+
if (!$helper->checkLockFile()) {
|
232 |
+
// create lock file => do not allow several process at the same time
|
233 |
+
$helper->createLockFile('Cleaning file cron process running at GMT timezone ' . $startRunTime);
|
234 |
+
$createdLock = true;
|
235 |
+
|
236 |
+
// open uploaded folder
|
237 |
+
$dirHandler = @opendir(
|
238 |
+
Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
239 |
+
. DS . Emv_Core_Helper_Data::BASE_WORKING_DIR
|
240 |
+
. DS . Emv_Core_Helper_Data::UPLOADED_FILE_DIR
|
241 |
+
);
|
242 |
+
while ($filename = readdir($dirHandler)) {
|
243 |
+
// Delete any file in uploaded folder
|
244 |
+
if ($filename != '.' && $filename != '..') {
|
245 |
+
@unlink(
|
246 |
+
Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
247 |
+
. DS . Emv_Core_Helper_Data::BASE_WORKING_DIR
|
248 |
+
. DS . Emv_Core_Helper_Data::UPLOADED_FILE_DIR
|
249 |
+
. DS . $filename
|
250 |
+
);
|
251 |
+
}
|
252 |
}
|
253 |
+
@closedir($dirHandler);
|
254 |
+
|
255 |
+
// open export folder
|
256 |
+
$dirHandler = @opendir(
|
257 |
+
Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
258 |
+
. DS . Emv_Core_Helper_Data::BASE_WORKING_DIR
|
259 |
+
);
|
260 |
+
while ($filename = readdir($dirHandler)) {
|
261 |
+
$path = Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
262 |
+
. DS . Emv_Core_Helper_Data::BASE_WORKING_DIR
|
263 |
+
. DS . $filename
|
264 |
+
;
|
265 |
+
// Delete any file in exporte folder
|
266 |
+
if ($filename != '.' && $filename != '..' && is_file($path)) {
|
267 |
+
@unlink($path);
|
268 |
+
}
|
269 |
}
|
270 |
+
@closedir($dirHandler);
|
271 |
}
|
|
|
272 |
} catch (Exception $e) {
|
273 |
$this->_errors[] = 'Errors occured while removing exported files (cleanEmailVisionFiles cron), at GMT timezone '
|
274 |
. $startRunTime;
|
275 |
$this->_errors[] = $e->getMessage();
|
276 |
+
}
|
277 |
+
|
278 |
+
// if lock is created, need to delete it
|
279 |
+
if ($createdLock) {
|
280 |
+
try {
|
281 |
+
$helper->removeLockFile();
|
282 |
+
} catch (Exception $e) {
|
283 |
+
$this->_errors[] = $e->getMessage();
|
284 |
+
}
|
285 |
+
}
|
286 |
+
|
287 |
+
// if some errors occur, we should inform the client
|
288 |
+
if (count($this->_errors)) {
|
289 |
+
$this->_sendCustomerExportErrors();
|
290 |
+
}
|
291 |
+
|
292 |
+
return $this;
|
293 |
+
}
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Cron method to proceed purchase information
|
297 |
+
*
|
298 |
+
* @return Emv_DataSync_Model_Cron
|
299 |
+
*/
|
300 |
+
public function startPurchaseProcess()
|
301 |
+
{
|
302 |
+
// everything is in GMT date time
|
303 |
+
$startRunTime = Mage::helper('emvdatasync')->getFormattedGmtDateTime();
|
304 |
+
$createdLock = false;
|
305 |
+
$helper = Mage::helper('emvdatasync');
|
306 |
+
|
307 |
+
$processErrors = array();
|
308 |
+
$this->_errors = array();
|
309 |
+
try {
|
310 |
+
// Check folders in case this method is called before any export
|
311 |
+
$helper->checkAndCreatFolder();
|
312 |
+
|
313 |
+
// check and create lock
|
314 |
+
if (!$helper->checkLockFile()) {
|
315 |
+
// create lock file => do not allow several process at the same time
|
316 |
+
$helper->createLockFile('Purchase information cron process running at GMT timezone ' . $startRunTime);
|
317 |
+
$createdLock = true;
|
318 |
+
|
319 |
+
$processErrors = Mage::getModel('emvdatasync/service_dataProcess')->prepareList();
|
320 |
+
if (!empty($processErrors)) {
|
321 |
+
throw (new Exception('Check below for more details:'));
|
322 |
+
}
|
323 |
+
}
|
324 |
+
} catch (Exception $e) {
|
325 |
+
$this->_errors[] = 'Errors occured while preparing purchase information, at GMT timezone '
|
326 |
+
. $startRunTime;
|
327 |
+
$this->_errors[] = $e->getMessage();
|
328 |
+
foreach ($processErrors as $error) {
|
329 |
+
$this->_errors[] = $error;
|
330 |
+
}
|
331 |
+
}
|
332 |
+
|
333 |
+
// if lock is created, need to delete it
|
334 |
+
if ($createdLock) {
|
335 |
+
try {
|
336 |
+
$helper->removeLockFile();
|
337 |
+
} catch (Exception $e) {
|
338 |
+
$this->_errors[] = $e->getMessage();
|
339 |
+
}
|
340 |
+
}
|
341 |
+
|
342 |
+
// if some errors occur, we should inform the client
|
343 |
+
if (count($this->_errors)) {
|
344 |
$this->_sendCustomerExportErrors();
|
345 |
}
|
346 |
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Purchase Information Model
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
+
*/
|
10 |
+
class Emv_DataSync_Model_DataProcess_PurchaseInformation extends Mage_Core_Model_Abstract
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* (non-PHPdoc)
|
14 |
+
* @see Varien_Object::_construct()
|
15 |
+
*/
|
16 |
+
public function _construct()
|
17 |
+
{
|
18 |
+
$this->_init('emvdatasync/dataProcess_purchaseInformation');
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Load purchase information by subscriber
|
23 |
+
*
|
24 |
+
* @param Mage_Newsletter_Model_Subscriber $subscriber
|
25 |
+
* @return Emv_DataSync_Model_DataProcess_PurchaseInformation
|
26 |
+
*/
|
27 |
+
public function loadBySubscriber(Mage_Newsletter_Model_Subscriber $subscriber)
|
28 |
+
{
|
29 |
+
$this->addData($this->getResource()->loadBySubscriber($subscriber));
|
30 |
+
return $this;
|
31 |
+
}
|
32 |
+
}
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Purchase Information Resource Model
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
*/
|
9 |
+
class Emv_DataSync_Model_Mysql4_DataProcess_PurchaseInformation extends Mage_Core_Model_Mysql4_Abstract
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* (non-PHPdoc)
|
13 |
+
* @see Mage_Core_Model_Resource_Abstract::_construct()
|
14 |
+
*/
|
15 |
+
public function _construct() {
|
16 |
+
$this->_init('emvdatasync/purchase_info', 'id');
|
17 |
+
}
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Load by subscriber
|
21 |
+
*
|
22 |
+
* @param Mage_Newsletter_Model_Subscriber $subscriber
|
23 |
+
* @return array
|
24 |
+
*/
|
25 |
+
public function loadBySubscriber(Mage_Newsletter_Model_Subscriber $subscriber)
|
26 |
+
{
|
27 |
+
$result = array();
|
28 |
+
if ($subscriber->getCustomerId()) {
|
29 |
+
$select = $this->_getReadAdapter()->select()
|
30 |
+
->from(array('main_table' => $this->getMainTable()))
|
31 |
+
->where('customer_id = :customer_id');
|
32 |
+
|
33 |
+
$result = $this->_getReadAdapter()->fetchRow($select, array('customer_id' => $subscriber->getCustomerId()));
|
34 |
+
|
35 |
+
if (!$result) {
|
36 |
+
$result = array();
|
37 |
+
}
|
38 |
+
}
|
39 |
+
|
40 |
+
return $result;
|
41 |
+
}
|
42 |
+
}
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Purchase Information Collection Resource Model
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
+
*/
|
10 |
+
class Emv_DataSync_Model_Mysql4_DataProcess_PurchaseInformation_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* (non-PHPdoc)
|
14 |
+
* @see Mage_Core_Model_Resource_Db_Collection_Abstract::_construct()
|
15 |
+
*/
|
16 |
+
public function _construct() {
|
17 |
+
$this->_init('emvdatasync/dataProcess_purchaseInformation');
|
18 |
+
}
|
19 |
+
}
|
@@ -4,30 +4,41 @@
|
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_DataSync
|
7 |
-
* @
|
|
|
8 |
*/
|
9 |
-
/* @var $customer Mage_Customer_Model_Customer */
|
10 |
-
/* @var $customerAddress Mage_Customer_Model_Address */
|
11 |
-
/* @var $subscriber Mage_Newsletter_Model_Subscriber */
|
12 |
-
/* @var $emailVisionApi Auguria_EmailVision_Model_Emailvision_Api */
|
13 |
-
/* @var $dateModel Mage_Core_Model_Date */
|
14 |
class Emv_DataSync_Model_Observer
|
15 |
{
|
16 |
-
|
17 |
-
|
18 |
-
|
|
|
19 |
protected $_instanciationTime;
|
20 |
|
|
|
|
|
|
|
|
|
21 |
protected $_customerHasDataChanged = array();
|
|
|
|
|
|
|
|
|
|
|
22 |
protected $_subscriberSaved = array();
|
23 |
|
24 |
/**
|
25 |
-
*
|
26 |
*
|
27 |
* @var array
|
28 |
*/
|
29 |
protected $_customerNewsletter = array();
|
30 |
|
|
|
|
|
|
|
|
|
|
|
31 |
/**
|
32 |
* Constructor, register $this instanciation datetime
|
33 |
*/
|
@@ -44,7 +55,7 @@ class Emv_DataSync_Model_Observer
|
|
44 |
*/
|
45 |
public function onSubscriberDelete(Varien_Event_Observer $observer)
|
46 |
{
|
47 |
-
if (Mage::getStoreConfigFlag(
|
48 |
$subscriber = $observer->getSubscriber();
|
49 |
// Direct unjoin (subscriber will be deleted on customer delete)
|
50 |
if ($subscriber->getId()) {
|
@@ -68,18 +79,20 @@ class Emv_DataSync_Model_Observer
|
|
68 |
*/
|
69 |
public function onCustomerAddressSave(Varien_Event_Observer $observer)
|
70 |
{
|
71 |
-
// If address is a billing one and has data changes, else nothing to do (avoid loading customer and subscriber)
|
72 |
$customerAddress = $observer->getCustomerAddress();
|
73 |
-
|
|
|
|
|
74 |
$customer = $customerAddress->getCustomer();
|
75 |
$subscriber = $this->getSubscriberFromCustomer($customer);
|
76 |
|
77 |
// If a subscriber is linked to this address' customer, update last data changes date
|
78 |
-
if (
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
|
|
83 |
}
|
84 |
}
|
85 |
}
|
@@ -140,11 +153,9 @@ class Emv_DataSync_Model_Observer
|
|
140 |
if ($subscriber && $subscriber->getId()) {
|
141 |
// Prevent multiple calls on a Mage::app instance
|
142 |
if (!$this->subscriberSaved($subscriber->getId())) {
|
143 |
-
if (
|
144 |
-
$subscriber->getStatus() == Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED
|
145 |
-
&& $customer->hasDataChanges()
|
146 |
-
) {
|
147 |
$this->setCustomerHasDataChanged($subscriber->getId());
|
|
|
148 |
}
|
149 |
}
|
150 |
}
|
@@ -170,20 +181,45 @@ class Emv_DataSync_Model_Observer
|
|
170 |
}
|
171 |
|
172 |
/**
|
173 |
-
* Method called on subscriber save.
|
174 |
-
* always have the return of getIsStatusChanged method setted to 1.
|
175 |
*
|
176 |
* @param Varien_Event_Observer $observer
|
177 |
*/
|
178 |
public function onSubscriberSave(Varien_Event_Observer $observer)
|
179 |
{
|
180 |
$subscriber = $observer->getSubscriber();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
if (!$subscriber->getId()) {
|
182 |
return false;
|
183 |
}
|
184 |
|
185 |
// Prevent multiple calls on a Mage::app instance
|
186 |
if (!$this->subscriberSaved($subscriber->getId())) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
if (
|
188 |
$subscriber->getStatus() == Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED
|
189 |
&& ($this->customerHasDataChanged($subscriber->getId()) || $this->isSubscriberStatusChanged($subscriber))
|
@@ -225,7 +261,7 @@ class Emv_DataSync_Model_Observer
|
|
225 |
* @param Mage_Newsletter_Model_Subscriber $subscriber
|
226 |
* @param boolean $isRejoining
|
227 |
*/
|
228 |
-
|
229 |
{
|
230 |
// Prevent infinite loops and multiple calls on a Mage::app instance
|
231 |
$this->setSubscriberSaved($subscriber->getId());
|
@@ -235,7 +271,8 @@ class Emv_DataSync_Model_Observer
|
|
235 |
$dateUnjoin = null;
|
236 |
}
|
237 |
|
238 |
-
$subscriber->setData(
|
|
|
239 |
$subscriber->save();
|
240 |
}
|
241 |
|
@@ -249,8 +286,38 @@ class Emv_DataSync_Model_Observer
|
|
249 |
// Prevent infinite loops and multiple calls on a Mage::app instance
|
250 |
$this->setSubscriberSaved($subscriber->getId());
|
251 |
|
252 |
-
$subscriber->setData(
|
|
|
253 |
$subscriber->save();
|
254 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
255 |
}
|
256 |
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_DataSync
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
*/
|
|
|
|
|
|
|
|
|
|
|
10 |
class Emv_DataSync_Model_Observer
|
11 |
{
|
12 |
+
/**
|
13 |
+
* Instanciation Date/time
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
protected $_instanciationTime;
|
17 |
|
18 |
+
/**
|
19 |
+
* List of customers that have data changes - use subscriber id as identifiant
|
20 |
+
* @var array
|
21 |
+
*/
|
22 |
protected $_customerHasDataChanged = array();
|
23 |
+
|
24 |
+
/**
|
25 |
+
* List of subscribers that have been saved
|
26 |
+
* @var array
|
27 |
+
*/
|
28 |
protected $_subscriberSaved = array();
|
29 |
|
30 |
/**
|
31 |
+
* List of loaded subscribers (sorted by customers)
|
32 |
*
|
33 |
* @var array
|
34 |
*/
|
35 |
protected $_customerNewsletter = array();
|
36 |
|
37 |
+
/**
|
38 |
+
* @var array
|
39 |
+
*/
|
40 |
+
protected $_customerHasSavedOrder = array();
|
41 |
+
|
42 |
/**
|
43 |
* Constructor, register $this instanciation datetime
|
44 |
*/
|
55 |
*/
|
56 |
public function onSubscriberDelete(Varien_Event_Observer $observer)
|
57 |
{
|
58 |
+
if (Mage::getStoreConfigFlag(Emv_DataSync_Helper_Data::XML_PATH_ENABLED_FOR_MEMBER)) {
|
59 |
$subscriber = $observer->getSubscriber();
|
60 |
// Direct unjoin (subscriber will be deleted on customer delete)
|
61 |
if ($subscriber->getId()) {
|
79 |
*/
|
80 |
public function onCustomerAddressSave(Varien_Event_Observer $observer)
|
81 |
{
|
|
|
82 |
$customerAddress = $observer->getCustomerAddress();
|
83 |
+
|
84 |
+
// Proceed data if address has data changes
|
85 |
+
if ($customerAddress->hasDataChanges()) {
|
86 |
$customer = $customerAddress->getCustomer();
|
87 |
$subscriber = $this->getSubscriberFromCustomer($customer);
|
88 |
|
89 |
// If a subscriber is linked to this address' customer, update last data changes date
|
90 |
+
if ($subscriber && $subscriber->getId()) {
|
91 |
+
// Prevent multiple calls on a Mage::app instance
|
92 |
+
if (!$this->subscriberSaved($subscriber->getId())) {
|
93 |
+
$this->setCustomerHasDataChanged($subscriber->getId());
|
94 |
+
$this->handleSubscriberInformation($subscriber);
|
95 |
+
}
|
96 |
}
|
97 |
}
|
98 |
}
|
153 |
if ($subscriber && $subscriber->getId()) {
|
154 |
// Prevent multiple calls on a Mage::app instance
|
155 |
if (!$this->subscriberSaved($subscriber->getId())) {
|
156 |
+
if ($customer->hasDataChanges()) {
|
|
|
|
|
|
|
157 |
$this->setCustomerHasDataChanged($subscriber->getId());
|
158 |
+
$this->handleSubscriberInformation($subscriber);
|
159 |
}
|
160 |
}
|
161 |
}
|
181 |
}
|
182 |
|
183 |
/**
|
184 |
+
* Method called on subscriber save.
|
|
|
185 |
*
|
186 |
* @param Varien_Event_Observer $observer
|
187 |
*/
|
188 |
public function onSubscriberSave(Varien_Event_Observer $observer)
|
189 |
{
|
190 |
$subscriber = $observer->getSubscriber();
|
191 |
+
|
192 |
+
$this->handleSubscriberInformation($subscriber);
|
193 |
+
}
|
194 |
+
|
195 |
+
/**
|
196 |
+
* Update the subscriber information according to the changes
|
197 |
+
*
|
198 |
+
* @param Mage_Newsletter_Model_Subscriber $subscriber
|
199 |
+
* @return boolean
|
200 |
+
*/
|
201 |
+
public function handleSubscriberInformation(Mage_Newsletter_Model_Subscriber $subscriber)
|
202 |
+
{
|
203 |
if (!$subscriber->getId()) {
|
204 |
return false;
|
205 |
}
|
206 |
|
207 |
// Prevent multiple calls on a Mage::app instance
|
208 |
if (!$this->subscriberSaved($subscriber->getId())) {
|
209 |
+
// if the subscriber was just created
|
210 |
+
if ($subscriber->getCustomerId() && $subscriber->isObjectNew()) {
|
211 |
+
try {
|
212 |
+
if (Mage::helper('emvdatasync')->doesCustomerHaveOrder($subscriber->getCustomerId())) {
|
213 |
+
$subscriber->setData(
|
214 |
+
Emv_DataSync_Helper_Service::FIELD_PURCHASE_LAST_UPDATE,
|
215 |
+
$this->_instanciationTime
|
216 |
+
);
|
217 |
+
}
|
218 |
+
} catch (Exception $e) {
|
219 |
+
Mage::logException($e);
|
220 |
+
}
|
221 |
+
}
|
222 |
+
|
223 |
if (
|
224 |
$subscriber->getStatus() == Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED
|
225 |
&& ($this->customerHasDataChanged($subscriber->getId()) || $this->isSubscriberStatusChanged($subscriber))
|
261 |
* @param Mage_Newsletter_Model_Subscriber $subscriber
|
262 |
* @param boolean $isRejoining
|
263 |
*/
|
264 |
+
public function updateUnjoinDate(Mage_Newsletter_Model_Subscriber $subscriber, $isRejoining = false)
|
265 |
{
|
266 |
// Prevent infinite loops and multiple calls on a Mage::app instance
|
267 |
$this->setSubscriberSaved($subscriber->getId());
|
271 |
$dateUnjoin = null;
|
272 |
}
|
273 |
|
274 |
+
$subscriber->setData(Emv_DataSync_Helper_Service::FIELD_DATE_UNJOIN, $dateUnjoin);
|
275 |
+
$subscriber->setData(Emv_DataSync_Helper_Service::FIELD_QUEUED, Emv_DataSync_Helper_Service::SCHEDULED_VALUE);
|
276 |
$subscriber->save();
|
277 |
}
|
278 |
|
286 |
// Prevent infinite loops and multiple calls on a Mage::app instance
|
287 |
$this->setSubscriberSaved($subscriber->getId());
|
288 |
|
289 |
+
$subscriber->setData(Emv_DataSync_Helper_Service::FIELD_DATA_LAST_UPDATE, $this->_instanciationTime);
|
290 |
+
$subscriber->setData(Emv_DataSync_Helper_Service::FIELD_QUEUED, Emv_DataSync_Helper_Service::SCHEDULED_VALUE);
|
291 |
$subscriber->save();
|
292 |
}
|
293 |
+
|
294 |
+
/**
|
295 |
+
* Observer on order save after event, update subscriber information according to the changes
|
296 |
+
*
|
297 |
+
* @param Varien_Event_Observer $observer
|
298 |
+
*/
|
299 |
+
public function handleOrderSaveAfter(Varien_Event_Observer $observer)
|
300 |
+
{
|
301 |
+
/* @var $order Mage_Sales_Model_Order */
|
302 |
+
$order = $observer->getEvent()->getOrder();
|
303 |
+
|
304 |
+
$customer = Mage::getSingleton('customer/session')->getCustomer();
|
305 |
+
if ($customer instanceof Mage_Customer_Model_Customer && $customer->getId()) {
|
306 |
+
$subscriber = $this->getSubscriberFromCustomer($customer);
|
307 |
+
if ($subscriber && $subscriber->getId() && !isset($this->_customerHasSavedOrder[$subscriber->getId()])) {
|
308 |
+
$subscriber->setData(
|
309 |
+
Emv_DataSync_Helper_Service::FIELD_PURCHASE_LAST_UPDATE,
|
310 |
+
$this->_instanciationTime
|
311 |
+
);
|
312 |
+
$subscriber->setData(
|
313 |
+
Emv_DataSync_Helper_Service::FIELD_QUEUED,
|
314 |
+
Emv_DataSync_Helper_Service::SCHEDULED_VALUE
|
315 |
+
);
|
316 |
+
$subscriber->save();
|
317 |
+
|
318 |
+
$this->_customerHasSavedOrder[$subscriber->getId()] = true;
|
319 |
+
}
|
320 |
+
}
|
321 |
+
}
|
322 |
}
|
323 |
|
@@ -3,16 +3,17 @@
|
|
3 |
* Batch Member service - Handle Member Data
|
4 |
*
|
5 |
* @category Emv
|
6 |
-
* @package
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
*/
|
10 |
class Emv_DataSync_Model_Service_BatchMember extends Emv_Core_Model_Service_BatchMember
|
|
|
11 |
{
|
12 |
/**
|
13 |
* XML config path for performance config
|
14 |
*/
|
15 |
-
const XML_PATH_PERFORMANCE = '
|
16 |
|
17 |
/**
|
18 |
* The default limit of subscribers to get
|
@@ -20,9 +21,9 @@ class Emv_DataSync_Model_Service_BatchMember extends Emv_Core_Model_Service_Batc
|
|
20 |
const PAGE_SIZE = 10000;
|
21 |
|
22 |
/**
|
23 |
-
* Waiting time between each status checking call
|
24 |
*/
|
25 |
-
const WAITING_TIME =
|
26 |
|
27 |
/**
|
28 |
* @var boolean
|
@@ -36,14 +37,11 @@ class Emv_DataSync_Model_Service_BatchMember extends Emv_Core_Model_Service_Batc
|
|
36 |
|
37 |
// Subscribers collection management vars
|
38 |
protected $_pageSize;
|
39 |
-
protected $_pageCount;
|
40 |
-
protected $_curPage;
|
41 |
|
42 |
// Files and upload data
|
43 |
-
protected $_uploadId;
|
44 |
protected $_errors = array();
|
45 |
-
|
46 |
-
protected $
|
47 |
|
48 |
/**
|
49 |
* Mapped headers
|
@@ -52,16 +50,34 @@ class Emv_DataSync_Model_Service_BatchMember extends Emv_Core_Model_Service_Batc
|
|
52 |
protected $_mappedHeaders = array();
|
53 |
|
54 |
/**
|
55 |
-
*
|
56 |
* @var array
|
57 |
*/
|
58 |
-
protected $
|
59 |
|
60 |
/**
|
61 |
-
*
|
62 |
-
* @var
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
*/
|
64 |
-
protected $
|
65 |
|
66 |
/**
|
67 |
* (non-PHPdoc)
|
@@ -75,181 +91,592 @@ class Emv_DataSync_Model_Service_BatchMember extends Emv_Core_Model_Service_Batc
|
|
75 |
$this->_pageSize = self::PAGE_SIZE;
|
76 |
}
|
77 |
|
78 |
-
// everything should be in GMT
|
79 |
-
$this->_currentTime = Mage::getModel('core/date')->gmtDate('Ymd_H-i-s');
|
80 |
-
|
81 |
return parent::_construct();
|
82 |
}
|
83 |
|
84 |
/**
|
85 |
-
*
|
|
|
|
|
86 |
*/
|
87 |
-
public function
|
88 |
{
|
89 |
-
$
|
90 |
-
|
91 |
-
$
|
92 |
-
$totalSubscribersCount = $subscribers->getSize();
|
93 |
-
$this->_pageCount = ceil($subscribers->getSize() / $this->_pageSize);
|
94 |
-
|
95 |
-
if ($subscribers->getSize() > 0) {
|
96 |
-
// Add all customer and address attributes that have been mapped into collection
|
97 |
-
Mage::helper('emvdatasync/service')->addCustomerAndAddressAttributes($subscribers);
|
98 |
-
|
99 |
-
// Get all stores
|
100 |
-
$stores = Mage::app()->getStores(true);
|
101 |
-
|
102 |
-
// Get mapped EmailVision entity id
|
103 |
-
$entityId = strtoupper(Mage::helper('emvdatasync')->getMappedEntityId());
|
104 |
-
|
105 |
-
// Get api service corresponding to current account
|
106 |
-
$service = $this->getApiService($this->getAccount());
|
107 |
-
|
108 |
-
for ($this->_curPage = 1; $this->_curPage <= $this->_pageCount; $this->_curPage++) {
|
109 |
-
// Define current page
|
110 |
-
$subscribers->clear()
|
111 |
-
->setPageSize($this->_pageSize)
|
112 |
-
->setCurPage($this->_curPage);
|
113 |
-
|
114 |
-
// Add a row foreach customer
|
115 |
-
$preparedData = array();
|
116 |
-
foreach ($subscribers as $subscriber) {
|
117 |
-
// Replace customer email by suscriber one
|
118 |
-
$subscriber->setData('email', $subscriber->getSubscriberEmail());
|
119 |
-
|
120 |
-
// Prepare and add a customer's data row
|
121 |
-
$subscriberData = array();
|
122 |
-
|
123 |
-
// retreive all maped attribute values from subscriber, build them into array
|
124 |
-
$entityFieldsToSelect = Mage::helper('emvdatasync/service')->prepareAndGetMappedCustomerAttributes();
|
125 |
-
foreach ($entityFieldsToSelect as $attribute) {
|
126 |
-
$emailVisionKey = strtoupper($attribute->getEmailVisionKey());
|
127 |
-
|
128 |
-
$fieldCode = ($attribute->getFinalAttributeCode())
|
129 |
-
? $attribute->getFinalAttributeCode() : $attribute->getAttributeCode();
|
130 |
-
$fieldValue = '';
|
131 |
-
|
132 |
-
if ($attribute->getFrontendInput() == 'date') {
|
133 |
-
if ($subscriber->getData($fieldCode)) {
|
134 |
-
// date time should be in EmailVision format
|
135 |
-
$fieldValue = Mage::helper('emvdatasync/service')
|
136 |
-
->getEmailVisionDate($subscriber->getData($fieldCode));
|
137 |
-
}
|
138 |
-
} else {
|
139 |
-
$fieldValue = $subscriber->getData($fieldCode);
|
140 |
-
if ($fieldCode == 'store_id' && isset($stores[$fieldValue])) {
|
141 |
-
$fieldValue = $stores[$fieldValue]->getName();
|
142 |
-
}
|
143 |
-
}
|
144 |
|
145 |
-
|
146 |
-
|
|
|
147 |
|
148 |
-
|
149 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
150 |
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
if ($subscriber->getData('date_unjoin')) {
|
155 |
-
// date time should be in EmailVision format
|
156 |
-
$unjoinedDate = Mage::helper('emvdatasync/service')
|
157 |
-
->getEmailVisionDate($subscriber->getData('date_unjoin'));
|
158 |
-
}
|
159 |
-
}
|
160 |
-
$subscriberData[strtoupper(Emv_Core_Model_Service_Member::FIELD_UNJOIN)] = $unjoinedDate;
|
161 |
-
$preparedData[] = array(
|
162 |
-
'id' => $subscriber->getId(),
|
163 |
-
'fields' => $subscriberData
|
164 |
-
);
|
165 |
|
166 |
-
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
}
|
176 |
-
$this->_subscriberDataList[$subscriber->getId()] = $tempSubscriber;
|
177 |
-
}// end foreach subscribers
|
178 |
|
179 |
-
|
180 |
-
$
|
181 |
-
|
182 |
-
|
183 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
184 |
);
|
|
|
185 |
|
186 |
-
|
187 |
-
|
188 |
-
$
|
189 |
-
|
|
|
190 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
} catch (Exception $e) {
|
192 |
Mage::logException($e);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
|
194 |
-
|
|
|
|
|
|
|
|
|
195 |
}
|
196 |
-
}
|
|
|
197 |
}
|
|
|
|
|
|
|
198 |
}
|
199 |
|
200 |
/**
|
201 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
202 |
*
|
203 |
-
* @
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
204 |
*/
|
205 |
-
|
206 |
{
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
211 |
}
|
212 |
-
return $mergeCriteria;
|
213 |
}
|
214 |
|
215 |
/**
|
216 |
-
*
|
217 |
-
*
|
|
|
|
|
218 |
*/
|
219 |
-
|
220 |
{
|
221 |
-
|
222 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
223 |
|
224 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
|
226 |
-
|
227 |
-
|
|
|
|
|
|
|
|
|
228 |
|
229 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
230 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
try {
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
|
237 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
238 |
$data,
|
239 |
$mappedHeaders,
|
240 |
-
$
|
241 |
false
|
242 |
);
|
243 |
|
|
|
|
|
244 |
// only checking upload status if we can have upload id
|
245 |
-
if ($
|
246 |
$uploadProcessing = true;
|
|
|
247 |
// wait until SmartFocus platform completes processing uploaded file
|
248 |
// check status's upload for an interval self::WAITING_TIME
|
249 |
do {
|
250 |
sleep(self::WAITING_TIME);
|
251 |
// get status's upload
|
252 |
-
$uploadStatus = $service->getUploadStatus($
|
253 |
|
254 |
if (
|
255 |
in_array(
|
@@ -257,45 +684,79 @@ class Emv_DataSync_Model_Service_BatchMember extends Emv_Core_Model_Service_Batc
|
|
257 |
EmailVision_Api_BatchMemberService::getAccomplishedStatuses()
|
258 |
)
|
259 |
) {
|
|
|
|
|
|
|
260 |
$uploadProcessing = false;
|
261 |
if (
|
262 |
$uploadStatus['status'] == EmailVision_Api_BatchMemberService::getStatusOkWithoutError()
|
263 |
) {
|
264 |
-
$
|
265 |
} else {
|
266 |
-
$
|
267 |
-
|
268 |
-
|
|
|
|
|
|
|
|
|
269 |
}
|
270 |
}
|
271 |
} while ($uploadProcessing);
|
272 |
-
|
273 |
-
|
274 |
-
$this->moveUploadedFile($data);
|
275 |
}
|
276 |
}
|
|
|
|
|
|
|
|
|
277 |
} catch (Exception $e) {
|
278 |
-
$uploadDone = false;
|
279 |
Mage::logException($e);
|
280 |
|
281 |
-
$
|
282 |
. $e->getMessage();
|
283 |
}
|
284 |
|
285 |
-
|
286 |
-
|
287 |
|
288 |
-
|
289 |
-
|
290 |
-
|
291 |
-
|
292 |
-
|
293 |
-
|
294 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
295 |
}
|
296 |
}
|
|
|
297 |
|
298 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
299 |
}
|
300 |
|
301 |
/**
|
@@ -318,119 +779,146 @@ class Emv_DataSync_Model_Service_BatchMember extends Emv_Core_Model_Service_Batc
|
|
318 |
}
|
319 |
|
320 |
// Preparing filename
|
321 |
-
$filename = 'customers' . $this->_currentTime . '_part' . $index . '.csv';
|
322 |
|
323 |
// Preparing file path
|
324 |
-
$path = Mage::getBaseDir(
|
|
|
325 |
return array('filename' => $filename, 'path' => $path, 'time' => $this->_currentTime);
|
326 |
}
|
327 |
|
328 |
/**
|
329 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
330 |
*/
|
331 |
-
public function
|
332 |
{
|
333 |
-
$
|
334 |
-
|
335 |
-
|
|
|
336 |
// Cases: mass export will have a _fileNamesUploaded set, member export will have _subsciberIds
|
337 |
-
if (!empty($
|
338 |
-
foreach ($
|
339 |
-
if (isset($
|
340 |
-
|
341 |
-
|
342 |
-
|
343 |
-
|
344 |
-
|
345 |
-
|
346 |
-
|
|
|
|
|
|
|
347 |
}
|
348 |
-
|
349 |
}
|
350 |
}
|
351 |
}
|
352 |
-
|
353 |
-
try {
|
354 |
-
$errorMessage = Mage::helper('emvdatasync/service')->massSetMemberLastUpdateDate($subscribersIds, $rejoinedIds);
|
355 |
-
if ($errorMessage !== true) {
|
356 |
-
$this->_errors[] = $errorMessage;
|
357 |
-
}
|
358 |
-
} catch (Exception $e) {
|
359 |
-
Mage::logException($e);
|
360 |
-
}
|
361 |
}
|
|
|
|
|
362 |
}
|
363 |
|
364 |
/**
|
365 |
-
*
|
366 |
-
*
|
|
|
|
|
|
|
|
|
367 |
*/
|
368 |
-
public function
|
369 |
{
|
370 |
-
|
371 |
-
|
372 |
-
Mage::
|
373 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
374 |
}
|
375 |
|
376 |
/**
|
377 |
-
* @
|
|
|
|
|
378 |
*/
|
379 |
-
public function getSubscriberCollection()
|
380 |
{
|
381 |
-
/* @var $subscribers
|
382 |
-
// Get all subscribers that have data modifed since the last sync as well as the unsubscribed ones
|
383 |
$subscribers = Mage::getModel('newsletter/subscriber')->getCollection();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
384 |
|
385 |
-
$
|
386 |
-
|
387 |
-
|
388 |
-
|
389 |
-
$select = $subscribers->getSelect();
|
390 |
-
// in the case of member_last_update is not null
|
391 |
-
// - data_last_update_date > member_last_update => member data has been changed
|
392 |
-
// - main_table.date_unjoin > member_last_update => member has just unjoined
|
393 |
-
$notNullMemberCond = "main_table.{$fieldMemberLastUpdate} IS NOT NULL"
|
394 |
-
. " AND ( main_table.{$fieldDataLastUpdate} > main_table.{$fieldMemberLastUpdate}"
|
395 |
-
. " OR main_table.{$fieldUnjoin} > main_table.{$fieldMemberLastUpdate}"
|
396 |
-
. ' )';
|
397 |
-
$select->where($notNullMemberCond);
|
398 |
-
$select->orWhere("main_table.{$fieldMemberLastUpdate} IS NULL");
|
399 |
|
400 |
return $subscribers;
|
401 |
}
|
402 |
|
403 |
/**
|
|
|
|
|
|
|
404 |
* @return array
|
405 |
*/
|
406 |
-
public function prepareAndGetMappedHeaders()
|
407 |
{
|
408 |
-
|
409 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
410 |
|
411 |
// retreive all maped attribute values from subscriber, build them into array
|
412 |
-
$entityFieldsToSelect = Mage::
|
|
|
413 |
foreach ($entityFieldsToSelect as $attribute) {
|
414 |
-
$emailVisionKey = $attribute->
|
415 |
$emailVisionKey = strtoupper($emailVisionKey);
|
416 |
|
417 |
-
$this->_mappedHeaders[strtoupper($emailVisionKey)] = array(
|
418 |
'to_replace' => true
|
419 |
);
|
420 |
}
|
421 |
|
422 |
// the entity id can not be replaced
|
423 |
$entityIdField = Mage::helper('emvdatasync')->getMappedEntityId();
|
424 |
-
$this->_mappedHeaders[strtoupper($entityIdField)] = array(
|
425 |
'to_replace' => false
|
426 |
);
|
427 |
|
428 |
-
$this->_mappedHeaders[strtoupper(Emv_Core_Model_Service_Member::FIELD_UNJOIN)] = array(
|
429 |
'to_replace' => true
|
430 |
);
|
431 |
}
|
432 |
|
433 |
-
return $this->_mappedHeaders;
|
434 |
}
|
435 |
|
436 |
/**
|
3 |
* Batch Member service - Handle Member Data
|
4 |
*
|
5 |
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
*/
|
10 |
class Emv_DataSync_Model_Service_BatchMember extends Emv_Core_Model_Service_BatchMember
|
11 |
+
implements Emv_Core_Model_DataProcessing_Profile_Interface
|
12 |
{
|
13 |
/**
|
14 |
* XML config path for performance config
|
15 |
*/
|
16 |
+
const XML_PATH_PERFORMANCE = 'emvdatasync/batchmember/performance';
|
17 |
|
18 |
/**
|
19 |
* The default limit of subscribers to get
|
21 |
const PAGE_SIZE = 10000;
|
22 |
|
23 |
/**
|
24 |
+
* Waiting time (seconds) between each status checking call
|
25 |
*/
|
26 |
+
const WAITING_TIME = 40;
|
27 |
|
28 |
/**
|
29 |
* @var boolean
|
37 |
|
38 |
// Subscribers collection management vars
|
39 |
protected $_pageSize;
|
|
|
|
|
40 |
|
41 |
// Files and upload data
|
|
|
42 |
protected $_errors = array();
|
43 |
+
|
44 |
+
protected $_exportFilePrefix = '';
|
45 |
|
46 |
/**
|
47 |
* Mapped headers
|
50 |
protected $_mappedHeaders = array();
|
51 |
|
52 |
/**
|
53 |
+
* Input data for service
|
54 |
* @var array
|
55 |
*/
|
56 |
+
protected $_inputData = array();
|
57 |
|
58 |
/**
|
59 |
+
* Profile type
|
60 |
+
* @var string
|
61 |
+
*/
|
62 |
+
public static $type = Emv_Core_Model_DataProcessing_Process::TYPE_DATA_SYNC;
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Profile title
|
66 |
+
* @var string
|
67 |
+
*/
|
68 |
+
protected $_title = 'Batch Member Data Synchronization';
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Current process
|
72 |
+
* @var Emv_Core_Model_DataProcessing_Process
|
73 |
+
*/
|
74 |
+
protected $_process = null;
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Process class name
|
78 |
+
* @var string
|
79 |
*/
|
80 |
+
protected $_processClassName = 'emvcore/dataProcessing_process';
|
81 |
|
82 |
/**
|
83 |
* (non-PHPdoc)
|
91 |
$this->_pageSize = self::PAGE_SIZE;
|
92 |
}
|
93 |
|
|
|
|
|
|
|
94 |
return parent::_construct();
|
95 |
}
|
96 |
|
97 |
/**
|
98 |
+
* Get default profile process
|
99 |
+
*
|
100 |
+
* @return Emv_Core_Model_DataProcessing_Process $process
|
101 |
*/
|
102 |
+
public function initProcess()
|
103 |
{
|
104 |
+
$process = Mage::getModel($this->_processClassName);
|
105 |
+
$process->setTitle($this->_title);
|
106 |
+
$process->setType(self::$type);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
|
108 |
+
$process->save();
|
109 |
+
return $process;
|
110 |
+
}
|
111 |
|
112 |
+
/**
|
113 |
+
* Init profile
|
114 |
+
*
|
115 |
+
* @param Emv_Core_Model_DataProcessing_Process $process
|
116 |
+
*
|
117 |
+
* @return void
|
118 |
+
* @throws Exception
|
119 |
+
*/
|
120 |
+
public function init(Emv_Core_Model_DataProcessing_Process $process = null)
|
121 |
+
{
|
122 |
+
if (is_null($process)) {
|
123 |
+
$process = $this->initProcess();
|
124 |
+
}
|
125 |
|
126 |
+
$process->initLog();
|
127 |
+
$this->_process = $process;
|
128 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
129 |
|
130 |
+
/**
|
131 |
+
* (non-PHPdoc)
|
132 |
+
* @see Emv_Core_Model_DataProcessing_Profile_Interface::getInputData()
|
133 |
+
*/
|
134 |
+
public function getInputData()
|
135 |
+
{
|
136 |
+
return $this->_inputData;
|
137 |
+
}
|
138 |
+
|
139 |
+
/**
|
140 |
+
* (non-PHPdoc)
|
141 |
+
* @see Emv_Core_Model_DataProcessing_Profile_Interface::setInputData()
|
142 |
+
*/
|
143 |
+
public function setInputData(array $input)
|
144 |
+
{
|
145 |
+
$this->_inputData = $input;
|
146 |
+
return $this;
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* Get Associated Process
|
151 |
+
* (non-PHPdoc)
|
152 |
+
* @see Emv_Core_Model_DataProcessing_Profile_Interface::getProcess()
|
153 |
+
*/
|
154 |
+
public function getProcess()
|
155 |
+
{
|
156 |
+
return $this->_process;
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Run the process of mass subscriber export
|
161 |
+
* - if member_ids is defined and an array, only the subscribers in this list are synced
|
162 |
+
* - if dry_mode is defined and contains true, we only create the csv files, no sync will be done at SmartFocus
|
163 |
+
* - if test_mode is defined, we run the process in test mode
|
164 |
+
*
|
165 |
+
* (non-PHPdoc)
|
166 |
+
* @see Emv_Core_Model_DataProcessing_Profile_Interface::run()
|
167 |
+
*/
|
168 |
+
public function run()
|
169 |
+
{
|
170 |
+
$inputData = $this->getInputData();
|
171 |
+
|
172 |
+
$memberIds = array();
|
173 |
+
if(isset($inputData['member_ids']) && is_array($inputData['member_ids'])) {
|
174 |
+
$memberIds = $inputData['member_ids'];
|
175 |
+
}
|
176 |
+
|
177 |
+
$dryMode = false;
|
178 |
+
if (isset($inputData['dry_mode'])) {
|
179 |
+
$dryMode = $inputData['dry_mode'];
|
180 |
+
}
|
181 |
+
|
182 |
+
$testMode = false;
|
183 |
+
if (isset($inputData['test_mode'])) {
|
184 |
+
$testMode = $inputData['test_mode'];
|
185 |
+
}
|
186 |
+
|
187 |
+
$this->massExportCustomers($memberIds, $dryMode, $testMode);
|
188 |
+
|
189 |
+
}
|
190 |
+
|
191 |
+
/**
|
192 |
+
* Export customers, by default if member id list is empty, we only take the scheduled members
|
193 |
+
*
|
194 |
+
* @param array $memberIds - which subscribers/members are allowed to sync
|
195 |
+
* @param boolean $dryMode - only allows to create csv file(s), no sync will be triggered
|
196 |
+
* @param boolean $testMode - run the export in test mode
|
197 |
+
* @param array - sorted by account id
|
198 |
+
* for each account, we have :
|
199 |
+
* - treated_files : all the files (path, name, label) have been created
|
200 |
+
* - uploaded_subscribers : the number of subscribers that have been correctly synced
|
201 |
+
*/
|
202 |
+
public function massExportCustomers(array $memberIds = array(), $dryMode = false, $testMode = false)
|
203 |
+
{
|
204 |
+
// Set new title
|
205 |
+
if ($this->getProcess()) {
|
206 |
+
if ($dryMode) {
|
207 |
+
$this->getProcess()->setTitle($this->_title . ' - Dry Mode');
|
208 |
+
}
|
209 |
+
if ($testMode) {
|
210 |
+
$this->getProcess()->setTitle($this->_title . ' - Manual Sync');
|
211 |
+
}
|
212 |
+
// run process
|
213 |
+
$this->getProcess()->run();
|
214 |
+
}
|
215 |
+
|
216 |
+
// get all active account for batch member service
|
217 |
+
$accounts = Mage::helper('emvdatasync')->getActiveEmvAccountsForStore(Emv_DataSync_Helper_Data::TYPE_BATCH);
|
218 |
+
|
219 |
+
// prepare final export info array
|
220 |
+
$exportInfo = array();
|
221 |
+
$this->_errors = array();
|
222 |
+
|
223 |
+
$percentForEachAccount = 100;
|
224 |
+
if (count($accounts)) {
|
225 |
+
$percentForEachAccount = 100 / count($accounts);
|
226 |
+
}
|
227 |
+
|
228 |
+
// the current percentage of the process
|
229 |
+
$currentPercent = 0;
|
230 |
+
|
231 |
+
$this->_updateProcess('Start Process');
|
232 |
+
foreach ($accounts as $accountId => $accountData)
|
233 |
+
{
|
234 |
+
$storeIds = $accountData['stores'];
|
235 |
+
$account = $accountData['model'];
|
236 |
+
$service = false;
|
237 |
+
$currentStore = $storeIds[0];
|
238 |
+
$totalTreatedSubscribers = array(
|
239 |
+
'treated_subscribers' => array(),
|
240 |
+
'rejoined_subscribers' => array(),
|
241 |
+
);
|
242 |
+
|
243 |
+
$exportInfo[$accountId] = array(
|
244 |
+
'treated_files' => array(),
|
245 |
+
'uploaded_subscribers' => 0,
|
246 |
+
);
|
247 |
+
|
248 |
+
$this->_updateProcess('Start proceeding account "' . $account->getName() . '"');
|
249 |
+
|
250 |
+
try {
|
251 |
+
// Get api service corresponding to current account
|
252 |
+
$service = $this->getApiService($account, $storeIds[0]);
|
253 |
+
} catch (Exception $e) {
|
254 |
+
$this->_errors[] = "The account {$account->getName()} is invalid : " . $e->getMessage();
|
255 |
+
}
|
256 |
+
|
257 |
+
if (!$service) {
|
258 |
+
$currentPercent = $currentPercent + $percentForEachAccount;
|
259 |
+
} else {
|
260 |
+
// only get subscribers from the associated stores
|
261 |
+
$subscribers = $subscribers = $this->getSubscriberCollection($memberIds, $storeIds);
|
262 |
+
$currentPercent = $currentPercent + (0.03 * $percentForEachAccount);
|
263 |
+
$this->_updateProcess('Prepare Subscriber Collection', Zend_Log::INFO, $currentPercent);
|
264 |
+
|
265 |
+
// Add all customer and address attributes that have been mapped into collection
|
266 |
+
Mage::getSingleton('emvdatasync/attributeProcessing_config')
|
267 |
+
->prepareSubscriberCollection($subscribers, $currentStore);
|
268 |
+
$currentPercent = $currentPercent + (0.07 * $percentForEachAccount);
|
269 |
+
$this->_updateProcess('Add mapping attributes into collection', Zend_Log::INFO, $currentPercent);
|
270 |
+
|
271 |
+
// calculate the number of pages to export
|
272 |
+
$pageCount = ceil($subscribers->getSize() / $this->_pageSize);
|
273 |
+
$this->_updateProcess(
|
274 |
+
'Collection contains ' . (int)$subscribers->getSize() . ' subscribers'
|
275 |
+
. ' divided in ' . $pageCount . ' pages (' . $this->_pageSize . ' members/page)'
|
276 |
+
);
|
277 |
+
|
278 |
+
if ($subscribers->getSize() == 0) {
|
279 |
+
$currentPercent = $currentPercent + (0.97 * $percentForEachAccount);
|
280 |
+
} else {
|
281 |
+
|
282 |
+
// everything should be in GMT
|
283 |
+
$this->_currentTime = Mage::getModel('core/date')->gmtDate('Ymd_H-i-s');
|
284 |
+
// make a new file prefix
|
285 |
+
$this->_exportFilePrefix = 'magento_account_' . $account->getId() . '_';
|
286 |
+
|
287 |
+
$percentForEachPage = 0.9 * $percentForEachAccount / $pageCount;
|
288 |
+
for ($curPage = 1; $curPage <= $pageCount; $curPage++) {
|
289 |
+
$this->_updateProcess('Start Proceeding Page ' . $curPage);
|
290 |
+
|
291 |
+
// Define current page
|
292 |
+
$subscribers->clear()
|
293 |
+
->setPageSize($this->_pageSize)
|
294 |
+
->setCurPage($curPage);
|
295 |
+
$this->_updateProcess('Get subscriber list');
|
296 |
+
|
297 |
+
$this->_updateProcess('Creating csv files');
|
298 |
+
// prepare csv files
|
299 |
+
$arrayReturn = $this->prepareCustomerCsvFiles($subscribers, $currentStore, $service);
|
300 |
+
$this->_errors = array_merge($arrayReturn['errors'], $this->_errors);
|
301 |
+
|
302 |
+
// update process for creating file step
|
303 |
+
$currentPercent = $currentPercent + (0.2 * $percentForEachPage);
|
304 |
+
$this->_updateProcessWhileCreatingFiles($arrayReturn, $currentPercent);
|
305 |
+
|
306 |
+
if ($dryMode) {
|
307 |
+
$currentPercent = $currentPercent + (0.8 * $percentForEachPage);
|
308 |
+
|
309 |
+
$this->_prepareOutputInfo(
|
310 |
+
$exportInfo[$accountId],
|
311 |
+
array(),
|
312 |
+
$arrayReturn
|
313 |
+
);
|
314 |
+
$this->_updateProcess('Prepare final export information');
|
315 |
+
|
316 |
+
} else {
|
317 |
+
$this->_updateProcess('Uploading csv files');
|
318 |
+
// send file and get status upload
|
319 |
+
$uploadInfo = $this->sendFileAndGetStatusUpload(
|
320 |
+
$arrayReturn['created_files'],
|
321 |
+
$currentStore,
|
322 |
+
$service
|
323 |
+
);
|
324 |
+
$this->_errors = array_merge($uploadInfo['errors'], $this->_errors);
|
325 |
+
|
326 |
+
// update process for uploading file step
|
327 |
+
$currentPercent = $currentPercent + (0.7 * $percentForEachPage);
|
328 |
+
$this->_updateProcess('Uploading files is done.', Zend_Log::INFO, $currentPercent);
|
329 |
+
$this->_updateProcessWhileUploadingFiles(
|
330 |
+
$uploadInfo,
|
331 |
+
$arrayReturn['writtent_subscriber_ids']
|
332 |
+
);
|
333 |
+
|
334 |
+
// move proceeded files to new placements
|
335 |
+
$this->treatProceededFiles($uploadInfo);
|
336 |
+
// update process for uploading file step
|
337 |
+
$currentPercent = $currentPercent + (0.1 * $percentForEachPage);
|
338 |
+
$this->_updateProcess('Treat uploaded files ', Zend_Log::INFO, $currentPercent);
|
339 |
+
|
340 |
+
// prepare treated subscriber list
|
341 |
+
$treatedList = $this->getTreatedSubscribers (
|
342 |
+
$uploadInfo['uploaded_files'],
|
343 |
+
$arrayReturn['writtent_subscriber_ids'],
|
344 |
+
$arrayReturn['subscriber_data_list']
|
345 |
+
);
|
346 |
+
$totalTreatedSubscribers['treated_subscribers'] = array_merge(
|
347 |
+
$treatedList['treated_subscribers'],
|
348 |
+
$totalTreatedSubscribers['treated_subscribers']
|
349 |
+
);
|
350 |
+
$totalTreatedSubscribers['rejoined_subscribers'] = array_merge(
|
351 |
+
$treatedList['rejoined_subscribers'],
|
352 |
+
$totalTreatedSubscribers['rejoined_subscribers']
|
353 |
+
);
|
354 |
+
|
355 |
+
// prepare out put information
|
356 |
+
$this->_prepareOutputInfo(
|
357 |
+
$exportInfo[$accountId],
|
358 |
+
$uploadInfo,
|
359 |
+
$arrayReturn
|
360 |
+
);
|
361 |
+
$this->_updateProcess('Prepare final export information');
|
362 |
+
|
363 |
+
unset($uploadInfo);
|
364 |
+
}
|
365 |
+
|
366 |
+
unset($arrayReturn);
|
367 |
+
$this->_updateProcess('End Proceeding Page ' . $curPage, Zend_Log::INFO, $currentPercent);
|
368 |
}
|
|
|
|
|
369 |
|
370 |
+
// clear all fetched data
|
371 |
+
$subscribers->getSelect()->reset();
|
372 |
+
$subscribers->resetData()->clear();
|
373 |
+
unset($subscribers);
|
374 |
+
Mage::getSingleton('emvdatasync/attributeProcessing_config')
|
375 |
+
->cleanMappedCustomerAttributes($currentStore);
|
376 |
+
$this->_updateProcess('Clean proceeded data');
|
377 |
+
} // subscriber collection is not empty
|
378 |
+
|
379 |
+
if (count($totalTreatedSubscribers['treated_subscribers'])) {
|
380 |
+
$errors = $this->massSetMemberLastUpdateDate(
|
381 |
+
$totalTreatedSubscribers['treated_subscribers'],
|
382 |
+
$totalTreatedSubscribers['rejoined_subscribers']
|
383 |
);
|
384 |
+
$this->_errors = array_merge($errors, $this->_errors);
|
385 |
|
386 |
+
$this->_updateProcess('Flag uploaded subscribers');
|
387 |
+
if (count($errors)) {
|
388 |
+
$error = "Process has encoutered the following errors when flagging uploaded subsscribers : \n"
|
389 |
+
. implode("\n", $errors);
|
390 |
+
$this->_updateProcess($error);
|
391 |
}
|
392 |
+
}
|
393 |
+
|
394 |
+
unset($totalTreatedSubscribers);
|
395 |
+
|
396 |
+
try {
|
397 |
+
$service->closeApiConnection();
|
398 |
} catch (Exception $e) {
|
399 |
Mage::logException($e);
|
400 |
+
$this->_errors[] = "Exception while closing SmartFocus service for account {{$account->getName()}} with message : "
|
401 |
+
. $e->getMessage();
|
402 |
+
}
|
403 |
+
} // end if service
|
404 |
+
|
405 |
+
$this->_updateProcess('Total of uploaded files : ' . count($exportInfo[$accountId]['treated_files']));
|
406 |
+
$this->_updateProcess('Total of uploaded subscribers : ' . $exportInfo[$accountId]['uploaded_subscribers']);
|
407 |
+
$this->_updateProcess('End proceeding account "' . $account->getName() . '"', Zend_Log::INFO, $currentPercent);
|
408 |
+
$this->_updateProcess('*************************');
|
409 |
+
}
|
410 |
|
411 |
+
// add output information into process and finalize it
|
412 |
+
if ($this->getProcess()) {
|
413 |
+
foreach ($exportInfo as $infoByAccount) {
|
414 |
+
foreach ($infoByAccount['treated_files'] as $fileOutput) {
|
415 |
+
$this->getProcess()->addOutputInformation($fileOutput);
|
416 |
}
|
417 |
+
}
|
418 |
+
$this->getProcess()->finalize();
|
419 |
}
|
420 |
+
$this->_updateProcess('End Process', Zend_Log::INFO, 100);
|
421 |
+
|
422 |
+
return $exportInfo;
|
423 |
}
|
424 |
|
425 |
/**
|
426 |
+
* Update process with a new message at give level, or/and update status percentage
|
427 |
+
* @param string $logMessage
|
428 |
+
* @param int $level (@see Zend_Log for more detail)
|
429 |
+
* @param int $statusPercent
|
430 |
+
*/
|
431 |
+
protected function _updateProcess($logMessage, $level = Zend_Log::INFO, $statusPercent = 0)
|
432 |
+
{
|
433 |
+
if ($this->getProcess()) {
|
434 |
+
$this->getProcess()->getLog()->log($logMessage, $level);
|
435 |
+
if ($statusPercent > 0) {
|
436 |
+
$this->getProcess()->updateStatus($statusPercent);
|
437 |
+
}
|
438 |
+
}
|
439 |
+
}
|
440 |
+
|
441 |
+
/**
|
442 |
+
* Update process for creating file step
|
443 |
*
|
444 |
+
* @param array $createdData
|
445 |
+
* - created_files : all file data will be stored in this array, each file will have the following information :
|
446 |
+
* - filename
|
447 |
+
* - path
|
448 |
+
* - time
|
449 |
+
* - writtent_subscriber_ids
|
450 |
+
*
|
451 |
+
* @param int $currentPercent - the current percentage
|
452 |
*/
|
453 |
+
protected function _updateProcessWhileCreatingFiles($createdData, $currentPercent)
|
454 |
{
|
455 |
+
$list = '';
|
456 |
+
if (count($createdData['created_files'])) {
|
457 |
+
$list = ' List of created files : ';
|
458 |
+
foreach ($createdData['created_files'] as $fileData) {
|
459 |
+
$list .= $fileData['filename'];
|
460 |
+
}
|
461 |
+
}
|
462 |
+
$this->_updateProcess(
|
463 |
+
count($createdData['created_files']) . ' csv files have been created.' . $list,
|
464 |
+
Zend_Log::INFO,
|
465 |
+
$currentPercent
|
466 |
+
);
|
467 |
+
if (count($createdData['errors'])) {
|
468 |
+
$error = "Process has encoutered the following errors when creating files : \n"
|
469 |
+
. implode("\n", $createdData['errors']);
|
470 |
+
$this->_updateProcess($error, Zend_Log::ERR);
|
471 |
}
|
|
|
472 |
}
|
473 |
|
474 |
/**
|
475 |
+
* Update process for uploading file step
|
476 |
+
*
|
477 |
+
* @param array $uploadInfo
|
478 |
+
* @param array $writtenSubscribers
|
479 |
*/
|
480 |
+
protected function _updateProcessWhileUploadingFiles($uploadInfo, $writtenSubscribers)
|
481 |
{
|
482 |
+
if (count($uploadInfo['uploaded_files'])) {
|
483 |
+
$uploadedFilesStatus = 'List of correctly uploaded files :';
|
484 |
+
foreach ($uploadInfo['uploaded_files'] as $fileData) {
|
485 |
+
$uploadedFilesStatus .= $fileData['file_data']['filename'];
|
486 |
+
if (
|
487 |
+
isset($writtenSubscribers[$fileData['file_data']['filename']])
|
488 |
+
) {
|
489 |
+
$uploadedFilesStatus .= '('
|
490 |
+
.count($writtenSubscribers[$fileData['file_data']['filename']]).' members)';
|
491 |
+
}
|
492 |
+
$uploadedFilesStatus .= ' ';
|
493 |
+
}
|
494 |
+
$this->_updateProcess($uploadedFilesStatus);
|
495 |
+
}
|
496 |
|
497 |
+
if (count($uploadInfo['invalid_files'])) {
|
498 |
+
$uploadedFilesStatus = 'List of invalid files :';
|
499 |
+
foreach ($uploadInfo['invalid_files'] as $fileData) {
|
500 |
+
$uploadedFilesStatus .= $fileData['file_data']['filename'];
|
501 |
+
if (
|
502 |
+
isset($writtenSubscribers[$fileData['file_data']['filename']])
|
503 |
+
) {
|
504 |
+
$uploadedFilesStatus .= '('
|
505 |
+
.count($writtenSubscribers[$fileData['file_data']['filename']]).')';
|
506 |
+
}
|
507 |
+
}
|
508 |
+
$this->_updateProcess($uploadedFilesStatus);
|
509 |
+
}
|
510 |
|
511 |
+
if (count($uploadInfo['errors'])) {
|
512 |
+
$error = "Process has encoutered the following errors when uploading files : \n"
|
513 |
+
. implode("\n", $uploadInfo['errors']);
|
514 |
+
$this->_updateProcess($error, Zend_Log::ERR);
|
515 |
+
}
|
516 |
+
}
|
517 |
|
518 |
+
/**
|
519 |
+
* Prepare output information (file name, lable, path) for the process
|
520 |
+
*
|
521 |
+
* @param reference to array $exportInfo
|
522 |
+
* @param array $uploadInfo
|
523 |
+
* @param array $createdFileInfo
|
524 |
+
*/
|
525 |
+
protected function _prepareOutputInfo(&$exportInfo, array $uploadInfo, array $createdFileInfo)
|
526 |
+
{
|
527 |
+
if (isset($createdFileInfo['created_files'])) {
|
528 |
+
foreach($createdFileInfo['created_files'] as $fileData) {
|
529 |
+
$exportInfo['treated_files'][$fileData['filename']] = array(
|
530 |
+
'path' => $fileData['path'],
|
531 |
+
'label' => $fileData['filename'],
|
532 |
+
'filename' => $fileData['filename']
|
533 |
+
);
|
534 |
+
}
|
535 |
+
}
|
536 |
+
|
537 |
+
if (isset($uploadInfo['uploaded_files'])) {
|
538 |
+
foreach ($uploadInfo['uploaded_files'] as $fileData) {
|
539 |
+
$fileName = $fileData['file_data']['filename'];
|
540 |
+
if (isset($exportInfo['treated_files'][$fileName])) {
|
541 |
+
$exportInfo['treated_files'][$fileName] = array(
|
542 |
+
'path' => $fileData['file_data']['path'],
|
543 |
+
'label' => $fileName . ' (correctly synced)',
|
544 |
+
'filename' => $fileName
|
545 |
+
);
|
546 |
|
547 |
+
if (
|
548 |
+
isset($createdFileInfo['writtent_subscriber_ids'])
|
549 |
+
&& isset($createdFileInfo['writtent_subscriber_ids'][$fileName])
|
550 |
+
) {
|
551 |
+
$exportInfo['uploaded_subscribers'] += count(
|
552 |
+
$createdFileInfo['writtent_subscriber_ids'][$fileName]
|
553 |
+
);
|
554 |
+
}
|
555 |
+
}
|
556 |
+
}
|
557 |
+
}
|
558 |
+
}
|
559 |
+
|
560 |
+
/**
|
561 |
+
* @param Varien_Data_Collection_Db $subscribers
|
562 |
+
* @param string $storeId
|
563 |
+
* @param EmailVision_Api_BatchMemberService $service
|
564 |
+
* @return array
|
565 |
+
* subscriber_data_list => list of subscriber data
|
566 |
+
* created_files => list of created files
|
567 |
+
* writtent_subscriber_ids => list of subscriber ids by created files
|
568 |
+
* errors => list of errors encountered during sync
|
569 |
+
*/
|
570 |
+
public function prepareCustomerCsvFiles($subscribers, $storeId, EmailVision_Api_BatchMemberService $service)
|
571 |
+
{
|
572 |
+
// list of return data
|
573 |
+
$arrayReturn = array(
|
574 |
+
'subscriber_data_list' => array(),
|
575 |
+
'created_files' => array(),
|
576 |
+
'writtent_subscriber_ids' => array(),
|
577 |
+
'errors' => array()
|
578 |
+
);
|
579 |
+
|
580 |
+
// Add a row foreach customer
|
581 |
+
$preparedData = array();
|
582 |
+
foreach ($subscribers as $subscriber) {
|
583 |
+
// Replace customer email by suscriber one
|
584 |
+
$subscriber->setData('email', $subscriber->getSubscriberEmail());
|
585 |
+
$subscriberData = Mage::getSingleton('emvdatasync/attributeProcessing_config')
|
586 |
+
->getSubscriberData($subscriber, $storeId);
|
587 |
+
|
588 |
+
$preparedData[] = array(
|
589 |
+
'id' => $subscriber->getId(),
|
590 |
+
'fields' => $subscriberData
|
591 |
+
);
|
592 |
+
|
593 |
+
// add subscriber data into array - this data will allow us to distinguish who rejoined recently
|
594 |
+
$tempSubscriber = array(
|
595 |
+
'id' => $subscriber->getId(),
|
596 |
+
'rejoined' => false
|
597 |
+
);
|
598 |
+
if ($subscriber->getData('subscriber_status') == Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED) {
|
599 |
+
if (
|
600 |
+
$subscriber->getData(Emv_DataSync_Helper_Service::FIELD_DATE_UNJOIN) != ''
|
601 |
+
&& $subscriber->getData(Emv_DataSync_Helper_Service::FIELD_DATE_UNJOIN) != null
|
602 |
+
) {
|
603 |
+
$tempSubscriber['rejoined'] = true;
|
604 |
+
}
|
605 |
+
}
|
606 |
+
|
607 |
+
$arrayReturn['subscriber_data_list'][$subscriber->getId()] = $tempSubscriber;
|
608 |
+
}// end foreach subscribers
|
609 |
+
|
610 |
+
// Mapped header array
|
611 |
+
$mappedHeaders = $this->prepareAndGetMappedHeaders($storeId);
|
612 |
try {
|
613 |
+
$csvFileData = $service->createCsvFiles(
|
614 |
+
$this,
|
615 |
+
array_keys($mappedHeaders),
|
616 |
+
$preparedData
|
617 |
+
);
|
618 |
+
|
619 |
+
// prepare array return from created file data
|
620 |
+
foreach ($csvFileData as $key => $data) {
|
621 |
+
// member list for each file
|
622 |
+
$arrayReturn['writtent_subscriber_ids'][$data['file']['filename']] = $data['list_member'];
|
623 |
+
$arrayReturn['created_files'][] = $data['file'];
|
624 |
+
}
|
625 |
+
} catch (Exception $e) {
|
626 |
+
Mage::logException($e);
|
627 |
+
|
628 |
+
$arrayReturn['errors'][] = 'Exception while building csv file, with message: ' . $e->getMessage();
|
629 |
+
}
|
630 |
+
|
631 |
+
return $arrayReturn;
|
632 |
+
}
|
633 |
|
634 |
+
/**
|
635 |
+
* @param array $filesToUpload
|
636 |
+
* @param unknown $storeId
|
637 |
+
* @param EmailVision_Api_BatchMemberService $service
|
638 |
+
* @param string $closeApi
|
639 |
+
* @return array
|
640 |
+
*/
|
641 |
+
public function sendFileAndGetStatusUpload(
|
642 |
+
array $filesToUpload = array(),
|
643 |
+
$storeId,
|
644 |
+
EmailVision_Api_BatchMemberService $service,
|
645 |
+
$closeApi = true
|
646 |
+
)
|
647 |
+
{
|
648 |
+
$arrayReturn = array(
|
649 |
+
'merge_criteria' => $this->getMergeCriteriaForBatchMember($storeId),
|
650 |
+
'uploaded_files' => array(),
|
651 |
+
'invalid_files' => array(),
|
652 |
+
'errors' => array()
|
653 |
+
);
|
654 |
+
|
655 |
+
// return
|
656 |
+
$uploadDone = true;
|
657 |
+
$mappedHeaders = $this->prepareAndGetMappedHeaders($storeId);
|
658 |
+
|
659 |
+
try {
|
660 |
+
foreach ($filesToUpload as $data) {
|
661 |
+
$uploadId = $service->sendFileToWebservice(
|
662 |
$data,
|
663 |
$mappedHeaders,
|
664 |
+
$arrayReturn['merge_criteria'],
|
665 |
false
|
666 |
);
|
667 |
|
668 |
+
$treatingFileArray = array('file_data' => $data, 'upload_id' => $uploadId, 'status' => false);
|
669 |
+
|
670 |
// only checking upload status if we can have upload id
|
671 |
+
if ($uploadId != false) {
|
672 |
$uploadProcessing = true;
|
673 |
+
|
674 |
// wait until SmartFocus platform completes processing uploaded file
|
675 |
// check status's upload for an interval self::WAITING_TIME
|
676 |
do {
|
677 |
sleep(self::WAITING_TIME);
|
678 |
// get status's upload
|
679 |
+
$uploadStatus = $service->getUploadStatus($uploadId, false);
|
680 |
|
681 |
if (
|
682 |
in_array(
|
684 |
EmailVision_Api_BatchMemberService::getAccomplishedStatuses()
|
685 |
)
|
686 |
) {
|
687 |
+
// update uploading status
|
688 |
+
$treatingFileArray['status'] = $uploadStatus['status'];
|
689 |
+
|
690 |
$uploadProcessing = false;
|
691 |
if (
|
692 |
$uploadStatus['status'] == EmailVision_Api_BatchMemberService::getStatusOkWithoutError()
|
693 |
) {
|
694 |
+
$arrayReturn['uploaded_files'][] = $treatingFileArray;
|
695 |
} else {
|
696 |
+
$arrayReturn['invalid_files'][] = $treatingFileArray;
|
697 |
+
|
698 |
+
$messageError = 'Error on while uploading file ' . $data['filename'];
|
699 |
+
if ($uploadStatus['details']) {
|
700 |
+
$messageError .= ", details returned from SmartFocus: " . $uploadStatus['details'];
|
701 |
+
}
|
702 |
+
$arrayReturn['errors'][] = $messageError;
|
703 |
}
|
704 |
}
|
705 |
} while ($uploadProcessing);
|
706 |
+
} else {
|
707 |
+
$arrayReturn['invalid_files'][] = $treatingFileArray;
|
|
|
708 |
}
|
709 |
}
|
710 |
+
|
711 |
+
if ($closeApi == true) {
|
712 |
+
$service->closeApiConnection();
|
713 |
+
}
|
714 |
} catch (Exception $e) {
|
|
|
715 |
Mage::logException($e);
|
716 |
|
717 |
+
$arrayReturn['errors'][] = "Exception during file uploading process, with message: "
|
718 |
. $e->getMessage();
|
719 |
}
|
720 |
|
721 |
+
return $arrayReturn;
|
722 |
+
}
|
723 |
|
724 |
+
/**
|
725 |
+
* Move the synced files to new placement, update their paths in the array respectively
|
726 |
+
*
|
727 |
+
* @param array $proceededFiles
|
728 |
+
*/
|
729 |
+
public function treatProceededFiles(array &$proceededFiles)
|
730 |
+
{
|
731 |
+
if (isset($proceededFiles['uploaded_files'])) {
|
732 |
+
foreach ($proceededFiles['uploaded_files'] as $key => $fileData) {
|
733 |
+
if (isset($fileData['file_data']['filename']) && $fileData['file_data']['path']) {
|
734 |
+
$newPath = Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
735 |
+
. DS . Emv_Core_Helper_Data::BASE_WORKING_DIR
|
736 |
+
. DS . Emv_Core_Helper_Data::UPLOADED_FILE_DIR
|
737 |
+
. DS . $fileData['file_data']['filename'];
|
738 |
+
|
739 |
+
if (@rename($fileData['file_data']['path'],$newPath)) {
|
740 |
+
$proceededFiles['uploaded_files'][$key]['file_data']['path'] = $newPath;
|
741 |
+
}
|
742 |
+
}
|
743 |
}
|
744 |
}
|
745 |
+
}
|
746 |
|
747 |
+
/**
|
748 |
+
* Get merge criteria for batch member api requests
|
749 |
+
* @param int $storeId
|
750 |
+
* @return array
|
751 |
+
*/
|
752 |
+
public function getMergeCriteriaForBatchMember($storeId = null)
|
753 |
+
{
|
754 |
+
if (Mage::helper('emvdatasync')->getEmailEnabled($storeId)) {
|
755 |
+
$mergeCriteria = array(strtoupper(Emv_Core_Model_Service_Member::FIELD_EMAIL));
|
756 |
+
} else {
|
757 |
+
$mergeCriteria = array(strtoupper(Mage::helper('emvdatasync')->getMappedEntityId($storeId)));
|
758 |
+
}
|
759 |
+
return $mergeCriteria;
|
760 |
}
|
761 |
|
762 |
/**
|
779 |
}
|
780 |
|
781 |
// Preparing filename
|
782 |
+
$filename = $this->_exportFilePrefix . 'customers' . $this->_currentTime . '_part' . $index . '.csv';
|
783 |
|
784 |
// Preparing file path
|
785 |
+
$path = Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
786 |
+
. DS . Emv_Core_Helper_Data::BASE_WORKING_DIR . DS . $filename;;
|
787 |
return array('filename' => $filename, 'path' => $path, 'time' => $this->_currentTime);
|
788 |
}
|
789 |
|
790 |
/**
|
791 |
+
* Get treated subscribers (synced and rejoined)
|
792 |
+
* @param array $uploadedFileNames
|
793 |
+
* @param array $listSubscriberByFiles
|
794 |
+
* @param array $subscriberData
|
795 |
+
* @return array
|
796 |
+
* - treated_subscribers : the total number of synced subscribers
|
797 |
+
* - rejoined_subscribers : the list of rejoined subscribers among the synced ones
|
798 |
*/
|
799 |
+
public function getTreatedSubscribers(array $uploadedFileNames, array $listSubscriberByFiles, array $subscriberData)
|
800 |
{
|
801 |
+
$arrayReturn = array(
|
802 |
+
'treated_subscribers' => array(),
|
803 |
+
'rejoined_subscribers' => array()
|
804 |
+
);
|
805 |
// Cases: mass export will have a _fileNamesUploaded set, member export will have _subsciberIds
|
806 |
+
if (!empty($uploadedFileNames) && count($uploadedFileNames)) {
|
807 |
+
foreach ($uploadedFileNames as $fileData) {
|
808 |
+
if (isset($fileData['file_data']) && isset($fileData['file_data']['filename'])) {
|
809 |
+
$fileName = $fileData['file_data']['filename'];
|
810 |
+
if (isset($listSubscriberByFiles[$fileName])) {
|
811 |
+
foreach ($listSubscriberByFiles[$fileName] as $subscriberId) {
|
812 |
+
$arrayReturn['treated_subscribers'][] = $subscriberId;
|
813 |
+
if (
|
814 |
+
isset($subscriberData[$subscriberId])
|
815 |
+
&& $subscriberData[$subscriberId]['rejoined'] == true
|
816 |
+
) {
|
817 |
+
$arrayReturn['rejoined_subscribers'][] = $subscriberId;
|
818 |
+
}
|
819 |
}
|
|
|
820 |
}
|
821 |
}
|
822 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
823 |
}
|
824 |
+
|
825 |
+
return $arrayReturn;
|
826 |
}
|
827 |
|
828 |
/**
|
829 |
+
* Set member last update date for all exported subscribers
|
830 |
+
*
|
831 |
+
* @param array $uploadedFileNames
|
832 |
+
* @param array $listSubscriberByFiles
|
833 |
+
* @param array $subscriberData
|
834 |
+
* @return array error
|
835 |
*/
|
836 |
+
public function massSetMemberLastUpdateDate(array $subscribersIds, array $rejoinedIds)
|
837 |
{
|
838 |
+
$errors = array();
|
839 |
+
try {
|
840 |
+
$errorMessage = Mage::helper('emvdatasync/service')->massSetMemberLastUpdateDate(
|
841 |
+
$subscribersIds,
|
842 |
+
$rejoinedIds
|
843 |
+
);
|
844 |
+
|
845 |
+
if ($errorMessage !== true) {
|
846 |
+
$errors[] = $errorMessage;
|
847 |
+
}
|
848 |
+
} catch (Exception $e) {
|
849 |
+
Mage::logException($e);
|
850 |
+
}
|
851 |
+
|
852 |
+
return $errors;
|
853 |
}
|
854 |
|
855 |
/**
|
856 |
+
* @param array $memberIds
|
857 |
+
* @param array $storeIds
|
858 |
+
* @return Mage_Newsletter_Model_Mysql4_Subscriber_Collection
|
859 |
*/
|
860 |
+
public function getSubscriberCollection(array $memberIds = array(), array $storeIds = array())
|
861 |
{
|
862 |
+
/* @var $subscribers Mage_Newsletter_Model_Mysql4_Subscriber_Collection */
|
|
|
863 |
$subscribers = Mage::getModel('newsletter/subscriber')->getCollection();
|
864 |
+
if (count($memberIds)) {
|
865 |
+
$subscribers->addFieldToFilter('subscriber_id', array('in' => $memberIds));
|
866 |
+
} else {
|
867 |
+
// only get subscirbers that have been scheduled
|
868 |
+
$subscribers->addFieldToFilter(
|
869 |
+
'main_table.' . Emv_DataSync_Helper_Service::FIELD_QUEUED,
|
870 |
+
Emv_DataSync_Helper_Service::SCHEDULED_VALUE
|
871 |
+
);
|
872 |
+
}
|
873 |
|
874 |
+
if (count($storeIds)) {
|
875 |
+
$subscribers->addFieldToFilter('main_table.store_id', array('in' => $storeIds));
|
876 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
877 |
|
878 |
return $subscribers;
|
879 |
}
|
880 |
|
881 |
/**
|
882 |
+
* Prepare and get mapped header array
|
883 |
+
*
|
884 |
+
* @param int $storeId
|
885 |
* @return array
|
886 |
*/
|
887 |
+
public function prepareAndGetMappedHeaders($storeId = null)
|
888 |
{
|
889 |
+
// by default the key will be store id, else will be set to undefined
|
890 |
+
$key = $storeId;
|
891 |
+
if ($key === null) {
|
892 |
+
$key = 'undefined';
|
893 |
+
}
|
894 |
+
|
895 |
+
if (!isset($this->_mappedHeaders[$key])) {
|
896 |
+
$this->_mappedHeaders[$key] = array();
|
897 |
|
898 |
// retreive all maped attribute values from subscriber, build them into array
|
899 |
+
$entityFieldsToSelect = Mage::getSingleton('emvdatasync/attributeProcessing_config')
|
900 |
+
->prepareAndGetMappedCustomerAttributes($storeId);
|
901 |
foreach ($entityFieldsToSelect as $attribute) {
|
902 |
+
$emailVisionKey = $attribute->getMappedEmailVisionKey();
|
903 |
$emailVisionKey = strtoupper($emailVisionKey);
|
904 |
|
905 |
+
$this->_mappedHeaders[$key][strtoupper($emailVisionKey)] = array(
|
906 |
'to_replace' => true
|
907 |
);
|
908 |
}
|
909 |
|
910 |
// the entity id can not be replaced
|
911 |
$entityIdField = Mage::helper('emvdatasync')->getMappedEntityId();
|
912 |
+
$this->_mappedHeaders[$key][strtoupper($entityIdField)] = array(
|
913 |
'to_replace' => false
|
914 |
);
|
915 |
|
916 |
+
$this->_mappedHeaders[$key][strtoupper(Emv_Core_Model_Service_Member::FIELD_UNJOIN)] = array(
|
917 |
'to_replace' => true
|
918 |
);
|
919 |
}
|
920 |
|
921 |
+
return $this->_mappedHeaders[$key];
|
922 |
}
|
923 |
|
924 |
/**
|
@@ -0,0 +1,360 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Data process service
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
+
*/
|
10 |
+
class Emv_DataSync_Model_Service_DataProcess
|
11 |
+
{
|
12 |
+
const XML_PATH_ENABLED_PURCHASE_INFO = 'emvdatasync/purchase_info/enabled';
|
13 |
+
const XML_PATH_LIMIT_TABLE_SIZE = 'emvdatasync/purchase_info/limit_size';
|
14 |
+
const LIMIT_PAGE_SIZE = 50000;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Chunk size (the limit number of customers to handle
|
18 |
+
* @var int
|
19 |
+
*/
|
20 |
+
public static $chunkSize = 2000;
|
21 |
+
|
22 |
+
/**
|
23 |
+
* List of fields to insert
|
24 |
+
* @var array
|
25 |
+
*/
|
26 |
+
protected $_fieldsForInsert = array(
|
27 |
+
'email' ,
|
28 |
+
'customer_id' ,
|
29 |
+
'order_list' ,
|
30 |
+
|
31 |
+
'created_at' ,
|
32 |
+
'updated_at' ,
|
33 |
+
|
34 |
+
'base_currency_code' ,
|
35 |
+
|
36 |
+
'total_order' ,
|
37 |
+
|
38 |
+
'total_ordered_item_qty' ,
|
39 |
+
'avg_item_qty' ,
|
40 |
+
'order_amount_total' ,
|
41 |
+
'avg_order_amount_total' ,
|
42 |
+
'discount_amount_total' ,
|
43 |
+
'avg_discount_amount_total' ,
|
44 |
+
'shipping_amount_total' ,
|
45 |
+
'avg_shipping_amount_total' ,
|
46 |
+
|
47 |
+
'min_order_amount_total' ,
|
48 |
+
'max_order_amount_total' ,
|
49 |
+
'first_order_date' ,
|
50 |
+
'last_order_date' ,
|
51 |
+
'min_total_ordered_item_qty' ,
|
52 |
+
'max_total_ordered_item_qty' ,
|
53 |
+
|
54 |
+
'shipping_list' ,
|
55 |
+
'payment_methods' ,
|
56 |
+
'coupon_list' ,
|
57 |
+
'nb_order_having_discount'
|
58 |
+
);
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Is the purchase information process enabled ?
|
62 |
+
*
|
63 |
+
* @return boolean
|
64 |
+
*/
|
65 |
+
public function enabledPurchaseInformation($storeId = null)
|
66 |
+
{
|
67 |
+
return Mage::getStoreConfig(self::XML_PATH_ENABLED_PURCHASE_INFO, $storeId);
|
68 |
+
}
|
69 |
+
|
70 |
+
/**
|
71 |
+
* Get limit of purchase information records to be stored inside the table
|
72 |
+
*
|
73 |
+
* @return int
|
74 |
+
*/
|
75 |
+
public function getLimitPurchaseInformationTableSize()
|
76 |
+
{
|
77 |
+
return Mage::getStoreConfig(self::XML_PATH_LIMIT_TABLE_SIZE);
|
78 |
+
}
|
79 |
+
|
80 |
+
/**
|
81 |
+
* Get the customer id list that have correct purchase information
|
82 |
+
*
|
83 |
+
* @param string $list - indicates if we should return the list
|
84 |
+
* @param string $count - indicates if we should return the total number
|
85 |
+
* @return array
|
86 |
+
*/
|
87 |
+
public function getOkPurchaseInfoCustomerIdList($list = true, $count = false)
|
88 |
+
{
|
89 |
+
$resource = Mage::getModel('core/resource');
|
90 |
+
$readConnection = $resource->getConnection(Mage_Core_Model_Resource::DEFAULT_READ_RESOURCE);
|
91 |
+
|
92 |
+
$queuedField = Emv_DataSync_Helper_Service::FIELD_QUEUED;
|
93 |
+
$select = $readConnection->select();
|
94 |
+
$select
|
95 |
+
->from(array('main_table' => $resource->getTableName('emvdatasync/purchase_info')), array())
|
96 |
+
->join(
|
97 |
+
array('newsletter' => $resource->getTableName('newsletter/subscriber')),
|
98 |
+
'main_table.customer_id = newsletter.customer_id
|
99 |
+
AND newsletter.date_last_purchase < main_table.updated_at',
|
100 |
+
array()
|
101 |
+
)
|
102 |
+
-> where("$queuedField = ?", Emv_DataSync_Helper_Service::SCHEDULED_VALUE);
|
103 |
+
|
104 |
+
if ($list) {
|
105 |
+
$select->columns(array('main_table.customer_id'));
|
106 |
+
}
|
107 |
+
if ($count) {
|
108 |
+
$select->columns('COUNT(*)');
|
109 |
+
}
|
110 |
+
|
111 |
+
return $readConnection->fetchCol($select);
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* @return array
|
116 |
+
*/
|
117 |
+
public function numberOfRecordsInPurchaseInfoTable()
|
118 |
+
{
|
119 |
+
$resource = Mage::getModel('core/resource');
|
120 |
+
$readConnection = $resource->getConnection(Mage_Core_Model_Resource::DEFAULT_READ_RESOURCE);
|
121 |
+
|
122 |
+
$select = $readConnection->select();
|
123 |
+
$select->from(array('main_table' => $resource->getTableName('emvdatasync/purchase_info')), array('COUNT(*)'));
|
124 |
+
|
125 |
+
return $readConnection->fetchCol($select);
|
126 |
+
}
|
127 |
+
|
128 |
+
/**
|
129 |
+
* Remove useless purchase information
|
130 |
+
* - The subscribers that haven't been scheduled
|
131 |
+
* - The purchase date is outdated
|
132 |
+
*
|
133 |
+
* @return int - the number of rows which have been removed
|
134 |
+
*/
|
135 |
+
public function removeUselessPurchaseInfo()
|
136 |
+
{
|
137 |
+
$resource = Mage::getModel('core/resource');
|
138 |
+
$writeConnection = $resource->getConnection(Mage_Core_Model_Resource::DEFAULT_WRITE_RESOURCE);
|
139 |
+
|
140 |
+
$select = $writeConnection->select();
|
141 |
+
$select
|
142 |
+
->from(array('purchase' => $resource->getTableName('emvdatasync/purchase_info')), array())
|
143 |
+
->joinLeft(
|
144 |
+
array('subscriber' => $resource->getTableName('newsletter/subscriber')),
|
145 |
+
'purchase.customer_id = subscriber.customer_id',
|
146 |
+
array()
|
147 |
+
)
|
148 |
+
->where(
|
149 |
+
'subscriber.subscriber_id IS NULL OR subscriber.queued = ?
|
150 |
+
OR subscriber.date_last_purchase > purchase.updated_at',
|
151 |
+
Emv_DataSync_Helper_Service::NOT_SCHEDULED_VALUE
|
152 |
+
)
|
153 |
+
;
|
154 |
+
$select->reset(Zend_Db_Select::DISTINCT);
|
155 |
+
$select->reset(Zend_Db_Select::COLUMNS);
|
156 |
+
$deleteQuery = sprintf('DELETE purchase %s', $select->assemble());
|
157 |
+
|
158 |
+
$stmt = $writeConnection->query($deleteQuery);
|
159 |
+
$result = $stmt->rowCount();
|
160 |
+
return $result;
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Get list of customers to proceed.
|
165 |
+
* If $count is given and equal to true => only return the total number of concerning customers
|
166 |
+
* else we return the list of customers
|
167 |
+
*
|
168 |
+
* @param string $count
|
169 |
+
* @param int $page (the page to retrieve)
|
170 |
+
* @param int $pageSize (the page size)
|
171 |
+
* @return array
|
172 |
+
*/
|
173 |
+
public function getListCustomerToProceed($count = false, $page = 1, $pageSize = self::LIMIT_PAGE_SIZE)
|
174 |
+
{
|
175 |
+
$queuedField = Emv_DataSync_Helper_Service::FIELD_QUEUED;
|
176 |
+
|
177 |
+
$resource = Mage::getModel('core/resource');
|
178 |
+
$readConnection = $resource->getConnection(Mage_Core_Model_Resource::DEFAULT_READ_RESOURCE);
|
179 |
+
|
180 |
+
$select = $readConnection->select();
|
181 |
+
$select->from(
|
182 |
+
array('main_table' => $resource->getTableName('newsletter/subscriber')),
|
183 |
+
array()
|
184 |
+
)
|
185 |
+
->joinLeft(
|
186 |
+
array('purchase' => $resource->getTableName('emvdatasync/purchase_info')),
|
187 |
+
'purchase.customer_id = main_table.customer_id',
|
188 |
+
array()
|
189 |
+
)
|
190 |
+
->where('main_table.customer_id > 0')
|
191 |
+
->where("$queuedField = ?", Emv_DataSync_Helper_Service::SCHEDULED_VALUE)
|
192 |
+
->where('main_table.date_last_purchase IS NOT NULL')
|
193 |
+
// when member does not have calculated purchase information or, this information is outdated
|
194 |
+
->where('purchase.id IS NULL OR purchase.updated_at < main_table.date_last_purchase')
|
195 |
+
;
|
196 |
+
|
197 |
+
if ($count) {
|
198 |
+
$select->columns('COUNT(*)');
|
199 |
+
} else {
|
200 |
+
$select->columns('customer_id');
|
201 |
+
$select->limitPage($page, $pageSize);
|
202 |
+
}
|
203 |
+
|
204 |
+
return $readConnection->fetchCol($select);
|
205 |
+
}
|
206 |
+
|
207 |
+
/**
|
208 |
+
* Prepare and return the select to calculate purchase information
|
209 |
+
* (for now, we only accept the calculation for 1 global currency code)
|
210 |
+
*
|
211 |
+
* @param array $customerList
|
212 |
+
* @return Zend_Db_Select|boolean
|
213 |
+
*/
|
214 |
+
public function getSelectToCalculatePurchaseInformation($customerList = array())
|
215 |
+
{
|
216 |
+
if (is_array($customerList) && count($customerList)) {
|
217 |
+
$resource = Mage::getModel('core/resource');
|
218 |
+
$readConnection = $resource->getConnection(Mage_Core_Model_Resource::DEFAULT_READ_RESOURCE);
|
219 |
+
$select = $readConnection->select();
|
220 |
+
|
221 |
+
$gmtDate = Mage::getModel('core/date')->gmtDate();
|
222 |
+
$select->from(
|
223 |
+
array('flat_order' => $resource->getTableName('sales/order')),
|
224 |
+
array(
|
225 |
+
'email' => "GROUP_CONCAT( DISTINCT flat_order.customer_email SEPARATOR '|' )",
|
226 |
+
'customer_id' => 'flat_order.customer_id',
|
227 |
+
'order_list' => "GROUP_CONCAT( DISTINCT flat_order.increment_id SEPARATOR '|' )",
|
228 |
+
|
229 |
+
new Zend_Db_Expr('"' . $gmtDate . '" as created_at'),
|
230 |
+
new Zend_Db_Expr('"' . $gmtDate . '" as updated_at'),
|
231 |
+
|
232 |
+
'base_currency_code' => "GROUP_CONCAT( DISTINCT flat_order.base_currency_code SEPARATOR '|' )",
|
233 |
+
|
234 |
+
'total_order' => 'COUNT(flat_order.entity_id)',
|
235 |
+
|
236 |
+
'total_ordered_item_qty' => 'SUM(flat_order.total_item_count)',
|
237 |
+
'avg_item_qty' => 'AVG(flat_order.total_item_count)',
|
238 |
+
'order_amount_total' => 'SUM(flat_order.base_grand_total)',
|
239 |
+
'avg_order_amount_total' => 'AVG(flat_order.base_grand_total)',
|
240 |
+
'discount_amount_total' => 'ABS(SUM(flat_order.base_discount_amount))',
|
241 |
+
'avg_discount_amount_total' => 'ABS(AVG(flat_order.base_discount_amount))',
|
242 |
+
'shipping_amount_total' => 'SUM(flat_order.base_shipping_amount)',
|
243 |
+
'avg_shipping_amount_total' => 'AVG(flat_order.base_shipping_amount)',
|
244 |
+
|
245 |
+
'min_order_amount_total' => 'MIN(flat_order.base_grand_total)',
|
246 |
+
'max_order_amount_total' => 'MAX(flat_order.base_grand_total)',
|
247 |
+
'first_order_date' => 'MIN(flat_order.created_at)',
|
248 |
+
'last_order_date' => 'MAX(flat_order.created_at)',
|
249 |
+
'min_total_ordered_item_qty' => 'MIN(flat_order.total_item_count)',
|
250 |
+
'max_total_ordered_item_qty' => 'MAX(flat_order.total_item_count)',
|
251 |
+
|
252 |
+
'shipping_list' => "GROUP_CONCAT( DISTINCT flat_order.shipping_description SEPARATOR '|' )",
|
253 |
+
'payment_methods' => "GROUP_CONCAT( DISTINCT payment.method SEPARATOR '|' )",
|
254 |
+
'coupon_list' => "GROUP_CONCAT( DISTINCT flat_order.coupon_code SEPARATOR '|' )",
|
255 |
+
'nb_order_having_discount' => 'COUNT(coupon_code)'
|
256 |
+
)
|
257 |
+
)
|
258 |
+
->join(
|
259 |
+
array('subscriber' => $resource->getTableName('newsletter/subscriber')),
|
260 |
+
'subscriber.customer_id = flat_order.customer_id',
|
261 |
+
array()
|
262 |
+
) // only prepare data for subscriber
|
263 |
+
->join(
|
264 |
+
array('payment' => $resource->getTableName('sales/order_payment')),
|
265 |
+
'payment.parent_id = flat_order.entity_id',
|
266 |
+
array()
|
267 |
+
) // get used payment methods
|
268 |
+
->group(array('flat_order.customer_id'))
|
269 |
+
->where('flat_order.customer_id IN (?)', $customerList);
|
270 |
+
;
|
271 |
+
|
272 |
+
return $select;
|
273 |
+
}
|
274 |
+
|
275 |
+
return false;
|
276 |
+
}
|
277 |
+
|
278 |
+
/**
|
279 |
+
* Proceed purchase information for a given customer list
|
280 |
+
*
|
281 |
+
* @param array $customerList
|
282 |
+
*/
|
283 |
+
public function proceedPurchaseInfoForList($customerList = array())
|
284 |
+
{
|
285 |
+
$resource = Mage::getModel('core/resource');
|
286 |
+
$writeConnection = $resource->getConnection(Mage_Core_Model_Resource::DEFAULT_WRITE_RESOURCE);
|
287 |
+
|
288 |
+
// split email list into small chunk to easily handle
|
289 |
+
$chunkList = array_chunk($customerList, self::$chunkSize);
|
290 |
+
|
291 |
+
foreach ($chunkList as $list) {
|
292 |
+
$select = $this->getSelectToCalculatePurchaseInformation($list);
|
293 |
+
if ($select) {
|
294 |
+
$insert = sprintf(
|
295 |
+
"INSERT INTO `%s` (%s) %s",
|
296 |
+
$resource->getTableName('emvdatasync/purchase_info'),
|
297 |
+
implode(', ', $this->_fieldsForInsert),
|
298 |
+
$select->assemble()
|
299 |
+
);
|
300 |
+
$writeConnection->query($insert);
|
301 |
+
}
|
302 |
+
}
|
303 |
+
}
|
304 |
+
|
305 |
+
/**
|
306 |
+
* Start the whole process to proceed purchase information
|
307 |
+
*/
|
308 |
+
public function prepareList()
|
309 |
+
{
|
310 |
+
$errorList = array();
|
311 |
+
if ($this->enabledPurchaseInformation()) {
|
312 |
+
try {
|
313 |
+
// the number of clients will be proceeded
|
314 |
+
$nbToTreat = $this->getListCustomerToProceed(true);
|
315 |
+
if (is_array($nbToTreat) && count($nbToTreat) && $nbToTreat[0] > 0) {
|
316 |
+
$limit = $this->getLimitPurchaseInformationTableSize();
|
317 |
+
|
318 |
+
// the number of left records to treat
|
319 |
+
$nbRest = 0;
|
320 |
+
|
321 |
+
// clean useless information
|
322 |
+
$this->removeUselessPurchaseInfo();
|
323 |
+
// the number of existing records
|
324 |
+
$nbExisting = $this->numberOfRecordsInPurchaseInfoTable();
|
325 |
+
|
326 |
+
if (is_array($nbExisting) && count($nbExisting)) {
|
327 |
+
if ($nbExisting[0] + $nbToTreat[0] <= $limit) {
|
328 |
+
$nbRest = $nbToTreat[0];
|
329 |
+
} else {
|
330 |
+
if ($limit > $nbExisting[0]) {
|
331 |
+
$nbRest = $limit - $nbExisting[0];
|
332 |
+
}
|
333 |
+
}
|
334 |
+
}
|
335 |
+
|
336 |
+
$nbPages = ceil($nbRest/self::LIMIT_PAGE_SIZE);
|
337 |
+
$nbTaken = 0;
|
338 |
+
for ($curPage = 1; $curPage <= $nbPages; $curPage++) {
|
339 |
+
// always take the first page
|
340 |
+
$customerList = $this->getListCustomerToProceed(false, 0, self::LIMIT_PAGE_SIZE);
|
341 |
+
|
342 |
+
$nbToTake = $nbRest - $nbTaken;
|
343 |
+
if ($nbToTake < self::LIMIT_PAGE_SIZE) {
|
344 |
+
$this->proceedPurchaseInfoForList(array_slice($customerList, 0, $nbToTake));
|
345 |
+
$nbTaken += $nbToTake;
|
346 |
+
} else {
|
347 |
+
$this->proceedPurchaseInfoForList($customerList);
|
348 |
+
$nbTaken += self::LIMIT_PAGE_SIZE;
|
349 |
+
}
|
350 |
+
}
|
351 |
+
}
|
352 |
+
} catch (Exception $e) {
|
353 |
+
Mage::logException($e);
|
354 |
+
$errorList[] = $e->getMessage();
|
355 |
+
}
|
356 |
+
}
|
357 |
+
|
358 |
+
return $errorList;
|
359 |
+
}
|
360 |
+
}
|
@@ -3,46 +3,53 @@
|
|
3 |
* Member service - Handle Member Data
|
4 |
*
|
5 |
* @category Emv
|
6 |
-
* @package
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
*/
|
10 |
class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
11 |
{
|
12 |
-
protected $_subscribersIdsUpdated = array();
|
13 |
-
protected $_subscribersIdsUnjoined = array();
|
14 |
-
protected $_subscribersIdsRejoined = array();
|
15 |
-
|
16 |
protected $_errors = array();
|
17 |
|
18 |
/**
|
19 |
* This method will get subscribers that require data update to EmailVision platform
|
20 |
* and manage the api calls in order to insert or update the data
|
21 |
*
|
22 |
-
* @
|
|
|
|
|
|
|
|
|
23 |
*/
|
24 |
-
public function exportSubscribers()
|
25 |
{
|
26 |
$size = false;
|
|
|
27 |
try {
|
28 |
// Subscribers that never have been sync || that have been update more recently than their last sync
|
29 |
$subscribers = Mage::getModel('newsletter/subscriber')->getCollection()
|
30 |
-
->addFieldToFilter('main_table.' . Emv_DataSync_Helper_Service::FIELD_MEMBER_LAST_UPDATE,
|
31 |
-
array(
|
32 |
-
array('null'=> true),
|
33 |
-
array('lt'=> new Zend_Db_Expr('main_table.' . Emv_DataSync_Helper_Service::FIELD_DATA_LAST_UPDATE))
|
34 |
-
)
|
35 |
-
)
|
36 |
->addFieldToFilter(
|
37 |
'main_table.subscriber_status',
|
38 |
array(
|
39 |
array('eq' => Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED)
|
40 |
)
|
41 |
);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
$size = $subscribers->getSize();
|
43 |
if ($size) {
|
44 |
// Add all customer and address attributes that have been mapped into collection
|
45 |
-
Mage::
|
|
|
46 |
}
|
47 |
} catch (Exception $e) {
|
48 |
Mage::logException($e);
|
@@ -52,7 +59,10 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
52 |
if ($size) {
|
53 |
foreach ($subscribers as $subscriber) {
|
54 |
try {
|
55 |
-
$this->_insertOrUpdateMember($subscriber);
|
|
|
|
|
|
|
56 |
} catch (Exception $e) {
|
57 |
Mage::logException($e);
|
58 |
|
@@ -62,7 +72,7 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
62 |
}
|
63 |
}
|
64 |
|
65 |
-
return $
|
66 |
}
|
67 |
|
68 |
/**
|
@@ -72,19 +82,18 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
72 |
* @param Mage_Newsletter_Model_Subscriber $subscriber
|
73 |
* @return array
|
74 |
*/
|
75 |
-
public function getMergeCriteriaForMember(Mage_Newsletter_Model_Subscriber $subscriber)
|
76 |
{
|
77 |
-
if (Mage::helper('emvdatasync')->getEmailEnabled()) {
|
78 |
$mergeCriteria = array(strtoupper(Emv_Core_Model_Service_Member::FIELD_EMAIL) => $subscriber->getEmail());
|
79 |
} else {
|
80 |
$mergeCriteria = array(
|
81 |
-
strtoupper(Mage::helper('emvdatasync')->getMappedEntityId()) => $subscriber->getId()
|
82 |
);
|
83 |
}
|
84 |
return $mergeCriteria;
|
85 |
}
|
86 |
|
87 |
-
|
88 |
/**
|
89 |
* Method to call insert or update on subscriber passed as param
|
90 |
*
|
@@ -93,60 +102,27 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
93 |
*
|
94 |
* @return string | boolean $result The soap call result
|
95 |
*/
|
96 |
-
protected function _insertOrUpdateMember(
|
|
|
|
|
|
|
|
|
|
|
97 |
{
|
98 |
-
$params = array();
|
99 |
-
|
100 |
// Replace customer email by suscriber one
|
101 |
$subscriber->setData('email', $subscriber->getSubscriberEmail());
|
102 |
|
103 |
-
|
104 |
-
|
105 |
-
if ($entityFieldsToSelect && $entityFieldsToSelect->count() > 0) {
|
106 |
-
// get list of all available stores
|
107 |
-
$stores = Mage::app()->getStores(true);
|
108 |
-
|
109 |
-
foreach($entityFieldsToSelect as $attribute) {
|
110 |
-
$emailVisionKey = $attribute->getEmailVisionKey();
|
111 |
-
$emailVisionKey = strtoupper($emailVisionKey);
|
112 |
-
|
113 |
-
$fieldCode = ($attribute->getFinalAttributeCode())
|
114 |
-
? $attribute->getFinalAttributeCode() : $attribute->getAttributeCode();
|
115 |
-
|
116 |
-
$fieldValue = '';
|
117 |
-
|
118 |
-
if ($attribute->getFrontendInput() == 'date') {
|
119 |
-
if ($subscriber->getData($fieldCode)) {
|
120 |
-
// date time should be in EmailVision format
|
121 |
-
$fieldValue = Mage::helper('emvdatasync/service')
|
122 |
-
->getEmailVisionDate($subscriber->getData($fieldCode));
|
123 |
-
}
|
124 |
-
} else {
|
125 |
-
$fieldValue = $subscriber->getData($fieldCode);
|
126 |
-
if ($fieldCode == 'store_id' && isset($stores[$fieldValue])) {
|
127 |
-
// get store code
|
128 |
-
$fieldValue = $stores[$fieldValue]->getCode();
|
129 |
-
}
|
130 |
-
}
|
131 |
-
|
132 |
-
$params[$emailVisionKey] = $fieldValue;
|
133 |
-
}
|
134 |
-
|
135 |
-
// entity id
|
136 |
-
$params[strtoupper(Mage::helper('emvdatasync')->getMappedEntityId())] = $subscriber->getId();
|
137 |
-
}
|
138 |
|
139 |
// make api call with all prepared array (mapped attributes and criteria)
|
140 |
try {
|
141 |
$uploadId = null;
|
142 |
-
$service = $this->getApiService($this->getAccount());
|
143 |
$uploadId = $service->insertOrUpdateMemberByObj(
|
144 |
-
$this->getMergeCriteriaForMember($subscriber),
|
145 |
$params,
|
146 |
$closeApi
|
147 |
);
|
148 |
-
|
149 |
-
$this->_subscribersIdsUpdated[] = $subscriber->getId();
|
150 |
} catch (Exception $e) {
|
151 |
Mage::logException($e);
|
152 |
|
@@ -158,29 +134,39 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
158 |
}
|
159 |
|
160 |
/**
|
161 |
-
* Unjoin all unsubscribed members from
|
162 |
*
|
|
|
|
|
|
|
163 |
* @param boolean $closeApi
|
164 |
-
* @return Array
|
165 |
*/
|
166 |
-
public function unjoinSubscribers(
|
|
|
|
|
|
|
167 |
{
|
|
|
168 |
try {
|
169 |
// Subscribers that have unjoined more recently than their last sync
|
170 |
$subscribers = Mage::getModel('newsletter/subscriber')->getCollection()
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
)
|
182 |
);
|
183 |
-
|
|
|
|
|
|
|
|
|
184 |
} catch (Exception $e) {
|
185 |
Mage::logException($e);
|
186 |
$this->_errors[] = 'Exception while retreiving data for subscribers to unjoin with message: ' . $e->getMessage();
|
@@ -188,9 +174,9 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
188 |
|
189 |
foreach ($subscribers as $subscriber) {
|
190 |
try {
|
191 |
-
$this->unjoinOneSubscriber($subscriber, false);
|
192 |
|
193 |
-
$
|
194 |
} catch (Exception $e) {
|
195 |
Mage::logException($e);
|
196 |
$this->_errors[] = 'Exception while preparing data to call unjoin, for subscriber '
|
@@ -198,21 +184,26 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
198 |
}
|
199 |
}
|
200 |
|
201 |
-
return $
|
202 |
}
|
203 |
|
204 |
/**
|
205 |
* Unjoin member from EmailVision platform
|
206 |
*
|
207 |
* @param Mage_Newsletter_Model_Subscriber $subscriber
|
|
|
|
|
208 |
* @param boolean $closeApi
|
209 |
* @return Emv_DataSync_Model_Service_Member
|
210 |
*/
|
211 |
-
public function unjoinOneSubscriber(Mage_Newsletter_Model_Subscriber $subscriber,
|
|
|
|
|
|
|
|
|
212 |
{
|
213 |
if ($subscriber->getId()) {
|
214 |
-
$service
|
215 |
-
$service->unjoinMember('object', $this->getMergeCriteriaForMember($subscriber), $closeApi);
|
216 |
}
|
217 |
|
218 |
return $this;
|
@@ -221,12 +212,17 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
221 |
/**
|
222 |
* Rejoin subscribers to EmailVision platform
|
223 |
* (subscribers that change their status from unsubscribed to subscribe)
|
224 |
-
*
|
|
|
225 |
* @param boolean $closeApi
|
226 |
-
* @return Array
|
227 |
*/
|
228 |
-
public function rejoinSubscribers($
|
|
|
|
|
|
|
229 |
{
|
|
|
230 |
try {
|
231 |
// Subscribers which have last sync more recently than unjoin && that are subscribed
|
232 |
$subscribers = Mage::getModel('newsletter/subscriber')->getCollection()
|
@@ -239,14 +235,21 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
239 |
array('eq'=> Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED),
|
240 |
));
|
241 |
|
242 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
243 |
} catch (Exception $e) {
|
244 |
Mage::logException($e);
|
245 |
$this->_errors[] = 'Exception while retreiving data for subscribers to rejoin with message: ' . $e->getMessage();
|
246 |
}
|
247 |
|
248 |
-
$service = $this->getApiService($this->getAccount());
|
249 |
-
|
250 |
foreach ($subscribers as $subscriber) {
|
251 |
try {
|
252 |
$memberId = false;
|
@@ -264,7 +267,7 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
264 |
}
|
265 |
if ($memberId) {
|
266 |
$service->rejoinMember('id', $memberId, $closeApi);
|
267 |
-
$
|
268 |
}
|
269 |
} catch (Exception $e) {
|
270 |
Mage::logException($e);
|
@@ -273,7 +276,7 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
273 |
}
|
274 |
}
|
275 |
|
276 |
-
return $
|
277 |
}
|
278 |
|
279 |
/**
|
@@ -287,16 +290,20 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
287 |
/**
|
288 |
* Method to set massively the custom member_last_update_date after a member or a batchmember export
|
289 |
*/
|
290 |
-
public function massSetMemberLastUpdateDate(
|
|
|
|
|
|
|
|
|
291 |
{
|
292 |
$subscribersIds = array();
|
293 |
-
foreach ($
|
294 |
$subscribersIds[] = $subscriberId;
|
295 |
}
|
296 |
-
foreach ($
|
297 |
$subscribersIds[] = $subscriberId;
|
298 |
}
|
299 |
-
foreach ($
|
300 |
$subscribersIds[] = $subscriberId;
|
301 |
}
|
302 |
$subscribersIds = array_unique($subscribersIds);
|
@@ -304,7 +311,7 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
304 |
try {
|
305 |
$errorMessage = Mage::helper('emvdatasync/service')->massSetMemberLastUpdateDate(
|
306 |
$subscribersIds,
|
307 |
-
$
|
308 |
);
|
309 |
if ($errorMessage !== true) {
|
310 |
$this->_errors[] = $errorMessage;
|
@@ -319,19 +326,38 @@ class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
|
319 |
*/
|
320 |
public function triggerExport()
|
321 |
{
|
322 |
-
$
|
323 |
-
$this->unjoinSubscribers();
|
324 |
-
$this->rejoinSubscribers();
|
325 |
|
326 |
-
|
327 |
-
|
|
|
|
|
|
|
|
|
328 |
|
329 |
-
|
330 |
-
|
331 |
-
|
332 |
-
|
333 |
-
|
334 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
335 |
}
|
336 |
}
|
337 |
}
|
3 |
* Member service - Handle Member Data
|
4 |
*
|
5 |
* @category Emv
|
6 |
+
* @package Emv_DataSync
|
7 |
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
*/
|
10 |
class Emv_DataSync_Model_Service_Member extends Emv_Core_Model_Service_Member
|
11 |
{
|
|
|
|
|
|
|
|
|
12 |
protected $_errors = array();
|
13 |
|
14 |
/**
|
15 |
* This method will get subscribers that require data update to EmailVision platform
|
16 |
* and manage the api calls in order to insert or update the data
|
17 |
*
|
18 |
+
* @param EmailVision_Api_MemberService $service
|
19 |
+
* @param array $storeIds
|
20 |
+
* @param string $currentStore
|
21 |
+
* @param boolean $closeApi
|
22 |
+
* @return Array - An array contains the subscribers ids updated with success
|
23 |
*/
|
24 |
+
public function exportSubscribers(EmailVision_Api_MemberService $service, array $storeIds = array(), $currentStore = null)
|
25 |
{
|
26 |
$size = false;
|
27 |
+
$updatedSubscribers = array();
|
28 |
try {
|
29 |
// Subscribers that never have been sync || that have been update more recently than their last sync
|
30 |
$subscribers = Mage::getModel('newsletter/subscriber')->getCollection()
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
->addFieldToFilter(
|
32 |
'main_table.subscriber_status',
|
33 |
array(
|
34 |
array('eq' => Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED)
|
35 |
)
|
36 |
);
|
37 |
+
|
38 |
+
// only get subscirbers that have been scheduled
|
39 |
+
$subscribers->addFieldToFilter(
|
40 |
+
'main_table.' . Emv_DataSync_Helper_Service::FIELD_QUEUED,
|
41 |
+
Emv_DataSync_Helper_Service::SCHEDULED_VALUE
|
42 |
+
);
|
43 |
+
|
44 |
+
if (count($storeIds)) {
|
45 |
+
$subscribers->addFieldToFilter('main_table.store_id', array('in' => $storeIds));
|
46 |
+
}
|
47 |
+
|
48 |
$size = $subscribers->getSize();
|
49 |
if ($size) {
|
50 |
// Add all customer and address attributes that have been mapped into collection
|
51 |
+
Mage::getSingleton('emvdatasync/attributeProcessing_config')
|
52 |
+
->prepareSubscriberCollection($subscribers, $currentStore);
|
53 |
}
|
54 |
} catch (Exception $e) {
|
55 |
Mage::logException($e);
|
59 |
if ($size) {
|
60 |
foreach ($subscribers as $subscriber) {
|
61 |
try {
|
62 |
+
$ok = $this->_insertOrUpdateMember($subscriber, $service, $currentStore);
|
63 |
+
if ($ok) {
|
64 |
+
$updatedSubscribers[] = $subscriber->getId();
|
65 |
+
}
|
66 |
} catch (Exception $e) {
|
67 |
Mage::logException($e);
|
68 |
|
72 |
}
|
73 |
}
|
74 |
|
75 |
+
return $updatedSubscribers;
|
76 |
}
|
77 |
|
78 |
/**
|
82 |
* @param Mage_Newsletter_Model_Subscriber $subscriber
|
83 |
* @return array
|
84 |
*/
|
85 |
+
public function getMergeCriteriaForMember(Mage_Newsletter_Model_Subscriber $subscriber, $storeId = null)
|
86 |
{
|
87 |
+
if (Mage::helper('emvdatasync')->getEmailEnabled($storeId)) {
|
88 |
$mergeCriteria = array(strtoupper(Emv_Core_Model_Service_Member::FIELD_EMAIL) => $subscriber->getEmail());
|
89 |
} else {
|
90 |
$mergeCriteria = array(
|
91 |
+
strtoupper(Mage::helper('emvdatasync')->getMappedEntityId($storeId)) => $subscriber->getId()
|
92 |
);
|
93 |
}
|
94 |
return $mergeCriteria;
|
95 |
}
|
96 |
|
|
|
97 |
/**
|
98 |
* Method to call insert or update on subscriber passed as param
|
99 |
*
|
102 |
*
|
103 |
* @return string | boolean $result The soap call result
|
104 |
*/
|
105 |
+
protected function _insertOrUpdateMember(
|
106 |
+
Mage_Newsletter_Model_Subscriber $subscriber,
|
107 |
+
EmailVision_Api_MemberService $service,
|
108 |
+
$storeId = null,
|
109 |
+
$closeApi = false
|
110 |
+
)
|
111 |
{
|
|
|
|
|
112 |
// Replace customer email by suscriber one
|
113 |
$subscriber->setData('email', $subscriber->getSubscriberEmail());
|
114 |
|
115 |
+
$params = Mage::getSingleton('emvdatasync/attributeProcessing_config')
|
116 |
+
->getSubscriberData($subscriber, $storeId);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
117 |
|
118 |
// make api call with all prepared array (mapped attributes and criteria)
|
119 |
try {
|
120 |
$uploadId = null;
|
|
|
121 |
$uploadId = $service->insertOrUpdateMemberByObj(
|
122 |
+
$this->getMergeCriteriaForMember($subscriber, $storeId),
|
123 |
$params,
|
124 |
$closeApi
|
125 |
);
|
|
|
|
|
126 |
} catch (Exception $e) {
|
127 |
Mage::logException($e);
|
128 |
|
134 |
}
|
135 |
|
136 |
/**
|
137 |
+
* Unjoin all unsubscribed members from SmartFocus platform
|
138 |
*
|
139 |
+
* @param EmailVision_Api_MemberService $service
|
140 |
+
* @param array $storeIds
|
141 |
+
* @param string $currentStore
|
142 |
* @param boolean $closeApi
|
143 |
+
* @return Array - An array containing the subscribers ids unjoined with success
|
144 |
*/
|
145 |
+
public function unjoinSubscribers(EmailVision_Api_MemberService $service,
|
146 |
+
array $storeIds = array(),
|
147 |
+
$currentStore = null
|
148 |
+
)
|
149 |
{
|
150 |
+
$unjoinedSubscribers = array();
|
151 |
try {
|
152 |
// Subscribers that have unjoined more recently than their last sync
|
153 |
$subscribers = Mage::getModel('newsletter/subscriber')->getCollection()
|
154 |
+
->addFieldToFilter(
|
155 |
+
'main_table.subscriber_status',
|
156 |
+
array(
|
157 |
+
array('eq' => Mage_Newsletter_Model_Subscriber::STATUS_UNSUBSCRIBED),
|
158 |
+
)
|
159 |
+
);
|
160 |
+
// only get subscirbers that have been scheduled
|
161 |
+
$subscribers->addFieldToFilter(
|
162 |
+
'main_table.' . Emv_DataSync_Helper_Service::FIELD_QUEUED,
|
163 |
+
Emv_DataSync_Helper_Service::SCHEDULED_VALUE
|
|
|
164 |
);
|
165 |
+
|
166 |
+
if (count($storeIds)) {
|
167 |
+
$subscribers->addFieldToFilter('main_table.store_id', array('in' => $storeIds));
|
168 |
+
}
|
169 |
+
|
170 |
} catch (Exception $e) {
|
171 |
Mage::logException($e);
|
172 |
$this->_errors[] = 'Exception while retreiving data for subscribers to unjoin with message: ' . $e->getMessage();
|
174 |
|
175 |
foreach ($subscribers as $subscriber) {
|
176 |
try {
|
177 |
+
$this->unjoinOneSubscriber($subscriber,$service, $currentStore, false);
|
178 |
|
179 |
+
$unjoinedSubscribers[] = $subscriber->getId();
|
180 |
} catch (Exception $e) {
|
181 |
Mage::logException($e);
|
182 |
$this->_errors[] = 'Exception while preparing data to call unjoin, for subscriber '
|
184 |
}
|
185 |
}
|
186 |
|
187 |
+
return $unjoinedSubscribers;
|
188 |
}
|
189 |
|
190 |
/**
|
191 |
* Unjoin member from EmailVision platform
|
192 |
*
|
193 |
* @param Mage_Newsletter_Model_Subscriber $subscriber
|
194 |
+
* @param EmailVision_Api_MemberService $service
|
195 |
+
* @param string $currentStore
|
196 |
* @param boolean $closeApi
|
197 |
* @return Emv_DataSync_Model_Service_Member
|
198 |
*/
|
199 |
+
public function unjoinOneSubscriber(Mage_Newsletter_Model_Subscriber $subscriber,
|
200 |
+
EmailVision_Api_MemberService $service,
|
201 |
+
$currentStore = null,
|
202 |
+
$closeApi = true
|
203 |
+
)
|
204 |
{
|
205 |
if ($subscriber->getId()) {
|
206 |
+
$service->unjoinMember('object', $this->getMergeCriteriaForMember($subscriber, $currentStore), $closeApi);
|
|
|
207 |
}
|
208 |
|
209 |
return $this;
|
212 |
/**
|
213 |
* Rejoin subscribers to EmailVision platform
|
214 |
* (subscribers that change their status from unsubscribed to subscribe)
|
215 |
+
* @param EmailVision_Api_MemberService $service
|
216 |
+
* @param array $storeIds
|
217 |
* @param boolean $closeApi
|
218 |
+
* @return Array - An array containing the subscribers ids rejoined with success
|
219 |
*/
|
220 |
+
public function rejoinSubscribers(EmailVision_Api_MemberService $service,
|
221 |
+
array $storeIds = array(),
|
222 |
+
$closeApi = false
|
223 |
+
)
|
224 |
{
|
225 |
+
$rejoinedSubscribers = array();
|
226 |
try {
|
227 |
// Subscribers which have last sync more recently than unjoin && that are subscribed
|
228 |
$subscribers = Mage::getModel('newsletter/subscriber')->getCollection()
|
235 |
array('eq'=> Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED),
|
236 |
));
|
237 |
|
238 |
+
// only get subscirbers that have been scheduled
|
239 |
+
$subscribers->addFieldToFilter(
|
240 |
+
'main_table.' . Emv_DataSync_Helper_Service::FIELD_QUEUED,
|
241 |
+
Emv_DataSync_Helper_Service::SCHEDULED_VALUE
|
242 |
+
);
|
243 |
+
|
244 |
+
if (count($storeIds)) {
|
245 |
+
$subscribers->addFieldToFilter('main_table.store_id', array('in' => $storeIds));
|
246 |
+
}
|
247 |
+
|
248 |
} catch (Exception $e) {
|
249 |
Mage::logException($e);
|
250 |
$this->_errors[] = 'Exception while retreiving data for subscribers to rejoin with message: ' . $e->getMessage();
|
251 |
}
|
252 |
|
|
|
|
|
253 |
foreach ($subscribers as $subscriber) {
|
254 |
try {
|
255 |
$memberId = false;
|
267 |
}
|
268 |
if ($memberId) {
|
269 |
$service->rejoinMember('id', $memberId, $closeApi);
|
270 |
+
$rejoinedSubscribers[] = $subscriber->getId();
|
271 |
}
|
272 |
} catch (Exception $e) {
|
273 |
Mage::logException($e);
|
276 |
}
|
277 |
}
|
278 |
|
279 |
+
return $rejoinedSubscribers;
|
280 |
}
|
281 |
|
282 |
/**
|
290 |
/**
|
291 |
* Method to set massively the custom member_last_update_date after a member or a batchmember export
|
292 |
*/
|
293 |
+
public function massSetMemberLastUpdateDate(
|
294 |
+
array $updatedSubscribers,
|
295 |
+
array $unjoinedSubscribers,
|
296 |
+
array $rejoinedSubscribers
|
297 |
+
)
|
298 |
{
|
299 |
$subscribersIds = array();
|
300 |
+
foreach ($updatedSubscribers as $subscriberId) {
|
301 |
$subscribersIds[] = $subscriberId;
|
302 |
}
|
303 |
+
foreach ($unjoinedSubscribers as $subscriberId) {
|
304 |
$subscribersIds[] = $subscriberId;
|
305 |
}
|
306 |
+
foreach ($rejoinedSubscribers as $subscriberId) {
|
307 |
$subscribersIds[] = $subscriberId;
|
308 |
}
|
309 |
$subscribersIds = array_unique($subscribersIds);
|
311 |
try {
|
312 |
$errorMessage = Mage::helper('emvdatasync/service')->massSetMemberLastUpdateDate(
|
313 |
$subscribersIds,
|
314 |
+
$rejoinedSubscribers
|
315 |
);
|
316 |
if ($errorMessage !== true) {
|
317 |
$this->_errors[] = $errorMessage;
|
326 |
*/
|
327 |
public function triggerExport()
|
328 |
{
|
329 |
+
$accounts = Mage::helper('emvdatasync')->getActiveEmvAccountsForStore(Emv_DataSync_Helper_Data::TYPE_MEMBER);
|
|
|
|
|
330 |
|
331 |
+
foreach ($accounts as $accountId => $accountData)
|
332 |
+
{
|
333 |
+
$storeIds = $accountData['stores'];
|
334 |
+
$account = $accountData['model'];
|
335 |
+
$service = false;
|
336 |
+
$currentStore = $storeIds[0];
|
337 |
|
338 |
+
try {
|
339 |
+
// Get api service corresponding to current account
|
340 |
+
$service = $this->getApiService($account, $storeIds[0]);
|
341 |
+
} catch (Exception $e) {
|
342 |
+
$this->_errors[] = "The account {$account->getName()} is invalid : " . $e->getMessage();
|
343 |
+
}
|
344 |
+
|
345 |
+
if ($service) {
|
346 |
+
$updatedSubscribers = $this->exportSubscribers($service, $storeIds, $currentStore);
|
347 |
+
$unjoinedSubscribers = $this->unjoinSubscribers($service, $storeIds, $currentStore);
|
348 |
+
$rejoinedSubscribers = $this->rejoinSubscribers($service, $storeIds);
|
349 |
+
|
350 |
+
// Update memberLastUpdateDate
|
351 |
+
$this->massSetMemberLastUpdateDate($updatedSubscribers, $unjoinedSubscribers, $rejoinedSubscribers);
|
352 |
+
|
353 |
+
try {
|
354 |
+
$service->closeApiConnection();
|
355 |
+
} catch (Exception $e) {
|
356 |
+
Mage::logException($e);
|
357 |
+
$this->_errors[] = "Exception while closing SmartFocus service for account {{$account->getName()}} with message : "
|
358 |
+
. $e->getMessage();
|
359 |
+
}
|
360 |
+
}
|
361 |
}
|
362 |
}
|
363 |
}
|
@@ -4,7 +4,8 @@
|
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_DataSync
|
7 |
-
* @
|
|
|
8 |
*/
|
9 |
class Emv_DataSync_Adminhtml_DataSyncController extends Mage_Adminhtml_Controller_Action
|
10 |
{
|
@@ -18,21 +19,268 @@ class Emv_DataSync_Adminhtml_DataSyncController extends Mage_Adminhtml_Controlle
|
|
18 |
$this->setUsedModuleName('Emv_DataSync');
|
19 |
}
|
20 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
/**
|
22 |
* Get EmailVision fields from api object
|
23 |
*/
|
24 |
public function getMemberFieldsAction()
|
25 |
{
|
26 |
$accountId = $this->getRequest()->getParam('account_id', null);
|
27 |
-
$preparedFields = array();
|
28 |
-
|
29 |
-
$account = Mage::getModel('emvcore/account');
|
30 |
if (!$accountId) {
|
31 |
-
$
|
32 |
-
|
33 |
-
|
34 |
}
|
35 |
|
|
|
|
|
|
|
|
|
36 |
// get account id for
|
37 |
if ($account->getId()) {
|
38 |
try {
|
@@ -62,10 +310,6 @@ class Emv_DataSync_Adminhtml_DataSyncController extends Mage_Adminhtml_Controlle
|
|
62 |
|
63 |
if (count($preparedFields)) {
|
64 |
Mage::helper('emvdatasync')->saveEmailVisionFieldsInConfig($preparedFields);
|
65 |
-
// SmartFocus fields need to be in lower case
|
66 |
-
Mage::helper('emvdatasync')->saveMappedEntityId(
|
67 |
-
strtolower(Emv_Core_Model_Service_Member::FIELD_SUBSCRIBER_ID)
|
68 |
-
);
|
69 |
|
70 |
$config = Mage::getModel('core/config');
|
71 |
$config->removeCache();
|
@@ -75,7 +319,21 @@ class Emv_DataSync_Adminhtml_DataSyncController extends Mage_Adminhtml_Controlle
|
|
75 |
);
|
76 |
}
|
77 |
|
78 |
-
$this->_redirect(
|
|
|
|
|
|
|
79 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
}
|
81 |
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_DataSync
|
7 |
+
* @author Minh Quang VO (minhquang.vo@smartfocus.com)
|
8 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
9 |
*/
|
10 |
class Emv_DataSync_Adminhtml_DataSyncController extends Mage_Adminhtml_Controller_Action
|
11 |
{
|
19 |
$this->setUsedModuleName('Emv_DataSync');
|
20 |
}
|
21 |
|
22 |
+
/**
|
23 |
+
* Subscriber Queue Grid
|
24 |
+
*/
|
25 |
+
public function indexAction()
|
26 |
+
{
|
27 |
+
$this->_title($this->__('SmartFocus'))->_title($this->__('Subscriber Export'));
|
28 |
+
|
29 |
+
if ($this->getRequest()->getParam('ajax')) {
|
30 |
+
$this->_forward('grid');
|
31 |
+
return;
|
32 |
+
}
|
33 |
+
$this->loadLayout();
|
34 |
+
|
35 |
+
$this->_setActiveMenu('emailvision/datasync');
|
36 |
+
|
37 |
+
$this->_addContent(
|
38 |
+
$this->getLayout()->createBlock('emvdatasync/adminhtml_newsletter_subscriber','subscriber')
|
39 |
+
);
|
40 |
+
|
41 |
+
$this->renderLayout();
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Subscriber Queue Grid action for ajax request
|
46 |
+
*/
|
47 |
+
public function gridAction()
|
48 |
+
{
|
49 |
+
$this->loadLayout();
|
50 |
+
$this->getResponse()->setBody(
|
51 |
+
$this->getLayout()->createBlock('emvdatasync/adminhtml_newsletter_subscriber_grid')->toHtml()
|
52 |
+
);
|
53 |
+
}
|
54 |
+
|
55 |
+
/**
|
56 |
+
* Export subscribers grid to CSV format
|
57 |
+
*/
|
58 |
+
public function exportCsvAction()
|
59 |
+
{
|
60 |
+
$fileName = 'subscribers.csv';
|
61 |
+
$content = $this->getLayout()->createBlock('emvdatasync/adminhtml_newsletter_subscriber_grid')
|
62 |
+
->getCsvFile();
|
63 |
+
|
64 |
+
$this->_prepareDownloadResponse($fileName, $content);
|
65 |
+
}
|
66 |
+
|
67 |
+
/**
|
68 |
+
* Export subscribers grid to XML format
|
69 |
+
*/
|
70 |
+
public function exportXmlAction()
|
71 |
+
{
|
72 |
+
$fileName = 'subscribers.xml';
|
73 |
+
$content = $this->getLayout()->createBlock('emvdatasync/adminhtml_newsletter_subscriber_grid')
|
74 |
+
->getExcelFile();
|
75 |
+
|
76 |
+
$this->_prepareDownloadResponse($fileName, $content);
|
77 |
+
}
|
78 |
+
|
79 |
+
/**
|
80 |
+
* Schedule or Remove subscriber list from export queue action
|
81 |
+
*/
|
82 |
+
public function massQueueAction()
|
83 |
+
{
|
84 |
+
$subscribersIds = $this->getRequest()->getParam('subscriber');
|
85 |
+
if (!is_array($subscribersIds) || count($subscribersIds) == 0) {
|
86 |
+
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('newsletter')->__('Please select subscriber(s)'));
|
87 |
+
} else {
|
88 |
+
try {
|
89 |
+
$scheduled = $this->getRequest()->getParam('scheduled');
|
90 |
+
if (
|
91 |
+
$scheduled != Emv_DataSync_Helper_Service::SCHEDULED_VALUE
|
92 |
+
&& $scheduled != Emv_DataSync_Helper_Service::NOT_SCHEDULED_VALUE
|
93 |
+
) {
|
94 |
+
$scheduled = Emv_DataSync_Helper_Service::SCHEDULED_VALUE;
|
95 |
+
}
|
96 |
+
|
97 |
+
Mage::helper('emvdatasync')->massScheduleSubscriber($subscribersIds, $scheduled);
|
98 |
+
Mage::getSingleton('adminhtml/session')->addSuccess(
|
99 |
+
Mage::helper('adminhtml')->__('Total of %d record(s) were updated', count($subscribersIds))
|
100 |
+
);
|
101 |
+
} catch (Exception $e) {
|
102 |
+
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
|
103 |
+
}
|
104 |
+
}
|
105 |
+
|
106 |
+
$this->_redirect('*/*/index');
|
107 |
+
}
|
108 |
+
|
109 |
+
/**
|
110 |
+
* Mass dry test - creating csv files for the given subscribers list
|
111 |
+
* Allows to download the file(s) if they are readable else display the error message and forward to queue grid
|
112 |
+
*/
|
113 |
+
public function massDryTestAction()
|
114 |
+
{
|
115 |
+
$subscribersIds = $this->getRequest()->getParam('subscriber');
|
116 |
+
if (!is_array($subscribersIds) || count($subscribersIds) == 0) {
|
117 |
+
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('newsletter')->__('Please select subscriber(s)'));
|
118 |
+
} else {
|
119 |
+
try {
|
120 |
+
$service = Mage::getModel('emvdatasync/service_batchMember');
|
121 |
+
$output = $service->massExportCustomers($subscribersIds, true);
|
122 |
+
|
123 |
+
// If non-blocking errors occurs
|
124 |
+
$processErrors = $service->getErrors();
|
125 |
+
if (!empty($processErrors)) {
|
126 |
+
foreach ($processErrors as $error) {
|
127 |
+
Mage::getSingleton('adminhtml/session')->addError($error);
|
128 |
+
}
|
129 |
+
} else {
|
130 |
+
$listFileToZip = array();
|
131 |
+
foreach ($output as $accountId => $fileData) {
|
132 |
+
foreach ($fileData['treated_files'] as $file) {
|
133 |
+
if (is_readable($file['path'])) {
|
134 |
+
$listFileToZip[] = array($file['path'], $file['filename']);
|
135 |
+
}
|
136 |
+
}
|
137 |
+
}
|
138 |
+
|
139 |
+
if (count($listFileToZip)) {
|
140 |
+
$downloadFileName = 'export_files_'.rand().'.zip';
|
141 |
+
$zipFilePath = Mage::getBaseDir(Emv_Core_Helper_Data::BASE_CONTAINER)
|
142 |
+
. DS . Emv_Core_Helper_Data::BASE_WORKING_DIR . DS . Emv_Core_Helper_Data::TEMPORARY_DIR;
|
143 |
+
Mage_System_Dirs::mkdirStrict($zipFilePath);
|
144 |
+
|
145 |
+
$zipFileName = $zipFilePath . DS . $downloadFileName;
|
146 |
+
$zip = new ZipArchive();
|
147 |
+
if ($zip->open($zipFileName, ZIPARCHIVE::CREATE) === true) {
|
148 |
+
/**
|
149 |
+
* Manage list of files to zip
|
150 |
+
*/
|
151 |
+
foreach ($listFileToZip as $file) {
|
152 |
+
if (is_readable($file[0])) {
|
153 |
+
$zip->addFile($file[0], $file[1]);
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
+
$zip->close();
|
158 |
+
|
159 |
+
$content = array(
|
160 |
+
'type' => 'filename',
|
161 |
+
'value' => $zipFileName,
|
162 |
+
'rm' => true,
|
163 |
+
);
|
164 |
+
return $this->_prepareDownloadResponse($downloadFileName, $content, 'application/zip');
|
165 |
+
} else {
|
166 |
+
Mage::throwException(Mage::helper('emvdatasync')->__('Error while creating archive'));
|
167 |
+
}
|
168 |
+
} else {
|
169 |
+
Mage::getSingleton('adminhtml/session')->addNotice(
|
170 |
+
Mage::helper('emvdatasync')->__('No file is generated')
|
171 |
+
);
|
172 |
+
}
|
173 |
+
}
|
174 |
+
} catch (Exception $e) {
|
175 |
+
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
|
176 |
+
}
|
177 |
+
}
|
178 |
+
|
179 |
+
$this->_redirect('*/*/index');
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Make a test of synchronization
|
184 |
+
*/
|
185 |
+
public function sendTestAction()
|
186 |
+
{
|
187 |
+
$subscribersIds = $this->getRequest()->getParam('subscriber');
|
188 |
+
if (!is_array($subscribersIds) || count($subscribersIds) == 0) {
|
189 |
+
Mage::getSingleton('adminhtml/session')->addError(Mage::helper('newsletter')->__('Please select subscriber(s)'));
|
190 |
+
} else {
|
191 |
+
$allowed = (int)Mage::getStoreConfig(Emv_DataSync_Helper_Data::XML_PATH_ALLOWED_NUMBER_TEST);
|
192 |
+
if ($allowed < count($subscribersIds)) {
|
193 |
+
Mage::getSingleton('adminhtml/session')->addError(
|
194 |
+
Mage::helper('emvdatasync')->__(
|
195 |
+
'Your list (%s members) exceeds the allowed limit (%s)!',
|
196 |
+
count($subscribersIds),
|
197 |
+
$allowed
|
198 |
+
)
|
199 |
+
);
|
200 |
+
} else {
|
201 |
+
$helper = Mage::helper('emvdatasync');
|
202 |
+
$createdLock = false;
|
203 |
+
$startRunTime = $helper->getFormattedGmtDateTime();
|
204 |
+
|
205 |
+
try {
|
206 |
+
// check and create lock
|
207 |
+
if (!$helper->checkLockFile()) {
|
208 |
+
// create lock file => do not allow several process at the same time
|
209 |
+
$helper->createLockFile('Batch member synchronization cron process running at GMT timezone '
|
210 |
+
. $startRunTime
|
211 |
+
);
|
212 |
+
$service = Mage::getModel('emvdatasync/service_batchMember');
|
213 |
+
$createdLock = true;
|
214 |
+
|
215 |
+
$service->init();
|
216 |
+
$service->setInputData(array('test_mode' => true, 'member_ids' => $subscribersIds));
|
217 |
+
$service->run();
|
218 |
+
|
219 |
+
$gridLink = sprintf(
|
220 |
+
'<a href="%s">%s</a>',
|
221 |
+
$this->getUrl('emv_core/dataProcessing'),
|
222 |
+
Mage::helper('emvcore')->__('Process grid')
|
223 |
+
);
|
224 |
+
Mage::getSingleton('adminhtml/session')->addNotice(
|
225 |
+
Mage::helper('emvdatasync')->__(
|
226 |
+
'Your synchronization (%s subscriber(s)) has been triggered. Please look at process %s (%s)',
|
227 |
+
count($subscribersIds),
|
228 |
+
$service->getProcess()->getId(),
|
229 |
+
$gridLink
|
230 |
+
)
|
231 |
+
);
|
232 |
+
|
233 |
+
// If non-blocking errors occurs
|
234 |
+
$processErrors = $service->getErrors();
|
235 |
+
if (!empty($processErrors)) {
|
236 |
+
$url = Mage::helper('emvcore')->getLogUrlForProcess($service->getProcess());
|
237 |
+
$logLink = sprintf('<a href="%s">%s</a>', $url, Mage::helper('emvcore')->__('Click here'));
|
238 |
+
Mage::getSingleton('adminhtml/session')->addError(
|
239 |
+
Mage::helper('emvdatasync')->__(
|
240 |
+
'Some non-blocking errors occured, check log (%s) for more details!',
|
241 |
+
$logLink
|
242 |
+
)
|
243 |
+
);
|
244 |
+
}
|
245 |
+
} else {
|
246 |
+
Mage::getSingleton('adminhtml/session')->addError(
|
247 |
+
Mage::helper('newsletter')->__('Another Data Sync has been running! Please wait until it finishes!')
|
248 |
+
);
|
249 |
+
}
|
250 |
+
} catch (Exception $e) {
|
251 |
+
Mage::getSingleton('adminhtml/session')->addError($e->getMessage());
|
252 |
+
}
|
253 |
+
|
254 |
+
// if lock is created, need to delete it
|
255 |
+
if ($createdLock) {
|
256 |
+
try {
|
257 |
+
$helper->removeLockFile();
|
258 |
+
} catch (Exception $e) {
|
259 |
+
// don't do anything
|
260 |
+
}
|
261 |
+
}
|
262 |
+
}
|
263 |
+
}
|
264 |
+
|
265 |
+
$this->_redirect('*/*/index');
|
266 |
+
}
|
267 |
+
|
268 |
/**
|
269 |
* Get EmailVision fields from api object
|
270 |
*/
|
271 |
public function getMemberFieldsAction()
|
272 |
{
|
273 |
$accountId = $this->getRequest()->getParam('account_id', null);
|
|
|
|
|
|
|
274 |
if (!$accountId) {
|
275 |
+
$accountId = Mage::helper('emvcore')->getAdminScopedConfig(
|
276 |
+
Emv_DataSync_Helper_Data::XML_PATH_ACCOUNT_FOR_MEMBER
|
277 |
+
);
|
278 |
}
|
279 |
|
280 |
+
$preparedFields = array();
|
281 |
+
|
282 |
+
$account = Mage::getModel('emvcore/account');
|
283 |
+
$account->load($accountId);
|
284 |
// get account id for
|
285 |
if ($account->getId()) {
|
286 |
try {
|
310 |
|
311 |
if (count($preparedFields)) {
|
312 |
Mage::helper('emvdatasync')->saveEmailVisionFieldsInConfig($preparedFields);
|
|
|
|
|
|
|
|
|
313 |
|
314 |
$config = Mage::getModel('core/config');
|
315 |
$config->removeCache();
|
319 |
);
|
320 |
}
|
321 |
|
322 |
+
$this->_redirect(
|
323 |
+
'adminhtml/system_config/edit/section/emvdatasync/',
|
324 |
+
array('_current' => array('section', 'website', 'store'))
|
325 |
+
);
|
326 |
}
|
327 |
+
|
328 |
+
/**
|
329 |
+
* Check if having a correct permission
|
330 |
+
*
|
331 |
+
* @return boolean
|
332 |
+
*/
|
333 |
+
protected function _isallowed()
|
334 |
+
{
|
335 |
+
return Mage::getSingleton('admin/session')->isAllowed('emailvision/datasync/queue');
|
336 |
+
}
|
337 |
+
|
338 |
}
|
339 |
|
@@ -1,9 +1,42 @@
|
|
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<config>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
3 |
<acl>
|
4 |
<resources>
|
5 |
<admin>
|
6 |
<children>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
<system>
|
8 |
<children>
|
9 |
<config>
|
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<config>
|
3 |
+
<menu>
|
4 |
+
<emailvision>
|
5 |
+
<children>
|
6 |
+
<!-- SmartFocus Data Sync menu in the back office -->
|
7 |
+
<datasync translate="title" module="emvdatasync">
|
8 |
+
<title>Subscriber Export</title>
|
9 |
+
<sort_order>999</sort_order>
|
10 |
+
<children>
|
11 |
+
<queue translate="title">
|
12 |
+
<title>Newsletter Subscriber Queue</title>
|
13 |
+
<sort_order>10</sort_order>
|
14 |
+
<action>emv_datasync/dataSync</action>
|
15 |
+
</queue>
|
16 |
+
</children>
|
17 |
+
</datasync>
|
18 |
+
</children>
|
19 |
+
</emailvision>
|
20 |
+
</menu>
|
21 |
+
|
22 |
<acl>
|
23 |
<resources>
|
24 |
<admin>
|
25 |
<children>
|
26 |
+
<emailvision>
|
27 |
+
<children>
|
28 |
+
<datasync>
|
29 |
+
<title>Subscriber Export</title>
|
30 |
+
<sort_order>999</sort_order>
|
31 |
+
<children>
|
32 |
+
<queue>
|
33 |
+
<title>Subscriber Queue</title>
|
34 |
+
<sort_order>10</sort_order>
|
35 |
+
</queue>
|
36 |
+
</children>
|
37 |
+
</datasync>
|
38 |
+
</children>
|
39 |
+
</emailvision>
|
40 |
<system>
|
41 |
<children>
|
42 |
<config>
|
@@ -2,7 +2,7 @@
|
|
2 |
<config>
|
3 |
<modules>
|
4 |
<Emv_DataSync>
|
5 |
-
<version>0.1
|
6 |
</Emv_DataSync>
|
7 |
</modules>
|
8 |
|
@@ -31,21 +31,37 @@
|
|
31 |
</adminhtml>
|
32 |
|
33 |
<global>
|
|
|
|
|
|
|
|
|
34 |
<blocks>
|
35 |
<emvdatasync>
|
36 |
<class>Emv_DataSync_Block</class>
|
37 |
</emvdatasync>
|
38 |
</blocks>
|
|
|
39 |
<models>
|
40 |
<emvdatasync>
|
41 |
<class>Emv_DataSync_Model</class>
|
|
|
42 |
</emvdatasync>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
</models>
|
|
|
44 |
<helpers>
|
45 |
<emvdatasync>
|
46 |
<class>Emv_DataSync_Helper</class>
|
47 |
</emvdatasync>
|
48 |
</helpers>
|
|
|
49 |
<resources>
|
50 |
<emvdatasync_setup>
|
51 |
<setup>
|
@@ -66,6 +82,8 @@
|
|
66 |
</connection>
|
67 |
</emvdatasync_read>
|
68 |
</resources>
|
|
|
|
|
69 |
<events>
|
70 |
<!-- customer/customer -->
|
71 |
<customer_save_after>
|
@@ -106,18 +124,28 @@
|
|
106 |
</emailvision_on_subscriber_save>
|
107 |
</observers>
|
108 |
</newsletter_subscriber_save_after>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
</events>
|
|
|
110 |
<template>
|
111 |
<email>
|
112 |
<emvdatasync_general_error_email_template translate="label" module="directory">
|
113 |
-
<label>
|
114 |
-
<file>
|
115 |
<type>html</type>
|
116 |
</emvdatasync_general_error_email_template>
|
117 |
</email>
|
118 |
</template>
|
119 |
</global>
|
120 |
|
|
|
121 |
<crontab>
|
122 |
<jobs>
|
123 |
<emailvision_member_export>
|
@@ -130,22 +158,34 @@
|
|
130 |
<model>emvdatasync/cron::batchMemberExport</model>
|
131 |
</run>
|
132 |
</emailvision_batchmember_export>
|
133 |
-
<
|
134 |
<run>
|
135 |
<model>emvdatasync/cron::cleanEmailVisionFiles</model>
|
136 |
</run>
|
137 |
-
</
|
|
|
|
|
|
|
|
|
|
|
138 |
</jobs>
|
139 |
</crontab>
|
140 |
|
|
|
141 |
<default>
|
142 |
<emvdatasync>
|
143 |
<general>
|
|
|
144 |
<error_email_recipient>contact@domain.com</error_email_recipient>
|
145 |
<error_email_sender>general</error_email_sender>
|
146 |
<error_email_template>emvdatasync_batchmember_error_email_template</error_email_template>
|
147 |
</general>
|
148 |
|
|
|
|
|
|
|
|
|
|
|
149 |
<batchmember>
|
150 |
<performance>10000</performance>
|
151 |
<enabled>0</enabled>
|
2 |
<config>
|
3 |
<modules>
|
4 |
<Emv_DataSync>
|
5 |
+
<version>0.2.1</version>
|
6 |
</Emv_DataSync>
|
7 |
</modules>
|
8 |
|
31 |
</adminhtml>
|
32 |
|
33 |
<global>
|
34 |
+
<smartfocus_attribute_processing>
|
35 |
+
<newsletter>emvdatasync/attributeProcessing_handler_newsletter</newsletter>
|
36 |
+
<purchase_information>emvdatasync/attributeProcessing_handler_purchaseInformation</purchase_information>
|
37 |
+
</smartfocus_attribute_processing>
|
38 |
<blocks>
|
39 |
<emvdatasync>
|
40 |
<class>Emv_DataSync_Block</class>
|
41 |
</emvdatasync>
|
42 |
</blocks>
|
43 |
+
<!-- Model Defintion -->
|
44 |
<models>
|
45 |
<emvdatasync>
|
46 |
<class>Emv_DataSync_Model</class>
|
47 |
+
<resourceModel>emvdatasync_mysql4</resourceModel>
|
48 |
</emvdatasync>
|
49 |
+
<emvdatasync_mysql4>
|
50 |
+
<class>Emv_DataSync_Model_Mysql4</class>
|
51 |
+
<entities>
|
52 |
+
<purchase_info>
|
53 |
+
<table>emv_dataprocess_purchaseinformation</table>
|
54 |
+
</purchase_info>
|
55 |
+
</entities>
|
56 |
+
</emvdatasync_mysql4>
|
57 |
</models>
|
58 |
+
<!-- Helper Defintion -->
|
59 |
<helpers>
|
60 |
<emvdatasync>
|
61 |
<class>Emv_DataSync_Helper</class>
|
62 |
</emvdatasync>
|
63 |
</helpers>
|
64 |
+
<!-- Resource Defintion -->
|
65 |
<resources>
|
66 |
<emvdatasync_setup>
|
67 |
<setup>
|
82 |
</connection>
|
83 |
</emvdatasync_read>
|
84 |
</resources>
|
85 |
+
|
86 |
+
<!-- Event observers -->
|
87 |
<events>
|
88 |
<!-- customer/customer -->
|
89 |
<customer_save_after>
|
124 |
</emailvision_on_subscriber_save>
|
125 |
</observers>
|
126 |
</newsletter_subscriber_save_after>
|
127 |
+
<sales_order_save_after>
|
128 |
+
<observers>
|
129 |
+
<emailvision_on_order_save_after>
|
130 |
+
<class>emvdatasync/observer</class>
|
131 |
+
<method>handleOrderSaveAfter</method>
|
132 |
+
</emailvision_on_order_save_after>
|
133 |
+
</observers>
|
134 |
+
</sales_order_save_after>
|
135 |
</events>
|
136 |
+
<!-- Email Template -->
|
137 |
<template>
|
138 |
<email>
|
139 |
<emvdatasync_general_error_email_template translate="label" module="directory">
|
140 |
+
<label>SmartFocus Cron Errors</label>
|
141 |
+
<file>smartfocus/datasync/cron_errors.html</file>
|
142 |
<type>html</type>
|
143 |
</emvdatasync_general_error_email_template>
|
144 |
</email>
|
145 |
</template>
|
146 |
</global>
|
147 |
|
148 |
+
<!-- Cron tab -->
|
149 |
<crontab>
|
150 |
<jobs>
|
151 |
<emailvision_member_export>
|
158 |
<model>emvdatasync/cron::batchMemberExport</model>
|
159 |
</run>
|
160 |
</emailvision_batchmember_export>
|
161 |
+
<emailvision_batchmember_cleanning>
|
162 |
<run>
|
163 |
<model>emvdatasync/cron::cleanEmailVisionFiles</model>
|
164 |
</run>
|
165 |
+
</emailvision_batchmember_cleanning>
|
166 |
+
<emailvision_purchase_process>
|
167 |
+
<run>
|
168 |
+
<model>emvdatasync/cron::startPurchaseProcess</model>
|
169 |
+
</run>
|
170 |
+
</emailvision_purchase_process>
|
171 |
</jobs>
|
172 |
</crontab>
|
173 |
|
174 |
+
<!-- Default parameters -->
|
175 |
<default>
|
176 |
<emvdatasync>
|
177 |
<general>
|
178 |
+
<test_members>50</test_members>
|
179 |
<error_email_recipient>contact@domain.com</error_email_recipient>
|
180 |
<error_email_sender>general</error_email_sender>
|
181 |
<error_email_template>emvdatasync_batchmember_error_email_template</error_email_template>
|
182 |
</general>
|
183 |
|
184 |
+
<purchase_info>
|
185 |
+
<enabled>0</enabled>
|
186 |
+
<limit_size>75000</limit_size>
|
187 |
+
</purchase_info>
|
188 |
+
|
189 |
<batchmember>
|
190 |
<performance>10000</performance>
|
191 |
<enabled>0</enabled>
|
@@ -9,11 +9,26 @@
|
|
9 |
<show_in_website>1</show_in_website>
|
10 |
<show_in_store>1</show_in_store>
|
11 |
<groups>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
<general translate="label comment" module="emvdatasync">
|
13 |
<label>General</label>
|
14 |
<sort_order>10</sort_order>
|
15 |
<show_in_default>1</show_in_default>
|
16 |
<fields>
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
<error_email_recipient translate="label">
|
18 |
<label>Error Email Recipient</label>
|
19 |
<frontend_type>text</frontend_type>
|
@@ -36,12 +51,44 @@
|
|
36 |
</error_email_template>
|
37 |
</fields>
|
38 |
</general>
|
39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
40 |
<apimember translate="label comment" module="emvdatasync">
|
41 |
<label>Triggered Export Settings</label>
|
42 |
<comment>Enable the automatic update of your members data with apimember (Member Service)</comment>
|
43 |
<sort_order>20</sort_order>
|
44 |
<show_in_default>1</show_in_default>
|
|
|
|
|
45 |
<fields>
|
46 |
<enabled translate="label">
|
47 |
<label>Enabled</label>
|
@@ -50,14 +97,18 @@
|
|
50 |
<backend_model>emvdatasync/adminhtml_system_config_backend_apiMember_enabled</backend_model>
|
51 |
<sort_order>1</sort_order>
|
52 |
<show_in_default>1</show_in_default>
|
|
|
|
|
53 |
</enabled>
|
54 |
<account translate="label">
|
55 |
<label>SmartFocus Account</label>
|
56 |
<frontend_type>select</frontend_type>
|
57 |
-
<source_model>emvcore/
|
58 |
<backend_model>emvdatasync/adminhtml_system_config_backend_apiMember_account</backend_model>
|
59 |
<sort_order>10</sort_order>
|
60 |
<show_in_default>1</show_in_default>
|
|
|
|
|
61 |
</account>
|
62 |
<frequency translate="label">
|
63 |
<label>Frequency</label>
|
@@ -76,6 +127,8 @@
|
|
76 |
<frontend_type>text</frontend_type>
|
77 |
<sort_order>30</sort_order>
|
78 |
<show_in_default>1</show_in_default>
|
|
|
|
|
79 |
<fields>
|
80 |
<enabled translate="label">
|
81 |
<label>Enabled</label>
|
@@ -84,14 +137,18 @@
|
|
84 |
<backend_model>emvdatasync/adminhtml_system_config_backend_batchMember_enabled</backend_model>
|
85 |
<sort_order>1</sort_order>
|
86 |
<show_in_default>1</show_in_default>
|
|
|
|
|
87 |
</enabled>
|
88 |
<account translate="label">
|
89 |
<label>SmartFocus Account</label>
|
90 |
<frontend_type>select</frontend_type>
|
91 |
-
<source_model>emvcore/
|
92 |
<backend_model>emvdatasync/adminhtml_system_config_backend_batchMember_account</backend_model>
|
93 |
<sort_order>10</sort_order>
|
94 |
<show_in_default>1</show_in_default>
|
|
|
|
|
95 |
</account>
|
96 |
<frequency translate="label">
|
97 |
<label>Frequency</label>
|
@@ -100,6 +157,22 @@
|
|
100 |
<sort_order>20</sort_order>
|
101 |
<show_in_default>1</show_in_default>
|
102 |
</frequency>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
<time translate="label">
|
104 |
<label>Start Time (in Admin timezone)</label>
|
105 |
<frontend_type>time</frontend_type>
|
@@ -131,20 +204,36 @@
|
|
131 |
<sort_order>1</sort_order>
|
132 |
<show_in_default>1</show_in_default>
|
133 |
</enabled>
|
134 |
-
<time translate="label">
|
135 |
-
<label>Start Time (in Admin timezone)</label>
|
136 |
-
<frontend_type>time</frontend_type>
|
137 |
-
<backend_model>emvdatasync/adminhtml_system_config_backend_clean_cron</backend_model>
|
138 |
-
<sort_order>3</sort_order>
|
139 |
-
<show_in_default>1</show_in_default>
|
140 |
-
</time>
|
141 |
<frequency translate="label">
|
142 |
<label>Frequency</label>
|
143 |
<frontend_type>select</frontend_type>
|
144 |
<source_model>adminhtml/system_config_source_cron_frequency</source_model>
|
145 |
-
<sort_order>
|
146 |
<show_in_default>1</show_in_default>
|
147 |
</frequency>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
</fields>
|
149 |
</export_file_cleaning>
|
150 |
|
@@ -169,6 +258,8 @@
|
|
169 |
<frontend_type>text</frontend_type>
|
170 |
<sort_order>70</sort_order>
|
171 |
<show_in_default>1</show_in_default>
|
|
|
|
|
172 |
<fields>
|
173 |
<get_emailvision_fields translate="label comment">
|
174 |
<label>Field Synchronization</label>
|
@@ -177,6 +268,8 @@
|
|
177 |
<comment>Connect to SmartFocus apimember webservice and get the list of available fields</comment>
|
178 |
<sort_order>1</sort_order>
|
179 |
<show_in_default>1</show_in_default>
|
|
|
|
|
180 |
</get_emailvision_fields>
|
181 |
<email_enabled translate="label">
|
182 |
<label>Synchronize with email</label>
|
@@ -185,6 +278,8 @@
|
|
185 |
<comment>If enabled, Magento newsletter subscribers will be synced by their email address. By default, the SmartFocus Entity Id will be used.</comment>
|
186 |
<sort_order>3</sort_order>
|
187 |
<show_in_default>1</show_in_default>
|
|
|
|
|
188 |
</email_enabled>
|
189 |
<emailvision_entity_id translate="label comment">
|
190 |
<label>SmartFocus Entity Id</label>
|
@@ -193,6 +288,8 @@
|
|
193 |
<comment>Default field used to link a Magento newsletter subscriber to a SmartFocus member. CLIENTURN is selected by default.</comment>
|
194 |
<sort_order>5</sort_order>
|
195 |
<show_in_default>1</show_in_default>
|
|
|
|
|
196 |
</emailvision_entity_id>
|
197 |
<attributes translate="comment">
|
198 |
<label></label>
|
@@ -201,6 +298,8 @@
|
|
201 |
<backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
|
202 |
<sort_order>10</sort_order>
|
203 |
<show_in_default>1</show_in_default>
|
|
|
|
|
204 |
</attributes>
|
205 |
</fields>
|
206 |
</customer_mapping>
|
9 |
<show_in_website>1</show_in_website>
|
10 |
<show_in_store>1</show_in_store>
|
11 |
<groups>
|
12 |
+
<extension_status translate="label">
|
13 |
+
<label>Plugin Status</label>
|
14 |
+
<frontend_model>emvcore/adminhtml_config_extensionStatus</frontend_model>
|
15 |
+
<sort_order>0</sort_order>
|
16 |
+
<frontend_type>text</frontend_type>
|
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 |
+
</extension_status>
|
21 |
<general translate="label comment" module="emvdatasync">
|
22 |
<label>General</label>
|
23 |
<sort_order>10</sort_order>
|
24 |
<show_in_default>1</show_in_default>
|
25 |
<fields>
|
26 |
+
<test_members>
|
27 |
+
<label>Allowed Numbers of Subscribers (for testing)</label>
|
28 |
+
<frontend_type>text</frontend_type>
|
29 |
+
<sort_order>40</sort_order>
|
30 |
+
<show_in_default>1</show_in_default>
|
31 |
+
</test_members>
|
32 |
<error_email_recipient translate="label">
|
33 |
<label>Error Email Recipient</label>
|
34 |
<frontend_type>text</frontend_type>
|
51 |
</error_email_template>
|
52 |
</fields>
|
53 |
</general>
|
54 |
+
<purchase_info>
|
55 |
+
<label>Purchase Data Process Settings</label>
|
56 |
+
<comment>Enable the automatic calculation for Customer Purchase Data</comment>
|
57 |
+
<sort_order>15</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 |
+
<fields>
|
62 |
+
<enabled translate="label">
|
63 |
+
<label>Enabled</label>
|
64 |
+
<frontend_type>select</frontend_type>
|
65 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
66 |
+
<sort_order>1</sort_order>
|
67 |
+
<show_in_default>1</show_in_default>
|
68 |
+
</enabled>
|
69 |
+
<limit_size>
|
70 |
+
<label>The limit of purchase information to store</label>
|
71 |
+
<frontend_type>text</frontend_type>
|
72 |
+
<sort_order>10</sort_order>
|
73 |
+
<show_in_default>1</show_in_default>
|
74 |
+
</limit_size>
|
75 |
+
<frequency translate="label">
|
76 |
+
<label>Frequency</label>
|
77 |
+
<frontend_type>select</frontend_type>
|
78 |
+
<source_model>emvdatasync/adminhtml_system_config_source_memberCronTime</source_model>
|
79 |
+
<backend_model>emvdatasync/adminhtml_system_config_backend_purchaseProcess_cron</backend_model>
|
80 |
+
<sort_order>20</sort_order>
|
81 |
+
<show_in_default>1</show_in_default>
|
82 |
+
</frequency>
|
83 |
+
</fields>
|
84 |
+
</purchase_info>
|
85 |
<apimember translate="label comment" module="emvdatasync">
|
86 |
<label>Triggered Export Settings</label>
|
87 |
<comment>Enable the automatic update of your members data with apimember (Member Service)</comment>
|
88 |
<sort_order>20</sort_order>
|
89 |
<show_in_default>1</show_in_default>
|
90 |
+
<show_in_website>1</show_in_website>
|
91 |
+
<show_in_store>1</show_in_store>
|
92 |
<fields>
|
93 |
<enabled translate="label">
|
94 |
<label>Enabled</label>
|
97 |
<backend_model>emvdatasync/adminhtml_system_config_backend_apiMember_enabled</backend_model>
|
98 |
<sort_order>1</sort_order>
|
99 |
<show_in_default>1</show_in_default>
|
100 |
+
<show_in_website>1</show_in_website>
|
101 |
+
<show_in_store>1</show_in_store>
|
102 |
</enabled>
|
103 |
<account translate="label">
|
104 |
<label>SmartFocus Account</label>
|
105 |
<frontend_type>select</frontend_type>
|
106 |
+
<source_model>emvcore/adminhtml_system_config_source_account</source_model>
|
107 |
<backend_model>emvdatasync/adminhtml_system_config_backend_apiMember_account</backend_model>
|
108 |
<sort_order>10</sort_order>
|
109 |
<show_in_default>1</show_in_default>
|
110 |
+
<show_in_website>1</show_in_website>
|
111 |
+
<show_in_store>1</show_in_store>
|
112 |
</account>
|
113 |
<frequency translate="label">
|
114 |
<label>Frequency</label>
|
127 |
<frontend_type>text</frontend_type>
|
128 |
<sort_order>30</sort_order>
|
129 |
<show_in_default>1</show_in_default>
|
130 |
+
<show_in_website>1</show_in_website>
|
131 |
+
<show_in_store>1</show_in_store>
|
132 |
<fields>
|
133 |
<enabled translate="label">
|
134 |
<label>Enabled</label>
|
137 |
<backend_model>emvdatasync/adminhtml_system_config_backend_batchMember_enabled</backend_model>
|
138 |
<sort_order>1</sort_order>
|
139 |
<show_in_default>1</show_in_default>
|
140 |
+
<show_in_website>1</show_in_website>
|
141 |
+
<show_in_store>1</show_in_store>
|
142 |
</enabled>
|
143 |
<account translate="label">
|
144 |
<label>SmartFocus Account</label>
|
145 |
<frontend_type>select</frontend_type>
|
146 |
+
<source_model>emvcore/adminhtml_system_config_source_account</source_model>
|
147 |
<backend_model>emvdatasync/adminhtml_system_config_backend_batchMember_account</backend_model>
|
148 |
<sort_order>10</sort_order>
|
149 |
<show_in_default>1</show_in_default>
|
150 |
+
<show_in_website>1</show_in_website>
|
151 |
+
<show_in_store>1</show_in_store>
|
152 |
</account>
|
153 |
<frequency translate="label">
|
154 |
<label>Frequency</label>
|
157 |
<sort_order>20</sort_order>
|
158 |
<show_in_default>1</show_in_default>
|
159 |
</frequency>
|
160 |
+
<day>
|
161 |
+
<label>Day of the week</label>
|
162 |
+
<frontend_type>select</frontend_type>
|
163 |
+
<source_model>emvcore/adminhtml_system_config_source_cronDay</source_model>
|
164 |
+
<sort_order>22</sort_order>
|
165 |
+
<depends><frequency>W</frequency></depends>
|
166 |
+
<show_in_default>1</show_in_default>
|
167 |
+
</day>
|
168 |
+
<date>
|
169 |
+
<label>Date of the month</label>
|
170 |
+
<frontend_type>select</frontend_type>
|
171 |
+
<source_model>emvcore/adminhtml_system_config_source_cronDate</source_model>
|
172 |
+
<sort_order>23</sort_order>
|
173 |
+
<depends><frequency>M</frequency></depends>
|
174 |
+
<show_in_default>1</show_in_default>
|
175 |
+
</date>
|
176 |
<time translate="label">
|
177 |
<label>Start Time (in Admin timezone)</label>
|
178 |
<frontend_type>time</frontend_type>
|
204 |
<sort_order>1</sort_order>
|
205 |
<show_in_default>1</show_in_default>
|
206 |
</enabled>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
207 |
<frequency translate="label">
|
208 |
<label>Frequency</label>
|
209 |
<frontend_type>select</frontend_type>
|
210 |
<source_model>adminhtml/system_config_source_cron_frequency</source_model>
|
211 |
+
<sort_order>20</sort_order>
|
212 |
<show_in_default>1</show_in_default>
|
213 |
</frequency>
|
214 |
+
<day>
|
215 |
+
<label>Day of the week</label>
|
216 |
+
<frontend_type>select</frontend_type>
|
217 |
+
<source_model>emvcore/adminhtml_system_config_source_cronDay</source_model>
|
218 |
+
<sort_order>22</sort_order>
|
219 |
+
<depends><frequency>W</frequency></depends>
|
220 |
+
<show_in_default>1</show_in_default>
|
221 |
+
</day>
|
222 |
+
<date>
|
223 |
+
<label>Date of the month</label>
|
224 |
+
<frontend_type>select</frontend_type>
|
225 |
+
<source_model>emvcore/adminhtml_system_config_source_cronDate</source_model>
|
226 |
+
<sort_order>23</sort_order>
|
227 |
+
<depends><frequency>M</frequency></depends>
|
228 |
+
<show_in_default>1</show_in_default>
|
229 |
+
</date>
|
230 |
+
<time translate="label">
|
231 |
+
<label>Start Time (in Admin timezone)</label>
|
232 |
+
<frontend_type>time</frontend_type>
|
233 |
+
<backend_model>emvdatasync/adminhtml_system_config_backend_clean_cron</backend_model>
|
234 |
+
<sort_order>40</sort_order>
|
235 |
+
<show_in_default>1</show_in_default>
|
236 |
+
</time>
|
237 |
</fields>
|
238 |
</export_file_cleaning>
|
239 |
|
258 |
<frontend_type>text</frontend_type>
|
259 |
<sort_order>70</sort_order>
|
260 |
<show_in_default>1</show_in_default>
|
261 |
+
<show_in_website>1</show_in_website>
|
262 |
+
<show_in_store>1</show_in_store>
|
263 |
<fields>
|
264 |
<get_emailvision_fields translate="label comment">
|
265 |
<label>Field Synchronization</label>
|
268 |
<comment>Connect to SmartFocus apimember webservice and get the list of available fields</comment>
|
269 |
<sort_order>1</sort_order>
|
270 |
<show_in_default>1</show_in_default>
|
271 |
+
<show_in_website>1</show_in_website>
|
272 |
+
<show_in_store>1</show_in_store>
|
273 |
</get_emailvision_fields>
|
274 |
<email_enabled translate="label">
|
275 |
<label>Synchronize with email</label>
|
278 |
<comment>If enabled, Magento newsletter subscribers will be synced by their email address. By default, the SmartFocus Entity Id will be used.</comment>
|
279 |
<sort_order>3</sort_order>
|
280 |
<show_in_default>1</show_in_default>
|
281 |
+
<show_in_website>1</show_in_website>
|
282 |
+
<show_in_store>1</show_in_store>
|
283 |
</email_enabled>
|
284 |
<emailvision_entity_id translate="label comment">
|
285 |
<label>SmartFocus Entity Id</label>
|
288 |
<comment>Default field used to link a Magento newsletter subscriber to a SmartFocus member. CLIENTURN is selected by default.</comment>
|
289 |
<sort_order>5</sort_order>
|
290 |
<show_in_default>1</show_in_default>
|
291 |
+
<show_in_website>1</show_in_website>
|
292 |
+
<show_in_store>1</show_in_store>
|
293 |
</emailvision_entity_id>
|
294 |
<attributes translate="comment">
|
295 |
<label></label>
|
298 |
<backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
|
299 |
<sort_order>10</sort_order>
|
300 |
<show_in_default>1</show_in_default>
|
301 |
+
<show_in_website>1</show_in_website>
|
302 |
+
<show_in_store>1</show_in_store>
|
303 |
</attributes>
|
304 |
</fields>
|
305 |
</customer_mapping>
|
@@ -4,9 +4,9 @@ $this->startSetup();
|
|
4 |
/* @var Varien_Db_Adapter_Pdo_Mysql $connection*/
|
5 |
$connection = $this->getConnection();
|
6 |
|
7 |
-
$connection->addColumn($this->getTable('
|
8 |
-
$connection->addColumn($this->getTable('
|
9 |
-
$connection->addColumn($this->getTable('
|
10 |
|
11 |
$this->endSetup();
|
12 |
?>
|
4 |
/* @var Varien_Db_Adapter_Pdo_Mysql $connection*/
|
5 |
$connection = $this->getConnection();
|
6 |
|
7 |
+
$connection->addColumn($this->getTable('newsletter/subscriber'), 'date_unjoin', 'DATETIME default NULL');
|
8 |
+
$connection->addColumn($this->getTable('newsletter/subscriber'), 'data_last_update_date', 'DATETIME default NULL');
|
9 |
+
$connection->addColumn($this->getTable('newsletter/subscriber'), 'member_last_update_date', 'DATETIME default NULL');
|
10 |
|
11 |
$this->endSetup();
|
12 |
?>
|
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/* @var $installer Emv_Emt_Model_Resource_Setup */
|
3 |
+
$this->startSetup();
|
4 |
+
|
5 |
+
/* @var Varien_Db_Adapter_Pdo_Mysql $connection*/
|
6 |
+
$connection = $this->getConnection();
|
7 |
+
$connection->addColumn($this->getTable('newsletter/subscriber'), 'queued', 'TINYINT(1) default 0');
|
8 |
+
|
9 |
+
$this->run("
|
10 |
+
UPDATE {$this->getTable('newsletter/subscriber')}
|
11 |
+
SET queued = 1
|
12 |
+
WHERE member_last_update_date IS NULL
|
13 |
+
OR (member_last_update_date IS NOT NULL
|
14 |
+
AND (
|
15 |
+
date_unjoin > member_last_update_date OR data_last_update_date > member_last_update_date
|
16 |
+
)
|
17 |
+
)
|
18 |
+
");
|
19 |
+
|
20 |
+
$this->endSetup();
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/* @var $installer Emv_Emt_Model_Resource_Setup */
|
3 |
+
$this->startSetup();
|
4 |
+
|
5 |
+
/* @var Varien_Db_Adapter_Pdo_Mysql $connection*/
|
6 |
+
|
7 |
+
$this->run("
|
8 |
+
DROP TABLE IF EXISTS {$this->getTable('emvdatasync/purchase_info')};
|
9 |
+
CREATE TABLE {$this->getTable('emvdatasync/purchase_info')} (
|
10 |
+
`id` int(11) unsigned NOT NULL auto_increment,
|
11 |
+
`created_at` DATETIME NOT NULL,
|
12 |
+
`updated_at` DATETIME NOT NULL,
|
13 |
+
`base_currency_code` varchar(255) NULL,
|
14 |
+
|
15 |
+
`total_order` INT(4) DEFAULT 0,
|
16 |
+
|
17 |
+
`total_ordered_item_qty` INT(5) DEFAULT 0,
|
18 |
+
`avg_item_qty` INT(5) DEFAULT 0,
|
19 |
+
`order_amount_total` DECIMAL(12,4) DEFAULT 0,
|
20 |
+
`avg_order_amount_total` DECIMAL(12,4) DEFAULT 0,
|
21 |
+
`discount_amount_total` DECIMAL(12,4) DEFAULT 0,
|
22 |
+
`avg_discount_amount_total` DECIMAL(12,4) DEFAULT 0,
|
23 |
+
|
24 |
+
`min_order_amount_total` DECIMAL(12,4) DEFAULT 0,
|
25 |
+
`max_order_amount_total` DECIMAL(12,4) DEFAULT 0,
|
26 |
+
`first_order_date` DATETIME NULL,
|
27 |
+
`last_order_date` DATETIME NULL,
|
28 |
+
`min_total_ordered_item_qty` INT(5) DEFAULT 0,
|
29 |
+
`max_total_ordered_item_qty` INT(5) DEFAULT 0,
|
30 |
+
|
31 |
+
`shipping_amount_total` DECIMAL(12,4) DEFAULT 0,
|
32 |
+
`avg_shipping_amount_total` DECIMAL(12,4) DEFAULT 0,
|
33 |
+
`shipping_list` TEXT NULL,
|
34 |
+
`payment_methods` TEXT NULL,
|
35 |
+
`coupon_list` TEXT NULL,
|
36 |
+
`nb_order_having_discount` INT(4) DEFAULT 0,
|
37 |
+
|
38 |
+
`customer_id` int(9) unsigned NULL,
|
39 |
+
`email` varchar(255) NOT NULL,
|
40 |
+
`order_list` TEXT NULL,
|
41 |
+
|
42 |
+
PRIMARY KEY (`id`),
|
43 |
+
|
44 |
+
INDEX `IDX_PURCHASE_INFO_CUSTOMER_ID` (`customer_id`),
|
45 |
+
INDEX `IDX_PURCHASE_INFO_EMAIL` (`email`)
|
46 |
+
|
47 |
+
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Purchase Information';
|
48 |
+
");
|
49 |
+
|
50 |
+
/* @var Varien_Db_Adapter_Pdo_Mysql $connection*/
|
51 |
+
$connection = $this->getConnection();
|
52 |
+
$connection->addColumn($this->getTable('newsletter/subscriber'), 'date_last_purchase', 'DATETIME default NULL');
|
53 |
+
|
54 |
+
$gmtDate = Mage::getModel('core/date')->gmtDate();
|
55 |
+
$this->run("
|
56 |
+
UPDATE {$this->getTable('newsletter/subscriber')} subscriber
|
57 |
+
JOIN {$this->getTable('sales/order')} flat_order ON subscriber.customer_id = flat_order.customer_id
|
58 |
+
SET date_last_purchase = '$gmtDate';
|
59 |
+
");
|
60 |
+
$this->endSetup();
|
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Extension status block
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Emt
|
7 |
+
* @copyright Copyright (c) 2014 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Emt_Block_Adminhtml_Config_ExtensionStatus
|
11 |
+
extends Emv_Core_Block_Adminhtml_Config_ExtensionStatus
|
12 |
+
{
|
13 |
+
/**
|
14 |
+
* List of call back functions to test
|
15 |
+
* @var array
|
16 |
+
*/
|
17 |
+
protected $_callbackList = array('getEmailTemplateRewriteStatus');
|
18 |
+
|
19 |
+
/**
|
20 |
+
* Check if email template has been correctly rewritten by our module or it's in conflict with another extension
|
21 |
+
*
|
22 |
+
* @return string
|
23 |
+
*/
|
24 |
+
public function getEmailTemplateRewriteStatus()
|
25 |
+
{
|
26 |
+
$classModelName = 'core/email_template';
|
27 |
+
$class = Mage::getModel($classModelName);
|
28 |
+
|
29 |
+
$ok = true;
|
30 |
+
$className = '';
|
31 |
+
if (!$class instanceof Emv_Emt_Model_Mage_Core_Email_Template) {
|
32 |
+
$ok = false;
|
33 |
+
$className = get_class($class);
|
34 |
+
}
|
35 |
+
|
36 |
+
$message = '';
|
37 |
+
if ($ok) {
|
38 |
+
$image = $this->_getTickImageLink();
|
39 |
+
$message = Mage::helper('emvcore')->__(
|
40 |
+
'<span class="icon-status">%s</span> Email Template class (<strong>"%s"</strong>) has been correctly overwritten.',
|
41 |
+
$image,
|
42 |
+
$classModelName
|
43 |
+
);
|
44 |
+
} else {
|
45 |
+
$image = $this->_getUnTickImageLink();
|
46 |
+
$message = Mage::helper('emvcore')->__(
|
47 |
+
'<span class="icon-status">%s</span> Email Template class (<strong>"%s"</strong>) has not been correctly overwritten - in conflict with the following class <strong>%s</strong>.',
|
48 |
+
$image,
|
49 |
+
$classModelName,
|
50 |
+
$className
|
51 |
+
);
|
52 |
+
}
|
53 |
+
return $message;
|
54 |
+
}
|
55 |
+
|
56 |
+
}
|
@@ -9,6 +9,17 @@
|
|
9 |
*/
|
10 |
class Emv_Emt_Block_Adminhtml_Log_Grid extends Mage_Adminhtml_Block_Widget_Grid
|
11 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
/**
|
13 |
* Prepare collection for grid
|
14 |
*
|
@@ -100,7 +111,7 @@ class Emv_Emt_Block_Adminhtml_Log_Grid extends Mage_Adminhtml_Block_Widget_Grid
|
|
100 |
)
|
101 |
);
|
102 |
|
103 |
-
//
|
104 |
$this->addColumn('emv_name',
|
105 |
array(
|
106 |
'header'=> Mage::helper('emvemt')->__('SmartFocus Template'),
|
9 |
*/
|
10 |
class Emv_Emt_Block_Adminhtml_Log_Grid extends Mage_Adminhtml_Block_Widget_Grid
|
11 |
{
|
12 |
+
/**
|
13 |
+
* Constructor
|
14 |
+
*
|
15 |
+
* Set main configuration of grid
|
16 |
+
*/
|
17 |
+
public function __construct()
|
18 |
+
{
|
19 |
+
parent::__construct();
|
20 |
+
$this->setDefaultSort('id', 'desc');
|
21 |
+
}
|
22 |
+
|
23 |
/**
|
24 |
* Prepare collection for grid
|
25 |
*
|
111 |
)
|
112 |
);
|
113 |
|
114 |
+
// SmartFocus Template name
|
115 |
$this->addColumn('emv_name',
|
116 |
array(
|
117 |
'header'=> Mage::helper('emvemt')->__('SmartFocus Template'),
|
@@ -18,6 +18,7 @@ class Emv_Emt_Block_Adminhtml_Resending_Grid extends Mage_Adminhtml_Block_Widget
|
|
18 |
{
|
19 |
$collection = Mage::getResourceModel('emvemt/resending_queue_message_collection');
|
20 |
$this->setCollection($collection);
|
|
|
21 |
|
22 |
parent::_prepareCollection();
|
23 |
}
|
@@ -107,7 +108,7 @@ class Emv_Emt_Block_Adminhtml_Resending_Grid extends Mage_Adminhtml_Block_Widget
|
|
107 |
)
|
108 |
);
|
109 |
|
110 |
-
//
|
111 |
$this->addColumn('emv_name',
|
112 |
array(
|
113 |
'header'=> Mage::helper('emvemt')->__('SmartFocus Template'),
|
18 |
{
|
19 |
$collection = Mage::getResourceModel('emvemt/resending_queue_message_collection');
|
20 |
$this->setCollection($collection);
|
21 |
+
$this->setDefaultSort('id', 'desc');
|
22 |
|
23 |
parent::_prepareCollection();
|
24 |
}
|
108 |
)
|
109 |
);
|
110 |
|
111 |
+
// SmartFocus Template name
|
112 |
$this->addColumn('emv_name',
|
113 |
array(
|
114 |
'header'=> Mage::helper('emvemt')->__('SmartFocus Template'),
|
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Account validation block
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Emt
|
7 |
+
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
|
11 |
+
class Emv_Emt_Block_Adminhtml_System_Config_ValidateAccount
|
12 |
+
extends Mage_Adminhtml_Block_System_Config_Form_Field
|
13 |
+
{
|
14 |
+
/**
|
15 |
+
* Set template to itself
|
16 |
+
*
|
17 |
+
* @return Emv_Emt_Block_Adminhtml_System_Config_ValidateAccount
|
18 |
+
*/
|
19 |
+
protected function _prepareLayout()
|
20 |
+
{
|
21 |
+
parent::_prepareLayout();
|
22 |
+
if (!$this->getTemplate()) {
|
23 |
+
$this->setTemplate('smartfocus/emt/system/config/account_validation.phtml');
|
24 |
+
}
|
25 |
+
return $this;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Get the button and scripts contents
|
30 |
+
*
|
31 |
+
* @param Varien_Data_Form_Element_Abstract $element
|
32 |
+
*
|
33 |
+
* @return string
|
34 |
+
*/
|
35 |
+
protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
|
36 |
+
{
|
37 |
+
return $this->_toHtml();
|
38 |
+
}
|
39 |
+
}
|
@@ -11,7 +11,7 @@ class Emv_Emt_Block_Adminhtml_Template_Edit extends Mage_Adminhtml_Block_Widget
|
|
11 |
{
|
12 |
public function __construct()
|
13 |
{
|
14 |
-
$this->setTemplate('
|
15 |
$this->setId('emv_email_template');
|
16 |
}
|
17 |
|
@@ -27,8 +27,9 @@ class Emv_Emt_Block_Adminhtml_Template_Edit extends Mage_Adminhtml_Block_Widget
|
|
27 |
$head->addItem('js', 'prototype/window.js')
|
28 |
->addItem('js_css', 'prototype/windows/themes/default.css')
|
29 |
->addCss('lib/prototype/windows/themes/magento.css')
|
30 |
-
->addCss('
|
31 |
-
->addItem('js', 'mage/adminhtml/variables.js')
|
|
|
32 |
}
|
33 |
|
34 |
// back button - get back to grid menu
|
11 |
{
|
12 |
public function __construct()
|
13 |
{
|
14 |
+
$this->setTemplate('smartfocus/emt/template/edit.phtml');
|
15 |
$this->setId('emv_email_template');
|
16 |
}
|
17 |
|
27 |
$head->addItem('js', 'prototype/window.js')
|
28 |
->addItem('js_css', 'prototype/windows/themes/default.css')
|
29 |
->addCss('lib/prototype/windows/themes/magento.css')
|
30 |
+
->addCss('smartfocus.css')
|
31 |
+
->addItem('js', 'mage/adminhtml/variables.js')
|
32 |
+
->addItem('js_css', 'prototype/windows/themes/magento.css');
|
33 |
}
|
34 |
|
35 |
// back button - get back to grid menu
|
@@ -52,7 +52,7 @@ class Emv_Emt_Block_Adminhtml_Template_Edit_Tab_EmvDyn extends Mage_Adminhtml_Bl
|
|
52 |
public function __construct()
|
53 |
{
|
54 |
parent::__construct();
|
55 |
-
$this->setTemplate('
|
56 |
}
|
57 |
|
58 |
/**
|
52 |
public function __construct()
|
53 |
{
|
54 |
parent::__construct();
|
55 |
+
$this->setTemplate('smartfocus/emt/template/mapped_attributes.phtml');
|
56 |
}
|
57 |
|
58 |
/**
|
@@ -141,7 +141,7 @@ class Emv_Emt_Block_Adminhtml_Template_Edit_Tab_General extends Mage_Adminhtml_B
|
|
141 |
{
|
142 |
// js block contains all common javascript functions
|
143 |
$jsBlock = $this->getLayout()->createBlock('adminhtml/template');
|
144 |
-
$jsBlock->setData('edit_block', $this)->setTemplate('
|
145 |
$fieldset->addField(
|
146 |
'js_block',
|
147 |
'note',
|
141 |
{
|
142 |
// js block contains all common javascript functions
|
143 |
$jsBlock = $this->getLayout()->createBlock('adminhtml/template');
|
144 |
+
$jsBlock->setData('edit_block', $this)->setTemplate('smartfocus/emt/template/common_js.phtml');
|
145 |
$fieldset->addField(
|
146 |
'js_block',
|
147 |
'note',
|
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_Emt
|
@@ -12,8 +12,8 @@ class Emv_Emt_Helper_Emvtemplate extends Mage_Core_Helper_Abstract
|
|
12 |
/**
|
13 |
* Xml path for different configurations
|
14 |
*/
|
15 |
-
const XML_PATH_LOG_ENABLED
|
16 |
-
const XML_PATH_SENDING_PARAMETER_LOG_ENABLED
|
17 |
|
18 |
/**
|
19 |
* SmartFocus attributes for a current SmartFocus template from registry
|
@@ -111,7 +111,7 @@ class Emv_Emt_Helper_Emvtemplate extends Mage_Core_Helper_Abstract
|
|
111 |
}
|
112 |
|
113 |
/**
|
114 |
-
*
|
115 |
*
|
116 |
* @param string $mageTemplateId
|
117 |
* @param string $accountId
|
@@ -161,7 +161,7 @@ class Emv_Emt_Helper_Emvtemplate extends Mage_Core_Helper_Abstract
|
|
161 |
}
|
162 |
|
163 |
/**
|
164 |
-
* Get
|
165 |
*
|
166 |
* @param string $mageTemplateId
|
167 |
* @param string $accountId
|
@@ -179,13 +179,13 @@ class Emv_Emt_Helper_Emvtemplate extends Mage_Core_Helper_Abstract
|
|
179 |
$magentoEmailTable = $resource->getTableName('core/email_template');
|
180 |
|
181 |
// get SmartFocus sending template
|
182 |
-
$
|
183 |
. Emv_Emt_Model_Emt::MAGENTO_TEMPLATE_ID_FOR_EMV_SEND . '"'
|
184 |
. ' AND tmp_sending.emv_send_mail_mode_id = ' . Emv_Emt_Model_Mailmode::EMV_CREATE
|
185 |
;
|
186 |
$select->joinLeft(
|
187 |
array('tmp_sending' => $emtTable),
|
188 |
-
$
|
189 |
array(
|
190 |
'sending_template.emv_template_id' => 'tmp_sending.emv_template_id',
|
191 |
'sending_template.emv_parameters' => 'tmp_sending.emv_parameters',
|
@@ -360,7 +360,10 @@ class Emv_Emt_Helper_Emvtemplate extends Mage_Core_Helper_Abstract
|
|
360 |
}
|
361 |
|
362 |
/**
|
|
|
|
|
363 |
* @param Emv_Core_Model_Account $account
|
|
|
364 |
*/
|
365 |
public function checkAndCreateDefaultSendingTemplate(Emv_Core_Model_Account $account)
|
366 |
{
|
@@ -370,11 +373,39 @@ class Emv_Emt_Helper_Emvtemplate extends Mage_Core_Helper_Abstract
|
|
370 |
$existingDefault = $this->getEmvEmt(Emv_Emt_Model_Emt::MAGENTO_TEMPLATE_ID_FOR_EMV_SEND, $account->getId());
|
371 |
$needToCreate = false;
|
372 |
if ($existingDefault && $existingDefault->getId()) {
|
373 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
374 |
$needToCreate = true;
|
375 |
$defaultEmt->setId($existingDefault->getId());
|
376 |
} else {
|
377 |
$defaultEmt = $existingDefault;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
378 |
}
|
379 |
} else {
|
380 |
$needToCreate = true;
|
@@ -499,4 +530,43 @@ class Emv_Emt_Helper_Emvtemplate extends Mage_Core_Helper_Abstract
|
|
499 |
|
500 |
return $this->_sortedMappedAttributes;
|
501 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
502 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* SmartFocus Email template Helper
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_Emt
|
12 |
/**
|
13 |
* Xml path for different configurations
|
14 |
*/
|
15 |
+
const XML_PATH_LOG_ENABLED = 'emvemt/transactional_service/log_enabled';
|
16 |
+
const XML_PATH_SENDING_PARAMETER_LOG_ENABLED = 'emvemt/transactional_service/parameter_log_enabled';
|
17 |
|
18 |
/**
|
19 |
* SmartFocus attributes for a current SmartFocus template from registry
|
111 |
}
|
112 |
|
113 |
/**
|
114 |
+
* Prepare and get data necessary for email sending
|
115 |
*
|
116 |
* @param string $mageTemplateId
|
117 |
* @param string $accountId
|
161 |
}
|
162 |
|
163 |
/**
|
164 |
+
* Get all objects useful for email sending
|
165 |
*
|
166 |
* @param string $mageTemplateId
|
167 |
* @param string $accountId
|
179 |
$magentoEmailTable = $resource->getTableName('core/email_template');
|
180 |
|
181 |
// get SmartFocus sending template
|
182 |
+
$condition = 'tmp_sending.emv_account_id = main_table.emv_account_id AND tmp_sending.mage_template_id = "'
|
183 |
. Emv_Emt_Model_Emt::MAGENTO_TEMPLATE_ID_FOR_EMV_SEND . '"'
|
184 |
. ' AND tmp_sending.emv_send_mail_mode_id = ' . Emv_Emt_Model_Mailmode::EMV_CREATE
|
185 |
;
|
186 |
$select->joinLeft(
|
187 |
array('tmp_sending' => $emtTable),
|
188 |
+
$condition,
|
189 |
array(
|
190 |
'sending_template.emv_template_id' => 'tmp_sending.emv_template_id',
|
191 |
'sending_template.emv_parameters' => 'tmp_sending.emv_parameters',
|
360 |
}
|
361 |
|
362 |
/**
|
363 |
+
* Check and create default sending template if necessary
|
364 |
+
*
|
365 |
* @param Emv_Core_Model_Account $account
|
366 |
+
* @return Emv_Emt_Model_Emt
|
367 |
*/
|
368 |
public function checkAndCreateDefaultSendingTemplate(Emv_Core_Model_Account $account)
|
369 |
{
|
373 |
$existingDefault = $this->getEmvEmt(Emv_Emt_Model_Emt::MAGENTO_TEMPLATE_ID_FOR_EMV_SEND, $account->getId());
|
374 |
$needToCreate = false;
|
375 |
if ($existingDefault && $existingDefault->getId()) {
|
376 |
+
$emvTemplate = false;
|
377 |
+
try {
|
378 |
+
$emvTemplate = $existingDefault->getEmvTemplate();
|
379 |
+
} catch(Mage_Core_Exception $e) {
|
380 |
+
// ignore Exception, if template does not exist anymore, create a new one
|
381 |
+
}
|
382 |
+
|
383 |
+
if (!$emvTemplate) {
|
384 |
$needToCreate = true;
|
385 |
$defaultEmt->setId($existingDefault->getId());
|
386 |
} else {
|
387 |
$defaultEmt = $existingDefault;
|
388 |
+
|
389 |
+
// try to get all template parameters
|
390 |
+
$savedEmvParams = $existingDefault->getEmailVisionParams();
|
391 |
+
$newParms = $existingDefault->getEmailVisionParams($emvTemplate);
|
392 |
+
|
393 |
+
// if the template parameters are different, need to recreate the template
|
394 |
+
if (
|
395 |
+
!is_array($savedEmvParams)
|
396 |
+
|| !is_array($newParms)
|
397 |
+
|| count($savedEmvParams) != count($newParms)
|
398 |
+
) {
|
399 |
+
$needToCreate = true;
|
400 |
+
} else {
|
401 |
+
$checkingParam = array('emv_id','emv_random', 'emv_encrypt', 'emv_name');
|
402 |
+
foreach ($checkingParam as $paramName) {
|
403 |
+
if (!isset($newParms[$paramName]) || $newParms[$paramName] !== $savedEmvParams[$paramName]) {
|
404 |
+
$needToCreate = true;
|
405 |
+
break;
|
406 |
+
}
|
407 |
+
}
|
408 |
+
}
|
409 |
}
|
410 |
} else {
|
411 |
$needToCreate = true;
|
530 |
|
531 |
return $this->_sortedMappedAttributes;
|
532 |
}
|
533 |
+
|
534 |
+
/**
|
535 |
+
* Validate SmartFocus account with given account id
|
536 |
+
*
|
537 |
+
* @param string $accountId
|
538 |
+
* @throws Mage_Core_Exception if something is missing or not correctly defined
|
539 |
+
* @return boolean
|
540 |
+
*/
|
541 |
+
public function validateEmvAccount($accountId)
|
542 |
+
{
|
543 |
+
$account = Mage::getModel('emvcore/account')->load($accountId);
|
544 |
+
if (!$account->getId()) {
|
545 |
+
Mage::throwException(Mage::helper('emvcore')->__('Your selected account does not exist anymore!'));
|
546 |
+
}
|
547 |
+
|
548 |
+
// check url
|
549 |
+
$url = Mage::helper('emvcore')
|
550 |
+
->checkAndGetUrlForType($account, Emv_Core_Model_Account::URL_TRANSACTIONAL_SERVICE_TYPE);
|
551 |
+
|
552 |
+
try {
|
553 |
+
// check credentials
|
554 |
+
$this->checkAndCreateDefaultSendingTemplate($account);
|
555 |
+
} catch (EmailVision_Api_Exception $e) {
|
556 |
+
if ($e->isRecoverable()) {
|
557 |
+
Mage::throwException(
|
558 |
+
Mage::helper('emvcore')
|
559 |
+
->__('Could not verify the selected account. Network problems occured!')
|
560 |
+
);
|
561 |
+
} else {
|
562 |
+
Mage::throwException($e->getMessage());
|
563 |
+
}
|
564 |
+
}
|
565 |
+
|
566 |
+
Mage::helper('emvcore')
|
567 |
+
->checkAndGetUrlForType($account, Emv_Core_Model_Account::URL_REST_NOTIFICATION_SERVICE_TYPE);
|
568 |
+
|
569 |
+
// every thing is ok, so return true
|
570 |
+
return true;
|
571 |
+
}
|
572 |
}
|
@@ -29,29 +29,7 @@ class Emv_Emt_Model_Adminhtml_System_Config_Backend_Account extends Emv_Core_Mod
|
|
29 |
protected function _beforeSave()
|
30 |
{
|
31 |
if ($this->isValueChanged() && $this->getValue()) {
|
32 |
-
$
|
33 |
-
if (!$account->getId()) {
|
34 |
-
Mage::throwException(Mage::helper('emvcore')->__('Your selected account does not exist anymore!'));
|
35 |
-
}
|
36 |
-
|
37 |
-
// check url
|
38 |
-
$url = $this->_checkAndGetUrlForType($account, $this->_urlType);
|
39 |
-
|
40 |
-
try {
|
41 |
-
// check credentials
|
42 |
-
Mage::helper('emvemt/emvtemplate')->checkAndCreateDefaultSendingTemplate($account);
|
43 |
-
} catch (EmailVision_Api_Exception $e) {
|
44 |
-
if ($e->isRecoverable()) {
|
45 |
-
Mage::throwException(
|
46 |
-
Mage::helper('emvcore')
|
47 |
-
->__('Could not verify the account. Network problems occured! Please Save again!')
|
48 |
-
);
|
49 |
-
} else {
|
50 |
-
Mage::throwException($e->getMessage());
|
51 |
-
}
|
52 |
-
}
|
53 |
-
|
54 |
-
$this->_checkAndGetUrlForType($account, Emv_Core_Model_Account::URL_REST_NOTIFICATION_SERVICE_TYPE);
|
55 |
}
|
56 |
|
57 |
return Mage_Core_Model_Abstract::_beforeSave();
|
29 |
protected function _beforeSave()
|
30 |
{
|
31 |
if ($this->isValueChanged() && $this->getValue()) {
|
32 |
+
Mage::helper('emvemt/emvtemplate')->validateEmvAccount($this->getValue());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
33 |
}
|
34 |
|
35 |
return Mage_Core_Model_Abstract::_beforeSave();
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Log Cron Backend Model
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Emt
|
7 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
8 |
+
*/
|
9 |
+
class Emv_Emt_Model_Adminhtml_System_Config_Backend_Log_Cron extends Emv_Core_Model_Adminhtml_System_Config_Backend_Cron
|
10 |
+
{
|
11 |
+
protected $_crontabPath = 'crontab/jobs/emailvision_process_sending_log_cleanning/schedule/cron_expr';
|
12 |
+
}
|
@@ -1,6 +1,6 @@
|
|
1 |
<?php
|
2 |
/**
|
3 |
-
*
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_Emt
|
@@ -9,6 +9,32 @@
|
|
9 |
*/
|
10 |
class Emv_Emt_Model_Cron
|
11 |
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
/**
|
13 |
* Process all error sending emails
|
14 |
* - convert all error sending emails into rescheduled queue messages
|
@@ -23,6 +49,9 @@ class Emv_Emt_Model_Cron
|
|
23 |
return;
|
24 |
}
|
25 |
|
|
|
|
|
|
|
26 |
// create lock file, in order to prevent from launching several process at the same time
|
27 |
$rule->createLock();
|
28 |
|
@@ -33,7 +62,22 @@ class Emv_Emt_Model_Cron
|
|
33 |
Mage::logException($e);
|
34 |
}
|
35 |
|
|
|
|
|
36 |
// remove lock file
|
37 |
$rule->removeLock();
|
38 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
}
|
1 |
<?php
|
2 |
/**
|
3 |
+
* SmartFocus emt cron model
|
4 |
*
|
5 |
* @category Emv
|
6 |
* @package Emv_Emt
|
9 |
*/
|
10 |
class Emv_Emt_Model_Cron
|
11 |
{
|
12 |
+
/**
|
13 |
+
* Xml path for log cleanning mechanism
|
14 |
+
*/
|
15 |
+
const XML_PATH_LOG_CLEAN_ENABLED = 'emvemt/log_cleanning/enabled';
|
16 |
+
const XML_PATH_LOG_CLEAN_NUMBER_LAST_DAY = 'emvemt/log_cleanning/keeping_days';
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Is log cleanning mechanism activated ?
|
20 |
+
*
|
21 |
+
* @return boolean
|
22 |
+
*/
|
23 |
+
public function isLogCleanningEnabled()
|
24 |
+
{
|
25 |
+
return (bool)Mage::getStoreConfig(self::XML_PATH_LOG_CLEAN_ENABLED);
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Get number of days to keep
|
30 |
+
*
|
31 |
+
* @return int
|
32 |
+
*/
|
33 |
+
public function getNumberDaysToKeep()
|
34 |
+
{
|
35 |
+
return (int)Mage::getStoreConfig(self::XML_PATH_LOG_CLEAN_NUMBER_LAST_DAY);
|
36 |
+
}
|
37 |
+
|
38 |
/**
|
39 |
* Process all error sending emails
|
40 |
* - convert all error sending emails into rescheduled queue messages
|
49 |
return;
|
50 |
}
|
51 |
|
52 |
+
// !!! it's very important to set SmartFocus custom error handler in order to remove lock file in case of fatal error
|
53 |
+
Mage::helper('emvcore')->setSmartFocusErrorHandler();
|
54 |
+
|
55 |
// create lock file, in order to prevent from launching several process at the same time
|
56 |
$rule->createLock();
|
57 |
|
62 |
Mage::logException($e);
|
63 |
}
|
64 |
|
65 |
+
// reset error handler to Magento one
|
66 |
+
Mage::helper('emvcore')->resetErrorHandler();
|
67 |
// remove lock file
|
68 |
$rule->removeLock();
|
69 |
}
|
70 |
+
|
71 |
+
/**
|
72 |
+
* Clean sending logs
|
73 |
+
*/
|
74 |
+
public function cleanLogs()
|
75 |
+
{
|
76 |
+
if (!$this->isLogCleanningEnabled()) {
|
77 |
+
return false;
|
78 |
+
}
|
79 |
+
|
80 |
+
$timeLimit = $this->getNumberDaysToKeep() * 60 * 60 * 24;
|
81 |
+
Mage::getModel('emvemt/log')->cleanLogs($timeLimit);
|
82 |
+
}
|
83 |
}
|
@@ -55,7 +55,7 @@ class Emv_Emt_Model_Emt extends Mage_Core_Model_Abstract
|
|
55 |
{
|
56 |
$this->_emailVisionParams = array();
|
57 |
|
58 |
-
//reset emt template if user switch mail mode from '
|
59 |
if (
|
60 |
$this->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::CLASSIC_MODE
|
61 |
|| $this->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::EMV_SEND
|
55 |
{
|
56 |
$this->_emailVisionParams = array();
|
57 |
|
58 |
+
//reset emt template if user switch mail mode from 'SmartFocus Template' to 'SmartFocus Routage' or 'Classic'
|
59 |
if (
|
60 |
$this->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::CLASSIC_MODE
|
61 |
|| $this->getEmvSendMailModeId() == Emv_Emt_Model_Mailmode::EMV_SEND
|
@@ -19,7 +19,6 @@ class Emv_Emt_Model_Log extends Mage_Core_Model_Abstract
|
|
19 |
* Constant for resending workflow
|
20 |
*/
|
21 |
const RESENDING_WORKFLOW = 'resending';
|
22 |
-
|
23 |
const RESCHEDULED = 1;
|
24 |
|
25 |
/**
|
@@ -148,4 +147,15 @@ class Emv_Emt_Model_Log extends Mage_Core_Model_Abstract
|
|
148 |
=> Mage::helper('emvemt')->__('Invalid SmartFocus Parameters')
|
149 |
);
|
150 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
151 |
}
|
19 |
* Constant for resending workflow
|
20 |
*/
|
21 |
const RESENDING_WORKFLOW = 'resending';
|
|
|
22 |
const RESCHEDULED = 1;
|
23 |
|
24 |
/**
|
147 |
=> Mage::helper('emvemt')->__('Invalid SmartFocus Parameters')
|
148 |
);
|
149 |
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Clean logs created before a time limit
|
153 |
+
* @param int $timeLimit
|
154 |
+
* @return Emv_Emt_Model_Log
|
155 |
+
*/
|
156 |
+
public function cleanLogs($timeLimit)
|
157 |
+
{
|
158 |
+
$this->getResource()->cleanLogs($timeLimit);
|
159 |
+
return $this;
|
160 |
+
}
|
161 |
}
|
@@ -39,9 +39,9 @@ class Emv_Emt_Model_Mailmode extends Mage_Core_Model_Abstract
|
|
39 |
public static function getMailModesAndLabels()
|
40 |
{
|
41 |
return array(
|
42 |
-
self::CLASSIC_MODE => Mage::helper('emvemt')->__('
|
43 |
-
self::EMV_CREATE => Mage::helper('emvemt')->__('
|
44 |
-
self::EMV_SEND => Mage::helper('emvemt')->__('
|
45 |
);
|
46 |
}
|
47 |
|
39 |
public static function getMailModesAndLabels()
|
40 |
{
|
41 |
return array(
|
42 |
+
self::CLASSIC_MODE => Mage::helper('emvemt')->__('Classic'),
|
43 |
+
self::EMV_CREATE => Mage::helper('emvemt')->__('SmartFocus Template'),
|
44 |
+
self::EMV_SEND => Mage::helper('emvemt')->__('SmartFocus Routage'),
|
45 |
);
|
46 |
}
|
47 |
|
@@ -9,8 +9,61 @@
|
|
9 |
*/
|
10 |
class Emv_Emt_Model_Mysql4_Log extends Mage_Core_Model_Mysql4_Abstract
|
11 |
{
|
|
|
|
|
|
|
12 |
protected function _construct()
|
13 |
{
|
14 |
$this->_init('emvemt/log', 'id');
|
15 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
}
|
9 |
*/
|
10 |
class Emv_Emt_Model_Mysql4_Log extends Mage_Core_Model_Mysql4_Abstract
|
11 |
{
|
12 |
+
/* (non-PHPdoc)
|
13 |
+
* @see Mage_Core_Model_Resource_Abstract::_construct()
|
14 |
+
*/
|
15 |
protected function _construct()
|
16 |
{
|
17 |
$this->_init('emvemt/log', 'id');
|
18 |
}
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Clean logs before the time limit
|
22 |
+
*
|
23 |
+
* @param int $timeLimit
|
24 |
+
* @return Emv_Emt_Model_Mysql4_Log
|
25 |
+
*/
|
26 |
+
public function cleanLogs($timeLimit)
|
27 |
+
{
|
28 |
+
$writeAdapter = $this->_getWriteAdapter();
|
29 |
+
|
30 |
+
$cleaningTimstamp = Mage::getModel('core/date')->gmtTimestamp() - $timeLimit;
|
31 |
+
$cleaningTimstamp = Varien_Date::formatDate($cleaningTimstamp, true);
|
32 |
+
|
33 |
+
$condition = array('created_at < ?' => $cleaningTimstamp);
|
34 |
+
// clean sending logs
|
35 |
+
$writeAdapter->delete($this->getMainTable(), $condition);
|
36 |
+
// clean resending queue
|
37 |
+
$writeAdapter->delete($this->getTable('emvemt/resending_queue_message'), $condition);
|
38 |
+
return $this;
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Get total number of logs
|
43 |
+
*
|
44 |
+
* @return int
|
45 |
+
*/
|
46 |
+
public function getNbTotal()
|
47 |
+
{
|
48 |
+
$select = $this->_getReadAdapter()->select();
|
49 |
+
$select->from($this->getMainTable())->columns('COUNT(*)');
|
50 |
+
return $this->_getReadAdapter()->fetchCol($select);
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Delete logs
|
55 |
+
*
|
56 |
+
* @param array $logIds
|
57 |
+
* @return Emv_Emt_Model_Mysql4_Log
|
58 |
+
*/
|
59 |
+
public function deleteLogs(array $logIds)
|
60 |
+
{
|
61 |
+
if (count($logIds)) {
|
62 |
+
$condition = array('id IN (?)' => $logIds);
|
63 |
+
|
64 |
+
$writeAdapter = $this->_getWriteAdapter();
|
65 |
+
$writeAdapter->delete($this->getMainTable(), $condition);
|
66 |
+
}
|
67 |
+
return $this;
|
68 |
+
}
|
69 |
}
|
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Observer class
|
4 |
+
*
|
5 |
+
* @category Emv
|
6 |
+
* @package Emv_Emt
|
7 |
+
* @copyright Copyright (c) 2013 SmartFocus (http://www.smartfocus.com)
|
8 |
+
* @author Minh Quang VO <minhquang.vo@smartfocus.com>
|
9 |
+
*/
|
10 |
+
class Emv_Emt_Model_Observer
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Observer on SmartFocus account delete event. Delete temporary email template when deleting SmartFocus account
|
14 |
+
* @param Varien_Event_Observer $observer
|
15 |
+
*/
|
16 |
+
public function onAccountDelete(Varien_Event_Observer $observer)
|
17 |
+
{
|
18 |
+
// if we find an emv account
|
19 |
+
if ($observer->getEmvAccount()) {
|
20 |
+
// check if this account has an temporary email template
|
21 |
+
$existingDefault = Mage::helper('emvemt/emvtemplate')->
|
22 |
+
getEmvEmt(Emv_Emt_Model_Emt::MAGENTO_TEMPLATE_ID_FOR_EMV_SEND, $observer->getEmvAccount()->getId());
|
23 |
+
if ($existingDefault && $existingDefault->getId()) {
|
24 |
+
$existingDefault->delete();
|
25 |
+
}
|
26 |
+
}
|
27 |
+
}
|
28 |
+
}
|
@@ -24,7 +24,7 @@ class Emv_Emt_Model_Resending_Rule extends Mage_Core_Model_Abstract
|
|
24 |
/**
|
25 |
* Lock file name pattern
|
26 |
*/
|
27 |
-
const LOCK_FILE_NAME_PATTERN
|
28 |
|
29 |
/**
|
30 |
* Is resending mechanism activated ?
|
24 |
/**
|
25 |
* Lock file name pattern
|
26 |
*/
|
27 |
+
const LOCK_FILE_NAME_PATTERN = 'resending_error_email_process';
|
28 |
|
29 |
/**
|
30 |
* Is resending mechanism activated ?
|
@@ -713,4 +713,27 @@ class Emv_Emt_Adminhtml_TemplateController extends Mage_Adminhtml_Controller_Act
|
|
713 |
echo $preview;
|
714 |
}
|
715 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
716 |
}
|
713 |
echo $preview;
|
714 |
}
|
715 |
|
716 |
+
/**
|
717 |
+
* Action to validate SmartFocus account
|
718 |
+
*/
|
719 |
+
public function validateTemplateAction()
|
720 |
+
{
|
721 |
+
$accountId = $this->getRequest()->getParam('account_id');
|
722 |
+
$messageReturn = array('error' => array(), 'information' => array());
|
723 |
+
|
724 |
+
if ($accountId) {
|
725 |
+
try {
|
726 |
+
Mage::helper('emvemt/emvtemplate')->validateEmvAccount($accountId);
|
727 |
+
$messageReturn['information'][] = Mage::helper('emvemt')
|
728 |
+
->__('Your account is correctly set up and ready to send emails');
|
729 |
+
} catch (Exception $e) {
|
730 |
+
$messageReturn['error'][] = $e->getMessage();
|
731 |
+
}
|
732 |
+
} else {
|
733 |
+
$messageReturn['error'][] = Mage::helper('emvemt')
|
734 |
+
->__('Please select a SmartFocus account !');
|
735 |
+
}
|
736 |
+
|
737 |
+
$this->getResponse()->setBody(Mage::helper('core')->jsonEncode($messageReturn));
|
738 |
+
}
|
739 |
}
|
@@ -5,6 +5,7 @@
|
|
5 |
<version>0.4.1</version>
|
6 |
</Emv_Emt>
|
7 |
</modules>
|
|
|
8 |
<global>
|
9 |
<blocks>
|
10 |
<emvemt>
|
@@ -47,6 +48,8 @@
|
|
47 |
</entities>
|
48 |
</emvemt_mysql4>
|
49 |
</models>
|
|
|
|
|
50 |
<resources>
|
51 |
<emvemt_setup>
|
52 |
<setup>
|
@@ -55,7 +58,21 @@
|
|
55 |
</setup>
|
56 |
</emvemt_setup>
|
57 |
</resources>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
</global>
|
|
|
59 |
<adminhtml>
|
60 |
<translate>
|
61 |
<modules>
|
@@ -67,6 +84,7 @@
|
|
67 |
</modules>
|
68 |
</translate>
|
69 |
</adminhtml>
|
|
|
70 |
<admin>
|
71 |
<routers>
|
72 |
<emvemt>
|
@@ -78,6 +96,7 @@
|
|
78 |
</emvemt>
|
79 |
</routers>
|
80 |
</admin>
|
|
|
81 |
<crontab>
|
82 |
<jobs>
|
83 |
<emailvision_process_error_sending_emails>
|
@@ -88,6 +107,11 @@
|
|
88 |
<model>emvemt/cron::processErrorSendingEmails</model>
|
89 |
</run>
|
90 |
</emailvision_process_error_sending_emails>
|
|
|
|
|
|
|
|
|
|
|
91 |
</jobs>
|
92 |
</crontab>
|
93 |
<default>
|
@@ -99,6 +123,12 @@
|
|
99 |
<third_delay>120</third_delay>
|
100 |
<fourth_delay>240</fourth_delay>
|
101 |
</resending_mechanism>
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
</emvemt>
|
103 |
</default>
|
104 |
</config>
|
5 |
<version>0.4.1</version>
|
6 |
</Emv_Emt>
|
7 |
</modules>
|
8 |
+
|
9 |
<global>
|
10 |
<blocks>
|
11 |
<emvemt>
|
48 |
</entities>
|
49 |
</emvemt_mysql4>
|
50 |
</models>
|
51 |
+
|
52 |
+
<!-- Resource Defintion -->
|
53 |
<resources>
|
54 |
<emvemt_setup>
|
55 |
<setup>
|
58 |
</setup>
|
59 |
</emvemt_setup>
|
60 |
</resources>
|
61 |
+
|
62 |
+
<!-- Event observers -->
|
63 |
+
<events>
|
64 |
+
<emv_account_delete_after>
|
65 |
+
<observers>
|
66 |
+
<emailvision_on_account_delete>
|
67 |
+
<type>singleton</type>
|
68 |
+
<class>emvemt/observer</class>
|
69 |
+
<method>onAccountDelete</method>
|
70 |
+
</emailvision_on_account_delete>
|
71 |
+
</observers>
|
72 |
+
</emv_account_delete_after>
|
73 |
+
</events>
|
74 |
</global>
|
75 |
+
|
76 |
<adminhtml>
|
77 |
<translate>
|
78 |
<modules>
|
84 |
</modules>
|
85 |
</translate>
|
86 |
</adminhtml>
|
87 |
+
|
88 |
<admin>
|
89 |
<routers>
|
90 |
<emvemt>
|
96 |
</emvemt>
|
97 |
</routers>
|
98 |
</admin>
|
99 |
+
|
100 |
<crontab>
|
101 |
<jobs>
|
102 |
<emailvision_process_error_sending_emails>
|
107 |
<model>emvemt/cron::processErrorSendingEmails</model>
|
108 |
</run>
|
109 |
</emailvision_process_error_sending_emails>
|
110 |
+
<emailvision_process_sending_log_cleanning>
|
111 |
+
<run>
|
112 |
+
<model>emvemt/cron::cleanLogs</model>
|
113 |
+
</run>
|
114 |
+
</emailvision_process_sending_log_cleanning>
|
115 |
</jobs>
|
116 |
</crontab>
|
117 |
<default>
|
123 |
<third_delay>120</third_delay>
|
124 |
<fourth_delay>240</fourth_delay>
|
125 |
</resending_mechanism>
|
126 |
+
<log_cleanning>
|
127 |
+
<enabled>0</enabled>
|
128 |
+
<time/>
|
129 |
+
<frequency>D</frequency>
|
130 |
+
<keeping_days>30</keeping_days>
|
131 |
+
</log_cleanning>
|
132 |
</emvemt>
|
133 |
</default>
|
134 |
</config>
|
@@ -9,11 +9,20 @@
|
|
9 |
<show_in_website>1</show_in_website>
|
10 |
<show_in_store>1</show_in_store>
|
11 |
<groups>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
<transactional_service translate="label" module="emvemt">
|
13 |
<label>General</label>
|
14 |
<expanded>1</expanded>
|
15 |
<frontend_type>text</frontend_type>
|
16 |
-
<sort_order>
|
17 |
<show_in_default>1</show_in_default>
|
18 |
<show_in_website>1</show_in_website>
|
19 |
<show_in_store>1</show_in_store>
|
@@ -21,13 +30,20 @@
|
|
21 |
<account translate="label">
|
22 |
<label>SmartFocus Account</label>
|
23 |
<frontend_type>select</frontend_type>
|
24 |
-
<source_model>emvcore/
|
25 |
<backend_model>emvemt/adminhtml_system_config_backend_account</backend_model>
|
26 |
<sort_order>0</sort_order>
|
27 |
<show_in_default>1</show_in_default>
|
28 |
<show_in_website>1</show_in_website>
|
29 |
<show_in_store>1</show_in_store>
|
30 |
</account>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
31 |
<log_enabled translate="label" module="emvemt">
|
32 |
<label>Activate Sending Log</label>
|
33 |
<frontend_type>select</frontend_type>
|
@@ -50,6 +66,7 @@
|
|
50 |
</parameter_log_enabled>
|
51 |
</fields>
|
52 |
</transactional_service>
|
|
|
53 |
<resending_mechanism translate="label" module="emvemt">
|
54 |
<label>Resending Mechanism Configuration</label>
|
55 |
<expanded>1</expanded>
|
@@ -89,8 +106,64 @@
|
|
89 |
</fourth_delay>
|
90 |
</fields>
|
91 |
</resending_mechanism>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
</groups>
|
93 |
</emvemt>
|
94 |
</sections>
|
95 |
-
</config>
|
96 |
-
|
9 |
<show_in_website>1</show_in_website>
|
10 |
<show_in_store>1</show_in_store>
|
11 |
<groups>
|
12 |
+
<extension_status translate="label">
|
13 |
+
<label>Plugin Status</label>
|
14 |
+
<frontend_model>emvemt/adminhtml_config_extensionStatus</frontend_model>
|
15 |
+
<sort_order>1</sort_order>
|
16 |
+
<frontend_type>text</frontend_type>
|
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 |
+
</extension_status>
|
21 |
<transactional_service translate="label" module="emvemt">
|
22 |
<label>General</label>
|
23 |
<expanded>1</expanded>
|
24 |
<frontend_type>text</frontend_type>
|
25 |
+
<sort_order>10</sort_order>
|
26 |
<show_in_default>1</show_in_default>
|
27 |
<show_in_website>1</show_in_website>
|
28 |
<show_in_store>1</show_in_store>
|
30 |
<account translate="label">
|
31 |
<label>SmartFocus Account</label>
|
32 |
<frontend_type>select</frontend_type>
|
33 |
+
<source_model>emvcore/adminhtml_system_config_source_account</source_model>
|
34 |
<backend_model>emvemt/adminhtml_system_config_backend_account</backend_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 |
</account>
|
40 |
+
<validate_account translate="label">
|
41 |
+
<frontend_model>emvemt/adminhtml_system_config_validateAccount</frontend_model>
|
42 |
+
<sort_order>10</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 |
+
</validate_account>
|
47 |
<log_enabled translate="label" module="emvemt">
|
48 |
<label>Activate Sending Log</label>
|
49 |
<frontend_type>select</frontend_type>
|
66 |
</parameter_log_enabled>
|
67 |
</fields>
|
68 |
</transactional_service>
|
69 |
+
|
70 |
<resending_mechanism translate="label" module="emvemt">
|
71 |
<label>Resending Mechanism Configuration</label>
|
72 |
<expanded>1</expanded>
|
106 |
</fourth_delay>
|
107 |
</fields>
|
108 |
</resending_mechanism>
|
109 |
+
|
110 |
+
<log_cleanning translate="label" module="emvemt">
|
111 |
+
<label>Log Cleanning Configuration</label>
|
112 |
+
<expanded>1</expanded>
|
113 |
+
<sort_order>40</sort_order>
|
114 |
+
<show_in_default>1</show_in_default>
|
115 |
+
<fields>
|
116 |
+
<keeping_days translate="label" module="emvemt">
|
117 |
+
<label>Limit logging days</label>
|
118 |
+
<frontend_type>text</frontend_type>
|
119 |
+
<comment>How many days will sending logs be kept ?</comment>
|
120 |
+
<sort_order>20</sort_order>
|
121 |
+
<show_in_default>1</show_in_default>
|
122 |
+
</keeping_days>
|
123 |
+
<enabled translate="label" module="emvemt">
|
124 |
+
<label>Activate Log Cleanning Mechanism</label>
|
125 |
+
<frontend_type>select</frontend_type>
|
126 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
127 |
+
<sort_order>50</sort_order>
|
128 |
+
<show_in_default>1</show_in_default>
|
129 |
+
</enabled>
|
130 |
+
<frequency translate="label">
|
131 |
+
<label>Frequency</label>
|
132 |
+
<frontend_type>select</frontend_type>
|
133 |
+
<source_model>adminhtml/system_config_source_cron_frequency</source_model>
|
134 |
+
<backend_model>emvemt/adminhtml_system_config_backend_log_cron</backend_model>
|
135 |
+
<sort_order>60</sort_order>
|
136 |
+
<show_in_default>1</show_in_default>
|
137 |
+
<show_in_website>0</show_in_website>
|
138 |
+
<show_in_store>0</show_in_store>
|
139 |
+
</frequency>
|
140 |
+
<day>
|
141 |
+
<label>Day of the week</label>
|
142 |
+
<frontend_type>select</frontend_type>
|
143 |
+
<source_model>emvcore/adminhtml_system_config_source_cronDay</source_model>
|
144 |
+
<sort_order>65</sort_order>
|
145 |
+
<depends><frequency>W</frequency></depends>
|
146 |
+
<show_in_default>1</show_in_default>
|
147 |
+
</day>
|
148 |
+
<date>
|
149 |
+
<label>Date of the month</label>
|
150 |
+
<frontend_type>select</frontend_type>
|
151 |
+
<source_model>emvcore/adminhtml_system_config_source_cronDate</source_model>
|
152 |
+
<sort_order>70</sort_order>
|
153 |
+
<depends><frequency>M</frequency></depends>
|
154 |
+
<show_in_default>1</show_in_default>
|
155 |
+
</date>
|
156 |
+
<time translate="label">
|
157 |
+
<label>Start Time</label>
|
158 |
+
<frontend_type>time</frontend_type>
|
159 |
+
<sort_order>90</sort_order>
|
160 |
+
<show_in_default>1</show_in_default>
|
161 |
+
<show_in_website>0</show_in_website>
|
162 |
+
<show_in_store>0</show_in_store>
|
163 |
+
</time>
|
164 |
+
</fields>
|
165 |
+
</log_cleanning>
|
166 |
</groups>
|
167 |
</emvemt>
|
168 |
</sections>
|
169 |
+
</config>
|
|
@@ -200,6 +200,6 @@ class Emv_Report_Adminhtml_ConversionController extends Mage_Adminhtml_Controlle
|
|
200 |
*/
|
201 |
protected function _isAllowed()
|
202 |
{
|
203 |
-
return Mage::getSingleton('admin/session')->isAllowed('emailvision/abandonment');
|
204 |
}
|
205 |
}
|
200 |
*/
|
201 |
protected function _isAllowed()
|
202 |
{
|
203 |
+
return Mage::getSingleton('admin/session')->isAllowed('emailvision/abandonment/conversion');
|
204 |
}
|
205 |
}
|
@@ -3,9 +3,14 @@
|
|
3 |
<menu>
|
4 |
<emailvision>
|
5 |
<children>
|
6 |
-
<abandonment
|
7 |
-
<
|
8 |
-
|
|
|
|
|
|
|
|
|
|
|
9 |
</abandonment>
|
10 |
</children>
|
11 |
</emailvision>
|
@@ -14,10 +19,15 @@
|
|
14 |
<resources>
|
15 |
<admin>
|
16 |
<children>
|
17 |
-
<emailvision
|
18 |
<children>
|
19 |
-
<abandonment
|
20 |
-
<
|
|
|
|
|
|
|
|
|
|
|
21 |
</abandonment>
|
22 |
</children>
|
23 |
</emailvision>
|
3 |
<menu>
|
4 |
<emailvision>
|
5 |
<children>
|
6 |
+
<abandonment>
|
7 |
+
<children>
|
8 |
+
<conversion translate="title" module="abandonment_report">
|
9 |
+
<title>Conversion Report</title>
|
10 |
+
<action>emv_report/conversion</action>
|
11 |
+
<sort_order>30</sort_order>
|
12 |
+
</conversion>
|
13 |
+
</children>
|
14 |
</abandonment>
|
15 |
</children>
|
16 |
</emailvision>
|
19 |
<resources>
|
20 |
<admin>
|
21 |
<children>
|
22 |
+
<emailvision>
|
23 |
<children>
|
24 |
+
<abandonment>
|
25 |
+
<children>
|
26 |
+
<conversion>
|
27 |
+
<title>Conversion Report</title>
|
28 |
+
<sort_order>20</sort_order>
|
29 |
+
</conversion>
|
30 |
+
</children>
|
31 |
</abandonment>
|
32 |
</children>
|
33 |
</emailvision>
|
@@ -31,7 +31,7 @@
|
|
31 |
<layout>
|
32 |
<updates>
|
33 |
<abandonment_report>
|
34 |
-
<file>
|
35 |
</abandonment_report>
|
36 |
</updates>
|
37 |
</layout>
|
31 |
<layout>
|
32 |
<updates>
|
33 |
<abandonment_report>
|
34 |
+
<file>smartfocus/abandonment_report.xml</file>
|
35 |
</abandonment_report>
|
36 |
</updates>
|
37 |
</layout>
|
@@ -2,7 +2,7 @@
|
|
2 |
<layout>
|
3 |
<abandonment_report_conversion_index>
|
4 |
<reference name="content">
|
5 |
-
<block type="abandonment_report/adminhtml_conversion" template="
|
6 |
<block type="abandonment_report/adminhtml_conversion_form" name="abandonment.report.grid.filter.form">
|
7 |
</block>
|
8 |
</block>
|
2 |
<layout>
|
3 |
<abandonment_report_conversion_index>
|
4 |
<reference name="content">
|
5 |
+
<block type="abandonment_report/adminhtml_conversion" template="smartfocus/abandonment/grid/container.phtml" name="abandonment.report.grid.container">
|
6 |
<block type="abandonment_report/adminhtml_conversion_form" name="abandonment.report.grid.filter.form">
|
7 |
</block>
|
8 |
</block>
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<layout>
|
3 |
+
<default translate="label" module="page">
|
4 |
+
<reference name="head">
|
5 |
+
<action method="addCss"><name>smartfocus.css</name></action>
|
6 |
+
</reference>
|
7 |
+
</default>
|
8 |
+
</layout>
|
@@ -1,15 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @category Auguria
|
4 |
-
* @package Auguria_EmailVision
|
5 |
-
* @author Auguria
|
6 |
-
* @license http://opensource.org/licenses/gpl-3.0.html GNU General Public License version 3 (GPLv3)
|
7 |
-
*
|
8 |
-
* EmailVision getFields button to call the concerned controller action
|
9 |
-
*/
|
10 |
-
?>
|
11 |
-
<a href="<?php echo Mage::getSingleton('adminhtml/url')->getUrl('emv_datasync/dataSync/getMemberFields');?>">
|
12 |
-
<button class="scalable" type="button">
|
13 |
-
<span id="validation_result"><?php echo $this->__('Get SmartFocus member fields') ?></span>
|
14 |
-
</button>
|
15 |
-
</a>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File without changes
|
File without changes
|
@@ -0,0 +1,75 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
// prepare js file magento/js/mage/adminhtml
|
3 |
+
$baseJsUrl = Mage::getBaseUrl('js');
|
4 |
+
$widgetJs = $baseJsUrl . 'mage/adminhtml/wysiwyg/widget.js';
|
5 |
+
?>
|
6 |
+
<script type='text/javascript' src='<?php echo $widgetJs ?>'></script>
|
7 |
+
|
8 |
+
<?php
|
9 |
+
$widgetCss = Mage::getDesign()->getSkinUrl('lib/prototype/windows/themes/magento.css');
|
10 |
+
?>
|
11 |
+
<link rel='stylesheet' type='text/css' href='<?php echo $widgetCss?>' />
|
12 |
+
|
13 |
+
<?php
|
14 |
+
$widgetCss = Mage::getBaseUrl('js') . 'prototype/windows/themes/magento.css';
|
15 |
+
?>
|
16 |
+
<link rel='stylesheet' type='text/css' href='<?php echo $widgetCss?>' />
|
17 |
+
|
18 |
+
<?php
|
19 |
+
$wdgetCssDefault = Mage::getBaseUrl('js') . 'prototype/windows/themes/default.css';
|
20 |
+
?>
|
21 |
+
<link rel='stylesheet' type='text/css' href='<?php echo $wdgetCssDefault ?>' />
|
22 |
+
|
23 |
+
|
24 |
+
<?php // chooser button template?>
|
25 |
+
<span id="salesrule_id"></span>
|
26 |
+
<label class="widget-option-label" id="salesrule_idc30d6133660369e799b882a1d5da011clabel">
|
27 |
+
<?php echo $this->getLabel()?>
|
28 |
+
</label>
|
29 |
+
|
30 |
+
<div id="salesrule_idc30d6133660369e799b882a1d5da011cadvice-container" class="hidden"></div>
|
31 |
+
<script type="text/javascript">//<![CDATA[
|
32 |
+
(function() {
|
33 |
+
var instantiateChooser = function() {
|
34 |
+
window.salesrule_idc30d6133660369e799b882a1d5da011c = new WysiwygWidget.chooser(
|
35 |
+
"salesrule_idc30d6133660369e799b882a1d5da011c",
|
36 |
+
"<?php echo $this->getUrl('*/promo_quote/chooser', array())?>uniq_id/salesrule_idc30d6133660369e799b882a1d5da011c/",
|
37 |
+
<?php echo $this->getButtonConfigInJson() ?>
|
38 |
+
);
|
39 |
+
if ($("salesrule_idc30d6133660369e799b882a1d5da011cvalue")) {
|
40 |
+
$("salesrule_idc30d6133660369e799b882a1d5da011cvalue").advaiceContainer = "salesrule_idc30d6133660369e799b882a1d5da011cadvice-container";
|
41 |
+
}
|
42 |
+
}
|
43 |
+
|
44 |
+
if (document.loaded) { //allow load over ajax
|
45 |
+
instantiateChooser();
|
46 |
+
} else {
|
47 |
+
document.observe("dom:loaded", instantiateChooser);
|
48 |
+
}
|
49 |
+
})();
|
50 |
+
//]]></script>
|
51 |
+
<p class="note" id="note_salesrule_id">
|
52 |
+
<span><?php echo Mage::helper('abandonment')->__('Promotion rule that reminders will advertise.')?></span>
|
53 |
+
</p>
|
54 |
+
|
55 |
+
<label for="choosersalesrule_id"></label>
|
56 |
+
<span id="choosersalesrule_id"></span>
|
57 |
+
<input id="salesrule_idc30d6133660369e799b882a1d5da011cvalue"
|
58 |
+
name="<?php echo $this->getElementName()?>" value="<?php echo $this->getRuleId()?>" readonly="" type="hidden"
|
59 |
+
/>
|
60 |
+
<button id="salesrule_idc30d6133660369e799b882a1d5da011ccontrol" title="<?php echo Mage::helper('abandonment')->__('Select Promotion Rule')?>" type="button" class="scalable btn-chooser" onclick="salesrule_idc30d6133660369e799b882a1d5da011c.choose()" style="">
|
61 |
+
<span><span><span><?php echo Mage::helper('abandonment')->__('Select Promotion Rule')?></span></span></span>
|
62 |
+
</button>
|
63 |
+
|
64 |
+
|
65 |
+
<?php // reset promotion ?>
|
66 |
+
<button id="clearrule" title="<?php echo Mage::helper('abandonment')->__('Clear Selected Rule')?>"
|
67 |
+
type="button" class="scalable btn-chooser" onclick="clearRule()" style="">
|
68 |
+
<span><span><span><?php echo Mage::helper('abandonment')->__('Clear Selected Rule')?></span></span></span>
|
69 |
+
</button>
|
70 |
+
<script>
|
71 |
+
function clearRule() {
|
72 |
+
$('salesrule_idc30d6133660369e799b882a1d5da011cvalue').value = '';
|
73 |
+
$('salesrule_idc30d6133660369e799b882a1d5da011clabel').innerHTML = '<?php echo Mage::helper('widget')->__('Not Selected')?>';
|
74 |
+
}
|
75 |
+
</script>
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @var $this Emv_Core_Block_Adminhtml_Config_ExtensionStatus
|
4 |
+
* */
|
5 |
+
?>
|
6 |
+
<table class="smartfocus-selection" cellspacing="0">
|
7 |
+
<col width="75%" />
|
8 |
+
<col width="25%" />
|
9 |
+
<thead>
|
10 |
+
<tr>
|
11 |
+
<th><?php echo $this->escapeHtml($this->getExtensionVersion()) ?></th>
|
12 |
+
<?php if ($this->getHelpLink()) :?>
|
13 |
+
<th class="smartfocus-selection-info">
|
14 |
+
<a href="<?php echo $this->escapeHtml($this->getHelpLink()) ?>" target="blank"><?php echo Mage::helper('emvcore')->__('Help')?></a>
|
15 |
+
</th>
|
16 |
+
<?php endif;?>
|
17 |
+
</tr>
|
18 |
+
</thead>
|
19 |
+
<tbody>
|
20 |
+
<tr>
|
21 |
+
<td colspan="2">
|
22 |
+
<label><?php echo $this->getMagentoVersionStatus(); ?></label>
|
23 |
+
</td>
|
24 |
+
</tr>
|
25 |
+
<tr>
|
26 |
+
<td colspan="2">
|
27 |
+
<label><?php echo $this->getEmvModulesVersionStatus(); ?></label>
|
28 |
+
</td>
|
29 |
+
</tr>
|
30 |
+
<tr>
|
31 |
+
<td colspan="2">
|
32 |
+
<label><?php echo $this->getPhpEnvironmentStatus(); ?></label>
|
33 |
+
</td>
|
34 |
+
</tr>
|
35 |
+
<tr>
|
36 |
+
<td colspan="2">
|
37 |
+
<label><?php echo $this->getCronStatus(); ?></label>
|
38 |
+
</td>
|
39 |
+
</tr>
|
40 |
+
<tr>
|
41 |
+
<td colspan="2">
|
42 |
+
<label><?php echo $this->getMemoryStatus(); ?></label>
|
43 |
+
</td>
|
44 |
+
</tr>
|
45 |
+
<tr>
|
46 |
+
<td colspan="2">
|
47 |
+
<label><?php echo $this->getDirectoryPermissionStatus(); ?></label>
|
48 |
+
</td>
|
49 |
+
</tr>
|
50 |
+
<?php foreach($this->getOtherTestList() as $test) :?>
|
51 |
+
<?php $status = $this->getStatusForTest($test)?>
|
52 |
+
<?php if ($status) :?>
|
53 |
+
<tr>
|
54 |
+
<td colspan="2">
|
55 |
+
<label><?php echo $status; ?></label>
|
56 |
+
</td>
|
57 |
+
</tr>
|
58 |
+
<?php endif;?>
|
59 |
+
<?php endforeach;?>
|
60 |
+
</tbody>
|
61 |
+
</table>
|
File without changes
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/*@var $this Emv_DataSync_Block_Adminhtml_System_Config_GetFields */
|
3 |
+
|
4 |
+
/**
|
5 |
+
* SmartFocus getFields button to call the concerned controller action
|
6 |
+
*/
|
7 |
+
?>
|
8 |
+
<a href="<?php echo $this->getGetFieldsUrl() ?>">
|
9 |
+
<button class="scalable" type="button">
|
10 |
+
<span id="validation_result"><?php echo $this->__('Get SmartFocus member fields') ?></span>
|
11 |
+
</button>
|
12 |
+
</a>
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
<?php
|
3 |
+
$checkUrl = Mage::getSingleton('adminhtml/url')->getUrl('emvemt/template/validateTemplate');
|
4 |
+
?>
|
5 |
+
|
6 |
+
<div id="messages-connection" style="display: none;">
|
7 |
+
<ul class="messages">
|
8 |
+
<li class="error-msg error-connection">
|
9 |
+
</li>
|
10 |
+
<li class="success-msg success-connection">
|
11 |
+
</li>
|
12 |
+
</ul>
|
13 |
+
</div>
|
14 |
+
<button id="validate-button" class="scalable" type="button">
|
15 |
+
<span id="validation_result"><?php echo Mage::helper('emvemt')->__('Check and Configure your SmartFocus Account') ?></span>
|
16 |
+
</button>
|
17 |
+
|
18 |
+
|
19 |
+
<script type="text/javascript">
|
20 |
+
//<![CDATA[
|
21 |
+
|
22 |
+
var Emv_Check_Account = Class.create();
|
23 |
+
Emv_Check_Account.prototype = {
|
24 |
+
initialize : function()
|
25 |
+
{
|
26 |
+
this.loading = false;
|
27 |
+
this.loader = new varienLoader(false);
|
28 |
+
this.checkUrl = "<?php echo $checkUrl ?>";
|
29 |
+
|
30 |
+
this.bindCheckAccountButton();
|
31 |
+
},
|
32 |
+
bindCheckAccountButton : function()
|
33 |
+
{
|
34 |
+
var button = $('validate-button');
|
35 |
+
Event.observe(button, 'click', this.checkAccount.bind(this));
|
36 |
+
},
|
37 |
+
checkAccount : function(event)
|
38 |
+
{
|
39 |
+
if (this.loading == false) {
|
40 |
+
this.loading = true;
|
41 |
+
var params = {
|
42 |
+
'account_id' : $('emvemt_transactional_service_account').value
|
43 |
+
};
|
44 |
+
this.loader.load(this.checkUrl, params, this.proceedMessageReturn.bind(this));
|
45 |
+
}
|
46 |
+
},
|
47 |
+
proceedMessageReturn : function(serverResponse) {
|
48 |
+
this.loading = false;
|
49 |
+
this.hideAndRemoveMessage();
|
50 |
+
|
51 |
+
if (serverResponse) {
|
52 |
+
data = eval('(' + serverResponse + ')');
|
53 |
+
if (typeof(data.error) == 'object' && data.error.length >= 1) {
|
54 |
+
var html = this.prepareHtmlMessage(data.error);
|
55 |
+
$$('.error-connection').first().innerHTML = html;
|
56 |
+
}
|
57 |
+
if (typeof(data.information) == 'object' && data.information.length >= 1) {
|
58 |
+
var html = this.prepareHtmlMessage(data.information);
|
59 |
+
$$('.success-connection').first().innerHTML = html;
|
60 |
+
}
|
61 |
+
this.showMessage();
|
62 |
+
}
|
63 |
+
},
|
64 |
+
prepareHtmlMessage : function(messages)
|
65 |
+
{
|
66 |
+
html = '<ul>';
|
67 |
+
for (var i = 0; i < messages.length; i++) {
|
68 |
+
html += '<li><span>' + messages[i] + '</span></li>';
|
69 |
+
}
|
70 |
+
html += '</ul>';
|
71 |
+
|
72 |
+
return html;
|
73 |
+
},
|
74 |
+
hideAndRemoveMessage : function()
|
75 |
+
{
|
76 |
+
$$('.error-connection').first().innerHTML = "";
|
77 |
+
$$('.error-connection').first().hide();
|
78 |
+
$$('.success-connection').first().innerHTML = "";
|
79 |
+
$$('.success-connection').first().hide();
|
80 |
+
|
81 |
+
$('messages-connection').hide();
|
82 |
+
},
|
83 |
+
showMessage : function()
|
84 |
+
{
|
85 |
+
if ($$('.error-connection').first().innerHTML != "") {
|
86 |
+
$$('.error-connection').first().show();
|
87 |
+
}
|
88 |
+
if ($$('.success-connection').first().innerHTML != "") {
|
89 |
+
$$('.success-connection').first().show();
|
90 |
+
}
|
91 |
+
$('messages-connection').show();
|
92 |
+
}
|
93 |
+
}
|
94 |
+
checkAccountApply = new Emv_Check_Account();
|
95 |
+
//]]>
|
96 |
+
</script>
|
File without changes
|
File without changes
|
File without changes
|
@@ -17,7 +17,7 @@ Customer account home dashboard layout
|
|
17 |
<abandonment_customer_manage>
|
18 |
<update handle="customer_account"/>
|
19 |
<reference name="my.account.wrapper">
|
20 |
-
<block type="abandonment/customer_abandonment" name="customer_abandonment" as="info1" template="
|
21 |
</reference>
|
22 |
</abandonment_customer_manage>
|
23 |
</layout>
|
17 |
<abandonment_customer_manage>
|
18 |
<update handle="customer_account"/>
|
19 |
<reference name="my.account.wrapper">
|
20 |
+
<block type="abandonment/customer_abandonment" name="customer_abandonment" as="info1" template="smartfocus/abandonment/customer.phtml"/>
|
21 |
</reference>
|
22 |
</abandonment_customer_manage>
|
23 |
</layout>
|
File without changes
|
@@ -23,10 +23,10 @@ $cart = $this->getCart();
|
|
23 |
href="<?php echo $itemLink?>"
|
24 |
title="Checkout Now" target="_blank">
|
25 |
<img
|
26 |
-
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
</a>
|
31 |
</td>
|
32 |
<td width="8"> </td>
|
23 |
href="<?php echo $itemLink?>"
|
24 |
title="Checkout Now" target="_blank">
|
25 |
<img
|
26 |
+
alt="<?php echo $this->escapeHtml($item->getName()) ?>"
|
27 |
+
border="0" style="display: block;"
|
28 |
+
src="<?php echo Mage::helper('abandonment')->getProductImageUrl($item) ?>"
|
29 |
+
width="85" />
|
30 |
</a>
|
31 |
</td>
|
32 |
<td width="8"> </td>
|
@@ -1,3 +1,5 @@
|
|
|
|
|
|
1 |
"You are already unsubscribed from abandoned carts notifications.","You are already unsubscribed from abandoned carts notifications."
|
2 |
"You were successfully unsubscribed from abandoned carts notifications.","You were successfully unsubscribed from abandoned carts notifications."
|
3 |
"Cart Reminder Subscription","Cart Reminder Subscription"
|
@@ -7,10 +9,13 @@
|
|
7 |
"The link cannot be used by registered customers.","The link cannot be used by registered customers."
|
8 |
"The link is invalid.","The link is invalid."
|
9 |
"SmartFocus - Abandonment cart configs","SmartFocus - Abandonment cart configs"
|
10 |
-
"
|
11 |
"Email Sender","Email Sender"
|
12 |
"Image Size","Image Size"
|
13 |
-
"Shopping Cart Prices Rule
|
|
|
|
|
|
|
14 |
"Coupon Code Length","Coupon Code Length"
|
15 |
"Coupon Code Format","Coupon Code Format"
|
16 |
"Coupon Code Prefix","Coupon Code Prefix"
|
@@ -18,22 +23,42 @@
|
|
18 |
"Dash Every X Characters For Coupon Code","Dash Every X Characters For Coupon Code"
|
19 |
"If empty no separation.","If empty no separation."
|
20 |
"Excluding prefix, suffix and separators.","Excluding prefix, suffix and separators."
|
21 |
-
"First
|
22 |
-
"First Email
|
23 |
-
"First Email
|
24 |
-
"First Email
|
25 |
-
"Second
|
26 |
-
"Second Email
|
27 |
-
"Second Email
|
28 |
-
"Second Email Template","Second Email Template"
|
29 |
-
"Third
|
30 |
-
"Third Email
|
31 |
-
"Third Email
|
32 |
-
"Third Email
|
33 |
"Cart Reminder Email Subscription","Cart Reminder Email Subscription"
|
34 |
"Back","Back"
|
35 |
"Save","Save"
|
36 |
"Abandoned Cart 1","Abandoned Cart 1"
|
37 |
"Abandoned Cart 2","Abandoned Cart 2"
|
38 |
"Abandoned Cart 3","Abandoned Cart 3"
|
39 |
-
"General","General"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Abandoned Carts","Abandoned Carts"
|
2 |
+
"List","List"
|
3 |
"You are already unsubscribed from abandoned carts notifications.","You are already unsubscribed from abandoned carts notifications."
|
4 |
"You were successfully unsubscribed from abandoned carts notifications.","You were successfully unsubscribed from abandoned carts notifications."
|
5 |
"Cart Reminder Subscription","Cart Reminder Subscription"
|
9 |
"The link cannot be used by registered customers.","The link cannot be used by registered customers."
|
10 |
"The link is invalid.","The link is invalid."
|
11 |
"SmartFocus - Abandonment cart configs","SmartFocus - Abandonment cart configs"
|
12 |
+
"Abandoned Cart Reminders","Abandoned Cart Reminders"
|
13 |
"Email Sender","Email Sender"
|
14 |
"Image Size","Image Size"
|
15 |
+
"Shopping Cart Prices Rule","Shopping Cart Prices Rule"
|
16 |
+
"Promotion rule that reminders will advertise.","Promotion rule that reminders will advertise."
|
17 |
+
"Select Promotion Rule","Select Promotion Rule"
|
18 |
+
"Clear Selected Rule","Clear Selected Rule"
|
19 |
"Coupon Code Length","Coupon Code Length"
|
20 |
"Coupon Code Format","Coupon Code Format"
|
21 |
"Coupon Code Prefix","Coupon Code Prefix"
|
23 |
"Dash Every X Characters For Coupon Code","Dash Every X Characters For Coupon Code"
|
24 |
"If empty no separation.","If empty no separation."
|
25 |
"Excluding prefix, suffix and separators.","Excluding prefix, suffix and separators."
|
26 |
+
"First Reminder Configuration","First Reminder Configuration"
|
27 |
+
"First Email Reminder Enable","First Email Reminder Enable"
|
28 |
+
"First Email Reminder Delay (in hours)","First Email Reminder Delay (in hours)"
|
29 |
+
"First Email Reminder Template","First Email Reminder Template"
|
30 |
+
"Second Reminder Configuration","Second Reminder Configuration"
|
31 |
+
"Second Email Reminder Enable","Second Email Reminder Enable"
|
32 |
+
"Second Email Reminder Delay (in hours)","Second Email Reminder Delay (in hours)"
|
33 |
+
"Second Email Reminder Template","Second Email Reminder Template"
|
34 |
+
"Third Reminder Configuration","Third Reminder Configuration"
|
35 |
+
"Third Email Reminder Enable","Third Email Reminder Enable"
|
36 |
+
"Third Email Reminder Delay (in hours)","Third Email Reminder Delay (in hours)"
|
37 |
+
"Third Email Reminder Template","Third Email Reminder Template"
|
38 |
"Cart Reminder Email Subscription","Cart Reminder Email Subscription"
|
39 |
"Back","Back"
|
40 |
"Save","Save"
|
41 |
"Abandoned Cart 1","Abandoned Cart 1"
|
42 |
"Abandoned Cart 2","Abandoned Cart 2"
|
43 |
"Abandoned Cart 3","Abandoned Cart 3"
|
44 |
+
"General","General"
|
45 |
+
"Maximum Abandoned Carts per One Run","Maximum Abandoned Carts per One Run"
|
46 |
+
"Abandoned Cart Reminders","Abandoned Cart Reminders"
|
47 |
+
"Cannot send reminder for cart #%s. Reason: %s","Cannot send reminder for cart #%s. Reason: %s"
|
48 |
+
"%s carts were successfully sent with %s","%s carts were successfully sent with %s"
|
49 |
+
"One cart was successfully sent with %s","One cart was successfully sent with %s"
|
50 |
+
"Abandoned Cart (customer email : %s - on store %s)","Abandoned Cart (customer email : %s - on store %s)"
|
51 |
+
"Customer ID","Customer ID"
|
52 |
+
"Sent Reminder","Sent Reminder"
|
53 |
+
"Reminder Last Update","Reminder Last Update"
|
54 |
+
"Subscribed to abandoned cart reminders","Subscribed to abandoned cart reminders"
|
55 |
+
"Reminder Coupon","Reminder Coupon"
|
56 |
+
"Test First Reminder","Test First Reminder"
|
57 |
+
"Test Second Reminder","Test Second Reminder"
|
58 |
+
"Test Third Reminder","Test Third Reminder"
|
59 |
+
"None","None"
|
60 |
+
"First Reminder","First Reminder"
|
61 |
+
"Second Reminder","Second Reminder"
|
62 |
+
"Third Reminder","Third Reminder"
|
63 |
+
"Number of Item Types","Number of Item Types"
|
64 |
+
"Number of Items","Number of Items"
|
@@ -24,7 +24,7 @@
|
|
24 |
"Unable to find an account to delete.","Unable to find an account to delete."
|
25 |
"The SmartFocus account has been saved.","The SmartFocus account has been saved."
|
26 |
"Your selected account does not exist anymore!","Your selected account does not exist anymore!"
|
27 |
-
"Could not verify the account. Network problems occured!
|
28 |
"Your account ""%s"" is not allowed for %s !","Your account ""%s"" is not allowed for %s !"
|
29 |
"Please define a valid url for %s !","Please define a valid url for %s !"
|
30 |
"Could not enable ""%s"" process ! Please select an account in the list !","Could not enable ""%s"" process ! Please select an account in the list !"
|
@@ -57,4 +57,34 @@
|
|
57 |
"Please enter a valid url for %s!","Please enter a valid url for %s!"
|
58 |
"Service","Service"
|
59 |
"Url","Url"
|
60 |
-
"Remove","Remove"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
"Unable to find an account to delete.","Unable to find an account to delete."
|
25 |
"The SmartFocus account has been saved.","The SmartFocus account has been saved."
|
26 |
"Your selected account does not exist anymore!","Your selected account does not exist anymore!"
|
27 |
+
"Could not verify the selected account. Network problems occured!","Could not verify the selected account. Network problems occured!"
|
28 |
"Your account ""%s"" is not allowed for %s !","Your account ""%s"" is not allowed for %s !"
|
29 |
"Please define a valid url for %s !","Please define a valid url for %s !"
|
30 |
"Could not enable ""%s"" process ! Please select an account in the list !","Could not enable ""%s"" process ! Please select an account in the list !"
|
57 |
"Please enter a valid url for %s!","Please enter a valid url for %s!"
|
58 |
"Service","Service"
|
59 |
"Url","Url"
|
60 |
+
"Remove","Remove"
|
61 |
+
"SmartFocus Connector Status (Version %s)","SmartFocus Connector Status (Version %s)"
|
62 |
+
"<span class=""icon-status"">%s</span> Your Magento version is <strong>%s</strong>.","<span class=""icon-status"">%s</span> Your Magento version is <strong>%s</strong>."
|
63 |
+
"Required PHP version is <strong>%s</strong> - current version <strong>%s</strong>.","Required PHP version is <strong>%s</strong> - current version <strong>%s</strong>."
|
64 |
+
"Your PHP version (<strong>%s</strong>) is satisfied.","Your PHP version (<strong>%s</strong>) is satisfied."
|
65 |
+
"Required Php Extensions are <strong>%s</strong>.","Required Php Extensions are <strong>%s</strong>."
|
66 |
+
"The followings are missing : <strong>%s</strong>.","The followings are missing : <strong>%s</strong>."
|
67 |
+
"All the required Php Extensions (<strong>%s</strong>) are correctly installed.","All the required Php Extensions (<strong>%s</strong>) are correctly installed."
|
68 |
+
"<span class=""icon-status"">%s</span> Magento Cron Process has been correctly configured!","<span class=""icon-status"">%s</span> Magento Cron Process has been correctly configured!"
|
69 |
+
"<span class=""icon-status"">%s</span> Magento Cron Process has not been correctly activated!","<span class=""icon-status"">%s</span> Magento Cron Process has not been correctly activated!"
|
70 |
+
"<span class=""icon-status"">%s</span> memory_limit is set to <strong>%s</strong>.","<span class=""icon-status"">%s</span> memory_limit is set to <strong>%s</strong>."
|
71 |
+
"<span class=""icon-status"">%s</span> memory_limit should be set to at least <strong>%s M</strong> (currently %s).","<span class=""icon-status"">%s</span> memory_limit should be set to at least <strong>%s M</strong> (currently %s)."
|
72 |
+
"Data Sync","Data Sync"
|
73 |
+
"Title","Title"
|
74 |
+
"State","State"
|
75 |
+
"New","New"
|
76 |
+
"Processing","Processing"
|
77 |
+
"Failed","Failed"
|
78 |
+
"Success","Success"
|
79 |
+
"Status (%)","Status (%)"
|
80 |
+
"Terminated At","Terminated At"
|
81 |
+
"View Log","View Log"
|
82 |
+
"SmartFocus Data Process List","SmartFocus Data Process List"
|
83 |
+
"Data Process List","Data Process List"
|
84 |
+
"Error during get output file","Error during get output file"
|
85 |
+
"Error during get process log","Error during get process log"
|
86 |
+
"Please select something!","Please select something!"
|
87 |
+
"Unable to delete the process #%s. Reason: %s","Unable to delete the process #%s. Reason: %s"
|
88 |
+
"Unable to delete the process #%s","Unable to delete the process #%s"
|
89 |
+
"%s records were successfully deleted","%s records were successfully deleted"
|
90 |
+
"One record was successfully deleted","One record was successfully deleted"
|
@@ -41,4 +41,18 @@
|
|
41 |
"Daily","Daily"
|
42 |
"General","General"
|
43 |
"Enabled","Enabled"
|
44 |
-
"SmartFocus Entity Id","SmartFocus Entity Id"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
"Daily","Daily"
|
42 |
"General","General"
|
43 |
"Enabled","Enabled"
|
44 |
+
"SmartFocus Entity Id","SmartFocus Entity Id"
|
45 |
+
"Customer Billing Address","Customer Billing Address"
|
46 |
+
"Customer Shipping Address","Customer Shipping Address"
|
47 |
+
"Customer","Customer"
|
48 |
+
"Newsletter Subscriber","Newsletter Subscriber"
|
49 |
+
"Newsletter Subscriber Queue","Newsletter Subscriber Queue"
|
50 |
+
"Customer Name","Customer Name"
|
51 |
+
"Last Sync","Last Sync"
|
52 |
+
"Last Data Update","Last Data Update"
|
53 |
+
"Last Unsubscription","Last Unsubscription"
|
54 |
+
"Scheduled","Scheduled"
|
55 |
+
"Schedule","Schedule"
|
56 |
+
"Stop","Stop"
|
57 |
+
"Get Csv File(s)","Get Csv File(s)"
|
58 |
+
"Manual Sync","Manual Sync"
|
@@ -90,9 +90,9 @@ Mode","Mode"
|
|
90 |
"Server Error","Server Error"
|
91 |
"Network Problem","Network Problem"
|
92 |
"Invalid SmartFocus Parameters","Invalid SmartFocus Parameters"
|
93 |
-
"
|
94 |
-
"
|
95 |
-
"
|
96 |
"Refresh All Attributes","Refresh All Attributes"
|
97 |
"Insert Prepared Magento Variables","Insert Prepared Magento Variables"
|
98 |
"Please select a template","Please select a template"
|
@@ -108,4 +108,6 @@ Mode","Mode"
|
|
108 |
"Template Information","Template Information"
|
109 |
"Are you sure to change the sending mode ? All your mapped attributes will be deleted !","Are you sure to change the sending mode ? All your mapped attributes will be deleted !"
|
110 |
"SmartFocus Attribute","SmartFocus Attribute"
|
111 |
-
"Are you sure to refresh all your mapped SmartFocus Attributes ?","Are you sure to refresh all your mapped SmartFocus Attributes ?"
|
|
|
|
90 |
"Server Error","Server Error"
|
91 |
"Network Problem","Network Problem"
|
92 |
"Invalid SmartFocus Parameters","Invalid SmartFocus Parameters"
|
93 |
+
"Classic","Classic"
|
94 |
+
"SmartFocus Template","SmartFocus Template"
|
95 |
+
"SmartFocus Routage","SmartFocus Routage"
|
96 |
"Refresh All Attributes","Refresh All Attributes"
|
97 |
"Insert Prepared Magento Variables","Insert Prepared Magento Variables"
|
98 |
"Please select a template","Please select a template"
|
108 |
"Template Information","Template Information"
|
109 |
"Are you sure to change the sending mode ? All your mapped attributes will be deleted !","Are you sure to change the sending mode ? All your mapped attributes will be deleted !"
|
110 |
"SmartFocus Attribute","SmartFocus Attribute"
|
111 |
+
"Are you sure to refresh all your mapped SmartFocus Attributes ?","Are you sure to refresh all your mapped SmartFocus Attributes ?"
|
112 |
+
"Check and Configure your SmartFocus Account","Check and Configure your SmartFocus Account"
|
113 |
+
"Your account is correctly set up and ready to send emails","Your account is correctly set up and ready to send emails"
|
@@ -1,5 +0,0 @@
|
|
1 |
-
<!--@subject Emailvision synchronization by cron process errors @-->
|
2 |
-
<!--@vars
|
3 |
-
{"var errors":"Cron errors"}
|
4 |
-
@-->
|
5 |
-
{{var errors}}
|
|
|
|
|
|
|
|
|
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!--@subject SmartFocus Synchronization by cron process errors @-->
|
2 |
+
<!--@vars
|
3 |
+
{"var errors":"Cron errors"}
|
4 |
+
@-->
|
5 |
+
{{var errors}}
|
@@ -1,3 +1,5 @@
|
|
|
|
|
|
1 |
"You are already unsubscribed from abandoned carts notifications.","Vous êtes déjà désinscrit des relances de paniers abandonnés."
|
2 |
"You were successfully unsubscribed from abandoned carts notifications.","Vous avez été désinscrit des relances de paniers abandonnés avec succès"
|
3 |
"Cart Reminder Subscription","Inscription aux relances paniers abandonnés"
|
@@ -8,7 +10,10 @@
|
|
8 |
"The link is invalid.","Le lien est invalide."
|
9 |
"Cart Reminder Email Subscription","Inscription Aux Emails Relances Paniers Abandonnés"
|
10 |
"Image Size","Taille image"
|
11 |
-
"Shopping Cart Prices Rule
|
|
|
|
|
|
|
12 |
"Coupon Code Length","Longueur du code coupon"
|
13 |
"Coupon Code Format","Format du code coupon"
|
14 |
"Coupon Code Prefix","Préfixe du code coupon"
|
@@ -19,22 +24,42 @@
|
|
19 |
"Abandoned Cart 1","Panier Abandonné 1"
|
20 |
"Abandoned Cart 2","Panier Abandonné 2"
|
21 |
"Abandoned Cart 3","Panier Abandonné 3"
|
22 |
-
"
|
23 |
-
"First
|
24 |
-
"First Email
|
25 |
-
"First Email
|
26 |
-
"First Email
|
27 |
-
"Second
|
28 |
-
"Second Email
|
29 |
-
"Second Email
|
30 |
-
"Second Email Template","Template deuxième relance"
|
31 |
-
"Third
|
32 |
-
"Third Email
|
33 |
-
"Third Email
|
34 |
-
"Third Email
|
35 |
"Sender Identity","Identité de l'expéditeur"
|
36 |
"Email Sender","Expéditeur Email"
|
37 |
"Back","Retour"
|
38 |
"Save","Valider"
|
39 |
"General","Général"
|
40 |
-
"SmartFocus - Abandonment cart configs","SmartFocus - Configurations de la relance panier abandoné"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Abandoned Carts","Paniers abandonnés"
|
2 |
+
"List","Liste"
|
3 |
"You are already unsubscribed from abandoned carts notifications.","Vous êtes déjà désinscrit des relances de paniers abandonnés."
|
4 |
"You were successfully unsubscribed from abandoned carts notifications.","Vous avez été désinscrit des relances de paniers abandonnés avec succès"
|
5 |
"Cart Reminder Subscription","Inscription aux relances paniers abandonnés"
|
10 |
"The link is invalid.","Le lien est invalide."
|
11 |
"Cart Reminder Email Subscription","Inscription Aux Emails Relances Paniers Abandonnés"
|
12 |
"Image Size","Taille image"
|
13 |
+
"Shopping Cart Prices Rule","Règle de prix du panier"
|
14 |
+
"Promotion rule that reminders will advertise.","Règle de promotion pour laquelle rappels font de la publicité."
|
15 |
+
"Select Promotion Rule","Séléctioner règle de prix du panier"
|
16 |
+
"Clear Selected Rule","Supprimer la règle séléctionnée"
|
17 |
"Coupon Code Length","Longueur du code coupon"
|
18 |
"Coupon Code Format","Format du code coupon"
|
19 |
"Coupon Code Prefix","Préfixe du code coupon"
|
24 |
"Abandoned Cart 1","Panier Abandonné 1"
|
25 |
"Abandoned Cart 2","Panier Abandonné 2"
|
26 |
"Abandoned Cart 3","Panier Abandonné 3"
|
27 |
+
"Abandoned Cart Reminders","Relances panier abandonné"
|
28 |
+
"First Reminder Configuration","Configuration première relance"
|
29 |
+
"First Email Reminder Enable","Activation première relance"
|
30 |
+
"First Email Reminder Delay (in hours)","Délai première relance (en heures)"
|
31 |
+
"First Email Reminder Template","Template première relance"
|
32 |
+
"Second Reminder Configuration","Configuration deuxième relance"
|
33 |
+
"Second Email Reminder Enable","Activation deuxième relance"
|
34 |
+
"Second Email Reminder Delay (in hours)","Délai deuxième relance (en heures)"
|
35 |
+
"Second Email Reminder Template","Template deuxième relance"
|
36 |
+
"Third Reminder Configuration","Configuration troisième relance"
|
37 |
+
"Third Email Reminder Enable","Activation troisième relance"
|
38 |
+
"Third Email Reminder Delay (in hours)","Délai troisième relance (en heures)"
|
39 |
+
"Third Email Reminder Template","Template troisième relance"
|
40 |
"Sender Identity","Identité de l'expéditeur"
|
41 |
"Email Sender","Expéditeur Email"
|
42 |
"Back","Retour"
|
43 |
"Save","Valider"
|
44 |
"General","Général"
|
45 |
+
"SmartFocus - Abandonment cart configs","SmartFocus - Configurations de la relance panier abandoné"
|
46 |
+
"Maximum Abandoned Carts per One Run","Nombre de paniers abandonés à traiter par lancement"
|
47 |
+
"Abandoned Cart Reminders","Rappels des paniers abandonés"
|
48 |
+
"Cannot send reminder for cart #%s. Reason: %s","Impossible d'envoyer le rappel pour le panier #%s. Raison : %s"
|
49 |
+
"%s carts were successfully sent with %s","%s paniers ont été énvoyé avec %s"
|
50 |
+
"One cart was successfully sent with %s","Un panier a été envoyé avec %s"
|
51 |
+
"Abandoned Cart (customer email : %s - on store %s)","Panier (attaché au mail : %s - passé sur le store %s)"
|
52 |
+
"Customer ID","ID Client"
|
53 |
+
"Sent Reminder","Rappel Envoyé"
|
54 |
+
"Reminder Last Update","Dernière mise à jour du rappel"
|
55 |
+
"Subscribed to abandoned cart reminders","Souscrit au rappel"
|
56 |
+
"Reminder Coupon","Coupon attaché au rappel"
|
57 |
+
"Test First Reminder","Testez premier rappel"
|
58 |
+
"Test Second Reminder","Testez deuxième rappel"
|
59 |
+
"Test Third Reminder","Testez troisième rappel"
|
60 |
+
"None","Aucun"
|
61 |
+
"First Reminder","Premier rappel"
|
62 |
+
"Second Reminder","Deuxième rappel"
|
63 |
+
"Third Reminder","Troisième rappel"
|
64 |
+
"Number of Item Types","Nombre de types de produits"
|
65 |
+
"Number of Items","Nombre d'articles"
|
@@ -22,7 +22,7 @@
|
|
22 |
"SmartFocus account deleted.","Votre compte SmartFocus a été supprimé."
|
23 |
"Unable to find an account to delete.","Aucun compte n'a été trouvé pour suppression."
|
24 |
"Your selected account does not exist anymore!","Votre compte sélectionné n'existe plus!"
|
25 |
-
"Could not verify the account. Network problems occured!
|
26 |
"Your account ""%s"" is not allowed for %s !","Votre compte ""%s"" n'est pas autorisé pour %s !"
|
27 |
"Please define a valid url for %s !","Merci de renseigner un valid url pour %s!"
|
28 |
"Could not enable ""%s"" process ! Please select an account in the list !","Impossible d'activer ""%s"" process ! Veuillez sélectionner un compte dans la liste !"
|
@@ -58,4 +58,34 @@
|
|
58 |
"Url","Url"
|
59 |
"Add","Ajouter"
|
60 |
"Remove","Supprimer"
|
61 |
-
"General","Général"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
"SmartFocus account deleted.","Votre compte SmartFocus a été supprimé."
|
23 |
"Unable to find an account to delete.","Aucun compte n'a été trouvé pour suppression."
|
24 |
"Your selected account does not exist anymore!","Votre compte sélectionné n'existe plus!"
|
25 |
+
"Could not verify the selected account. Network problems occured!","Impossible de vérifier le compte séléctionné. Connexion au webservice SmartFocus impossible, veuillez ré-essayer à nouveau!"
|
26 |
"Your account ""%s"" is not allowed for %s !","Votre compte ""%s"" n'est pas autorisé pour %s !"
|
27 |
"Please define a valid url for %s !","Merci de renseigner un valid url pour %s!"
|
28 |
"Could not enable ""%s"" process ! Please select an account in the list !","Impossible d'activer ""%s"" process ! Veuillez sélectionner un compte dans la liste !"
|
58 |
"Url","Url"
|
59 |
"Add","Ajouter"
|
60 |
"Remove","Supprimer"
|
61 |
+
"General","Général"
|
62 |
+
"SmartFocus Connector Status (Version %s)","Connecteur Magento statut (Version %s)"
|
63 |
+
"<span class=""icon-status"">%s</span> Your Magento version is <strong>%s</strong>.","<span class=""icon-status"">%s</span> Votre version de Magento est <strong>%s</strong>."
|
64 |
+
"Required PHP version is <strong>%s</strong> - current version <strong>%s</strong>.","Version PHP requise est <strong>%s</strong> - version actuelle <strong>%s</strong>."
|
65 |
+
"Your PHP version (<strong>%s</strong>) is satisfied.","Votre version PHP (<strong>%s</strong>) est satisfaite."
|
66 |
+
"Required Php Extensions are <strong>%s</strong>.","Les PHP extension obligatoire sont <strong>%s</strong>."
|
67 |
+
"The followings are missing : <strong>%s</strong>.","Les extensions suivantes sont manquantes : <strong>%s</strong>."
|
68 |
+
"All the required Php Extensions (<strong>%s</strong>) are correctly installed.","Toutes les extensions PHP obligatoires (<strong>%s </strong>) sont correctement installées."
|
69 |
+
"<span class=""icon-status"">%s</span> Magento Cron Process has been correctly configured!","<span class=""icon-status"">%s</span> Cron de Magento a été correctement configuré!"
|
70 |
+
"<span class=""icon-status"">%s</span> Magento Cron Process has not been correctly activated!","<span class=""icon-status"">%s </span> Cron de Magento n'a pas été correctement activé!"
|
71 |
+
"<span class=""icon-status"">%s</span> memory_limit is set to <strong>%s</strong>.","<span class=""icon-status"">%s</span> memory_limit est configuré à <strong>%s</strong>."
|
72 |
+
"<span class=""icon-status"">%s</span> memory_limit should be set to at least <strong>%s M</strong> (currently %s).","<span class=""icon-status"">%s </span> memory_limit doit être réglé à au moins <strong>%s M </strong> (actuellement %s)."
|
73 |
+
"Data Sync","Data Sync"
|
74 |
+
"Title","Titre"
|
75 |
+
"State","Etat"
|
76 |
+
"New","Nouveau"
|
77 |
+
"Processing","En cours de traitement"
|
78 |
+
"Failed","Echoué"
|
79 |
+
"Success","Succès"
|
80 |
+
"Status (%)","Statut (%)"
|
81 |
+
"Terminated At","Terminé à"
|
82 |
+
"View Log","Consulter le log"
|
83 |
+
"SmartFocus Data Process List","Liste des procès SmartFocus"
|
84 |
+
"Data Process List","Liste des procès"
|
85 |
+
"Error during get output file","Erreur lors de la lecture de fichier output"
|
86 |
+
"Error during get process log","Erreur lors de la récupérartion de log"
|
87 |
+
"Please select something!","Merci de choisir un élément!"
|
88 |
+
"Unable to delete the process #%s. Reason: %s","Impossible de supprimer le processus #%s. Raison: %s"
|
89 |
+
"Unable to delete the process #%s","Impossible de supprimer le processus #%s"
|
90 |
+
"%s records were successfully deleted","%s procès ont été supprimés."
|
91 |
+
"One record was successfully deleted","Un procès a été supprimé."
|
@@ -26,6 +26,7 @@
|
|
26 |
"Add Field","Ajouter un champ"
|
27 |
"Magento Fields","Champs Magento"
|
28 |
"SmartFocus Member Fields","Champs de la table membre SmartFocus"
|
|
|
29 |
"If enabled, Magento newsletter subscribers will be synced by their email address. By default, the SmartFocus Entity Id will be used.","Si activée, les abonnés à la newsletter Magento seront synchronisés par leur adresse e-mail. Par défaut, SmartFocus Id sera utilisé."
|
30 |
"SmartFocus Entity Id","SmartFocus id"
|
31 |
"Default field used to link a Magento newsletter subscriber to a SmartFocus member. CLIENTURN is selected by default.","Champ par défaut utilisé pour lier l'identifiant d'un abonné à la newsletter à un membre SmartFocus correspondant. CLIENTURN est utilisé par défaut."
|
@@ -42,4 +43,18 @@
|
|
42 |
"Daily","Quotidiennement"
|
43 |
"General","Général"
|
44 |
"Enabled","Activé"
|
45 |
-
"Frequency","Fréquence"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
"Add Field","Ajouter un champ"
|
27 |
"Magento Fields","Champs Magento"
|
28 |
"SmartFocus Member Fields","Champs de la table membre SmartFocus"
|
29 |
+
"Synchronize with email","Synchroniser avec email"
|
30 |
"If enabled, Magento newsletter subscribers will be synced by their email address. By default, the SmartFocus Entity Id will be used.","Si activée, les abonnés à la newsletter Magento seront synchronisés par leur adresse e-mail. Par défaut, SmartFocus Id sera utilisé."
|
31 |
"SmartFocus Entity Id","SmartFocus id"
|
32 |
"Default field used to link a Magento newsletter subscriber to a SmartFocus member. CLIENTURN is selected by default.","Champ par défaut utilisé pour lier l'identifiant d'un abonné à la newsletter à un membre SmartFocus correspondant. CLIENTURN est utilisé par défaut."
|
43 |
"Daily","Quotidiennement"
|
44 |
"General","Général"
|
45 |
"Enabled","Activé"
|
46 |
+
"Frequency","Fréquence"
|
47 |
+
"Customer Billing Address","Adresse de facturation"
|
48 |
+
"Customer Shipping Address","Adresse de livraison"
|
49 |
+
"Customer","Client"
|
50 |
+
"Newsletter Subscriber","Abonné à la newsletter"
|
51 |
+
"Newsletter Subscriber Queue","List d'attente des abonnés"
|
52 |
+
"Customer Name","Nom du client"
|
53 |
+
"Last Sync","Dernière Sync."
|
54 |
+
"Last Data Update","Dernière modification de données"
|
55 |
+
"Last Unsubscription","Dernière désinscription"
|
56 |
+
"Scheduled","Programmé"
|
57 |
+
"Schedule","Programmer"
|
58 |
+
"Stop","Stopper"
|
59 |
+
"Get Csv File(s)","Récupérer fichier(s) Csv"
|
60 |
+
"Manual Sync","Synchronisation manuelle"
|
@@ -89,9 +89,9 @@ Mode","Mode"
|
|
89 |
"Server Error","Serveur problème"
|
90 |
"Network Problem","Problème de réseau"
|
91 |
"Invalid SmartFocus Parameters","Paramètres d'envoi invalides"
|
92 |
-
"
|
93 |
-
"
|
94 |
-
"
|
95 |
"Refresh All Attributes","Actualiser tous les attributs"
|
96 |
"Insert Prepared Magento Variables","Insérer les variables Magento"
|
97 |
"Please select a template","Veuillez sélectionner un modèle"
|
@@ -108,4 +108,6 @@ Mode","Mode"
|
|
108 |
"Are you sure to change the sending mode ? All your mapped attributes will be deleted !","Etes-vous sûr de changer le mode d\'envoi? Tous vos attributs mappés seront supprimés!"
|
109 |
"SmartFocus Attribute","Attribut SmartFocus"
|
110 |
"Are you sure to refresh all your mapped SmartFocus Attributes ?","Etes-vous sûr de rafraîchir tous vos attributs SmartFocus mappés?"
|
111 |
-
""Email Templates","Modèles d'email"
|
|
|
|
89 |
"Server Error","Serveur problème"
|
90 |
"Network Problem","Problème de réseau"
|
91 |
"Invalid SmartFocus Parameters","Paramètres d'envoi invalides"
|
92 |
+
"Classic","Classic"
|
93 |
+
"SmartFocus Template","SmartFocus Template"
|
94 |
+
"SmartFocus Routage","SmartFocus Routage"
|
95 |
"Refresh All Attributes","Actualiser tous les attributs"
|
96 |
"Insert Prepared Magento Variables","Insérer les variables Magento"
|
97 |
"Please select a template","Veuillez sélectionner un modèle"
|
108 |
"Are you sure to change the sending mode ? All your mapped attributes will be deleted !","Etes-vous sûr de changer le mode d\'envoi? Tous vos attributs mappés seront supprimés!"
|
109 |
"SmartFocus Attribute","Attribut SmartFocus"
|
110 |
"Are you sure to refresh all your mapped SmartFocus Attributes ?","Etes-vous sûr de rafraîchir tous vos attributs SmartFocus mappés?"
|
111 |
+
""Email Templates","Modèles d'email"
|
112 |
+
"Check and Configure your SmartFocus Account","Vérifier et configurer votre compte SmartFocus"
|
113 |
+
"Your account is correctly set up and ready to send emails","Votre compte est correctement configuré et prêt à envoyer des e-mails"
|
@@ -1,3 +1,4 @@
|
|
|
|
1 |
"Total Abandoned Cart Report","Rapport de paniers abandonés"
|
2 |
"the first reminders","les premières relances"
|
3 |
"the second reminders","les secondes relances"
|
1 |
+
"Conversion Report","Rapport de conversion"
|
2 |
"Total Abandoned Cart Report","Rapport de paniers abandonés"
|
3 |
"the first reminders","les premières relances"
|
4 |
"the second reminders","les secondes relances"
|
@@ -22,10 +22,16 @@ class EmailVision_Api_BatchMemberService extends EmailVision_Api_Common
|
|
22 |
const CSV_FIELD_ENCLOSURE = '"';
|
23 |
|
24 |
/**
|
25 |
-
* Max file size in
|
26 |
*/
|
27 |
-
const MAX_FILESIZE =
|
28 |
-
const MAX_ROW =
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
/**
|
31 |
* File index
|
@@ -65,6 +71,56 @@ class EmailVision_Api_BatchMemberService extends EmailVision_Api_Common
|
|
65 |
return self::$_statusOk;
|
66 |
}
|
67 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
/**
|
69 |
* Create csv files for a given list of members
|
70 |
* - you need
|
@@ -135,11 +191,11 @@ class EmailVision_Api_BatchMemberService extends EmailVision_Api_Common
|
|
135 |
$rowCount++;
|
136 |
$listMember[] = $id;
|
137 |
|
138 |
-
// If
|
139 |
if (
|
140 |
-
$fileSizeInBytes >
|
141 |
|| --$totalMemberCount == 0
|
142 |
-
|| $rowCount >=
|
143 |
) {
|
144 |
fclose($fileHandler);
|
145 |
$fileHandler = null;
|
22 |
const CSV_FIELD_ENCLOSURE = '"';
|
23 |
|
24 |
/**
|
25 |
+
* Max file size in bytes (77 Mb)
|
26 |
*/
|
27 |
+
const MAX_FILESIZE = 80000000;
|
28 |
+
const MAX_ROW = 250000;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* @var int
|
32 |
+
*/
|
33 |
+
protected $_maxFilesize = false;
|
34 |
+
protected $_maxRow = false;
|
35 |
|
36 |
/**
|
37 |
* File index
|
71 |
return self::$_statusOk;
|
72 |
}
|
73 |
|
74 |
+
/**
|
75 |
+
* Set max file size in bytes
|
76 |
+
*
|
77 |
+
* @param int $size
|
78 |
+
* @return EmailVision_Api_BatchMemberService
|
79 |
+
*/
|
80 |
+
public function setMaxFileSize($size)
|
81 |
+
{
|
82 |
+
$this->_maxFilesize = (int)$size;
|
83 |
+
return $this;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* Set max row
|
88 |
+
*
|
89 |
+
* @param int $maxRow
|
90 |
+
* @return EmailVision_Api_BatchMemberService
|
91 |
+
*/
|
92 |
+
public function setMaxRow($maxRow)
|
93 |
+
{
|
94 |
+
$this->_maxRow = (int)$maxRow;
|
95 |
+
return $this;
|
96 |
+
}
|
97 |
+
|
98 |
+
/**
|
99 |
+
* Get allowed max file size in bytes
|
100 |
+
*
|
101 |
+
* @return int
|
102 |
+
*/
|
103 |
+
public function getMaxFileSize()
|
104 |
+
{
|
105 |
+
if (!$this->_maxFilesize) {
|
106 |
+
$this->_maxFilesize = self::MAX_FILESIZE;
|
107 |
+
}
|
108 |
+
return $this->_maxFilesize;
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Get allowed max row
|
113 |
+
*
|
114 |
+
* @return int
|
115 |
+
*/
|
116 |
+
public function getMaxRow()
|
117 |
+
{
|
118 |
+
if (!$this->_maxRow) {
|
119 |
+
$this->_maxRow = self::MAX_ROW;
|
120 |
+
}
|
121 |
+
return $this->_maxRow;
|
122 |
+
}
|
123 |
+
|
124 |
/**
|
125 |
* Create csv files for a given list of members
|
126 |
* - you need
|
191 |
$rowCount++;
|
192 |
$listMember[] = $id;
|
193 |
|
194 |
+
// If file size approaches max uploadable, close file and set a new one on next turn
|
195 |
if (
|
196 |
+
$fileSizeInBytes > $this->getMaxFileSize()
|
197 |
|| --$totalMemberCount == 0
|
198 |
+
|| $rowCount >= $this->getMaxRow()
|
199 |
) {
|
200 |
fclose($fileHandler);
|
201 |
$fileHandler = null;
|
@@ -38,14 +38,14 @@ class EmailVision_Api_NotificationService extends EmailVision_Api_Common
|
|
38 |
const CURLE_OPERATION_TIMEDOUT = 28;
|
39 |
|
40 |
/**
|
41 |
-
* Connection time out for rest service - The number of seconds to wait while trying to connect.
|
42 |
*/
|
43 |
-
const REST_CONNECTION_TIME =
|
44 |
|
45 |
/**
|
46 |
* Time out for rest service - The maximum number of seconds to allow cURL functions to execute.
|
47 |
*/
|
48 |
-
const REST_TIME_OUT =
|
49 |
|
50 |
/**
|
51 |
* Convert an array of mapping into an array understandable by the webservice method sendObject
|
38 |
const CURLE_OPERATION_TIMEDOUT = 28;
|
39 |
|
40 |
/**
|
41 |
+
* Connection time out for rest service - The maximum number of seconds to wait while trying to connect.
|
42 |
*/
|
43 |
+
const REST_CONNECTION_TIME = 2;
|
44 |
|
45 |
/**
|
46 |
* Time out for rest service - The maximum number of seconds to allow cURL functions to execute.
|
47 |
*/
|
48 |
+
const REST_TIME_OUT = 3;
|
49 |
|
50 |
/**
|
51 |
* Convert an array of mapping into an array understandable by the webservice method sendObject
|
@@ -120,7 +120,10 @@ class EmailVision_Tools_File_Csv
|
|
120 |
public function fputcsv(&$handle, $fields = array(), $delimiter = ',', $enclosure = '"') {
|
121 |
$str = '';
|
122 |
$escapeChar = '\\';
|
|
|
123 |
foreach ($fields as $value) {
|
|
|
|
|
124 |
if (
|
125 |
strpos($value, $delimiter) !== false
|
126 |
|| strpos($value, $enclosure) !== false
|
@@ -132,7 +135,7 @@ class EmailVision_Tools_File_Csv
|
|
132 |
$str2 = $enclosure;
|
133 |
$escaped = 0;
|
134 |
$len = strlen($value);
|
135 |
-
for ($i=0
|
136 |
if ($value[$i] == $escapeChar) {
|
137 |
$escaped = 1;
|
138 |
} else if (!$escaped && $value[$i] == $enclosure) {
|
120 |
public function fputcsv(&$handle, $fields = array(), $delimiter = ',', $enclosure = '"') {
|
121 |
$str = '';
|
122 |
$escapeChar = '\\';
|
123 |
+
|
124 |
foreach ($fields as $value) {
|
125 |
+
// remove new line character by space
|
126 |
+
$value = preg_replace("/[\r\n]+/", ' ', $value);
|
127 |
if (
|
128 |
strpos($value, $delimiter) !== false
|
129 |
|| strpos($value, $enclosure) !== false
|
135 |
$str2 = $enclosure;
|
136 |
$escaped = 0;
|
137 |
$len = strlen($value);
|
138 |
+
for ($i=0; $i<$len; $i++) {
|
139 |
if ($value[$i] == $escapeChar) {
|
140 |
$escaped = 1;
|
141 |
} else if (!$escaped && $value[$i] == $enclosure) {
|
@@ -1,7 +1,7 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Campaign_Commander_Transactional_Email_1_5</name>
|
4 |
-
<version>3.0
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://www.opensource.org/licenses/academic.php">Academic Free License (AFL)</license>
|
7 |
<channel>community</channel>
|
@@ -19,15 +19,55 @@
|
|
19 |

|
20 |
3. Synchronize data for a complete view of the customer
|
21 |
* Automatically sychronize your Magento customer data with your SmartFocus marketing database</description>
|
22 |
-
<notes
|
|
|
|
|
|
|
23 |

|
24 |
-
|
25 |
-
|
26 |
-
*
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
27 |
<authors><author><name>SmartFocus</name><user>itgemailvision</user><email>EMVIntegrationsDevelopment@smartfocus.com</email></author></authors>
|
28 |
-
<date>2014-
|
29 |
-
<time>10:
|
30 |
-
<contents><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><file name="campaign-commander.css" hash="7a48c4846463a3710661d4e19a36f150"/></dir></dir></dir></target><target name="magelib"><dir name="EmailVision"><dir name="Api"><file name="BatchMemberService.php" hash="48443e2dd252c3f089b7f0870316f503"/><file name="Common.php" hash="aa50e6fab781d0431aece5ea77630f8b"/><file name="Exception.php" hash="fbe812474106cb6a694e2ec21d304d7b"/><file name="MemberService.php" hash="f3dc742201351e99b3eedfd06a0b9a9d"/><file name="NotificationService.php" hash="1445b72b496d61528302f12d12bd8fe2"/><file name="TransactionalService.php" hash="7aa5530026dbc8f3972b4ef543cef348"/></dir><file name="SoapClient.php" hash="a764db42192da691ab8d01aceb4d3e8d"/><dir name="Tools"><dir name="File"><file name="Csv.php" hash="4fd8516f3b80ed60a8a919d217f2e8d3"/></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><dir name="template"><dir name="email"><dir name="emailvision"><dir name="abandonment"><file name="template1.html" hash="3eda1598c50876324609c0d634526624"/><file name="template2.html" hash="3eda1598c50876324609c0d634526624"/><file name="template3.html" hash="3eda1598c50876324609c0d634526624"/></dir><dir name="datasync"><file name="cron_errors.html" hash="bbf6122128d85d2291fd291d4096b6b2"/></dir></dir></dir></dir><file name="Emv_CartAlert.csv" hash="9fc25be18876d260c0b8e56735f14713"/><file name="Emv_Core.csv" hash="33f26cf37e6ca8c3c73a0a3b82bc2d13"/><file name="Emv_DataSync.csv" hash="94d468f0f3924e7713aa8be5939094c6"/><file name="Emv_Emt.csv" hash="f1a0246d49a5a3beaba3b8033785ba99"/><file name="Emv_Report.csv" hash="5f25d083b33cd20697ac1190e626782a"/></dir><dir name="fr_FR"><file name="Emv_CartAlert.csv" hash="0acb2fa39d9199c8f31849beea6b782a"/><file name="Emv_Core.csv" hash="e73b4ad1ee7853d7fb8f949c2e295906"/><file name="Emv_DataSync.csv" hash="d5d443e8511ca960e938cf92716d3f7e"/><file name="Emv_Emt.csv" hash="490f8bf088b342b2047e723ce95f7c6a"/><file name="Emv_Report.csv" hash="f586e64852651a4524b7f27eb2c3cd6a"/></dir></target><target name="mageetc"><dir name="modules"><file name="Emv_CartAlert.xml" hash="7c23ed23c48254c30e4aad7c11db1b62"/><file name="Emv_Core.xml" hash="e25dd0ea40fad09e0d1f6260f46e65ac"/><file name="Emv_DataSync.xml" hash="089e2b362da3cb466e1ba2dc79e63289"/><file name="Emv_Emt.xml" hash="d1e26edb25bce0b78e6c14792c07ac03"/><file name="Emv_Report.xml" hash="b41b407bbd282fc33e0bf6970082a08b"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="emailvision"><file name="abandonment_report.xml" hash="f60cff6610a8ea2756b9ae4139688a1d"/></dir></dir><dir name="template"><dir name="emailvision"><dir name="abandonment"><dir name="grid"><file name="container.phtml" hash="3375ac98f71cab4a81bb59ef64b3d6fc"/></dir></dir><dir name="account"><file name="associated_urls.phtml" hash="b0f41cede2009e3728c819403cb28426"/></dir><dir name="datasync"><dir name="system"><dir name="config"><dir name="form"><dir name="field"><file name="array.phtml" hash="e809c2a4c2aecc27f5ec3f51faed3c0a"/></dir></dir><file name="getfields.phtml" hash="e5680827bf0c2955b252d0f711dc90e8"/></dir></dir></dir><dir name="emt"><dir name="template"><file name="common_js.phtml" hash="b91b877122f3d48728c5c97423c3eb42"/><file name="edit.phtml" hash="f09b248f3187d2f83c90765ad17b7413"/><file name="mapped_attributes.phtml" hash="be2ea5d80b24ad044e351607aa76932e"/></dir></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="emailvision"><file name="abandonment.xml" hash="c6f5b8cf0aec8cd0ac881b58167ff234"/></dir></dir><dir name="template"><dir name="emailvision"><dir name="abandonment"><file name="customer.phtml" hash="d63198ab64858039aa5b23f9964dd6d3"/><dir name="reminder"><file name="items.phtml" hash="c2e0211ac4c28d81c14199ecb7450a79"/></dir></dir></dir></dir></dir></dir></dir></target><target name="magecommunity"><dir name="Emv"><dir name="CartAlert"><dir name="Block"><dir name="Cart"><file name="Items.php" hash="a6a99b56060cb4254a384e5c4eaef467"/></dir><dir name="Customer"><file name="Abandonment.php" hash="06dd3435302590f774d29271cea4d76e"/></dir></dir><file name="Constants.php" hash="b10c0a770bf2075a30408b54dc4b9824"/><dir name="Helper"><file name="Data.php" hash="25185f79349a728a0ce684829c59e720"/></dir><dir name="Model"><file name="Abandonment.php" hash="ac7111c71d744dfc9713ae2894b41cc8"/><dir name="Mysql4"><dir name="Abandonment"><file name="Collection.php" hash="4f06a6c5528ff4d067dd963bab96fca2"/></dir><file name="Abandonment.php" hash="ef528abb65db08c6bed6f99cbe0947ca"/><dir name="Orderflag"><file name="Collection.php" hash="3fc55bad9566113db73b6e7632af4ec7"/></dir><file name="Orderflag.php" hash="5163bd389466708b84001fbeb85af913"/><dir name="Stats"><file name="Collection.php" hash="24178657849cf0bdffd939816f3c8ba9"/></dir><file name="Stats.php" hash="a54399b037a210a719abba376b0415bc"/></dir><file name="Observer.php" hash="768f5503d719f58c885c6ac7a202cb93"/><file name="Orderflag.php" hash="5a6e33fce2512ba3f4ee93e90fc6f4e8"/><dir name="Resource"><file name="Setup.php" hash="0724e1d2ed5fd1b5ef93a2a267a4ee21"/></dir><file name="Stats.php" hash="33e9f3578d961cd3db55ade1df61ef7b"/></dir><dir name="controllers"><file name="CustomerController.php" hash="5c042b38b1a0dedd46cb7403ea9371cb"/><file name="GuestController.php" hash="8fa642676dc3fc057c44d1d870ff1f37"/></dir><dir name="etc"><file name="adminhtml.xml" hash="c28a61bac9988480fb403007daba54ee"/><file name="config.xml" hash="874654c8b45830a2adf94d96b9311c04"/><file name="system.xml" hash="3fa7067de36957004c16bb753058af65"/></dir><dir name="sql"><dir name="abandonment_setup"><file name="mysql4-install-0.1.0.php" hash="ee9bc7cabf23bec2867ee1394562ce27"/><file name="mysql4-upgrade-0.1.0-0.2.0.php" hash="d77033018e89d437a229ef462c786f97"/><file name="mysql4-upgrade-0.2.0-0.3.0.php" hash="3ad1df3e579e6a5d1c18aa09f764937b"/><file name="mysql4-upgrade-0.3.0-0.4.0.php" hash="b2c7e93739a101f6f844db6f3548b080"/><file name="mysql4-upgrade-0.4.0-0.5.0.php" hash="7403b4f3b3edcc8665e85f3571abb58f"/><file name="mysql4-upgrade-0.5.0-0.5.1.php" hash="c893dd6a2b0d2304204dabf0659cc75c"/><file name="mysql4-upgrade-0.5.1-0.5.2.php" hash="35d81990131a6e9cd0bec82eeb8cbe68"/></dir></dir></dir><dir name="Core"><dir name="Block"><dir name="Adminhtml"><dir name="Account"><dir name="Edit"><file name="AssociatedUrls.php" hash="4879c49496102f0f152f589249817fad"/><file name="Form.php" hash="64420bd3f05f502d84673aaf6fa0f1e9"/></dir><file name="Edit.php" hash="7817ac5fbe3d641c6e4bd49ea1a4cc45"/><file name="Grid.php" hash="d7d869a26decc54beb2fbc9574c10b00"/></dir><file name="Accounts.php" hash="078f85d162665246cf6d475b4c6cbc16"/></dir></dir><dir name="Helper"><file name="Data.php" hash="f493849c2a6261c3a232f489caba8b44"/></dir><dir name="Model"><file name="Account.php" hash="0ca3e88df84a27c8986c0836c9d39b74"/><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Backend"><dir name="Account"><file name="Abstract.php" hash="d2b7f88918b2034284ce7ae042133229"/></dir><file name="Enabled.php" hash="b5b9c77a30d98097777dac3434d381b3"/></dir></dir></dir></dir><dir name="Mysql4"><dir name="Account"><file name="Collection.php" hash="f9dbdbb023051a3e412be801e7c1d5ec"/></dir><file name="Account.php" hash="b7949c5e00cb29efe2b067087933c6a4"/></dir><dir name="Resource"><file name="Setup.php" hash="1aed96e7fe8c8cb06b27b5ef56f8822f"/></dir><dir name="Service"><file name="Abstract.php" hash="6dca2afd30b6f2f3c23234663da6335f"/><file name="BatchMember.php" hash="b6cc28b33e169b40ddbb37b093cf13a1"/><file name="Member.php" hash="b46d65f710d9dbee42e8f805006b65b8"/><file name="Notification.php" hash="fd131bf3071e3b7b0614036ca3f76c63"/><file name="Transactional.php" hash="b16beffebe860b071110013b3d3d0571"/></dir><dir name="System"><dir name="Config"><dir name="Source"><file name="Account.php" hash="8e5ce5e669d481188c7e13cfee510697"/></dir></dir></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="AccountController.php" hash="545158a529f9b3ac17d5ab02fee354e3"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="e8f219eefa333cc503c48b0c1586d403"/><file name="config.xml" hash="cbd11a1571fb5b72185ab1a00c2cd7fd"/><file name="system.xml" hash="85d9908f748a15c6247582418a1b606c"/></dir><dir name="sql"><dir name="emvcore_setup"><file name="mysql4-install-0.1.0.php" hash="b1319057a975d8dd2c829d6c00affc74"/><file name="mysql4-upgrade-0.1.0-0.2.0.php" hash="af4506f20cd8cdfa11c0394fdd78a06c"/></dir></dir></dir><dir name="DataSync"><dir name="Block"><dir name="Adminhtml"><dir name="Form"><dir name="Field"><file name="CustomerAttributes.php" hash="c6add4119550dae8a1d3db4e5bca9683"/><file name="EmailVisionFields.php" hash="67d9bb70184bd844cba669d4ac5c04ed"/></dir></dir><dir name="System"><dir name="Config"><file name="CustomerAttributes.php" hash="7508f9dc0df62e5c9faf9accd3361765"/><file name="Date.php" hash="1790331bd1bb06a441737ecf345df6da"/><file name="GetFields.php" hash="75291de3c2c5e0338e8c6069066264f5"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="7e3b1646ab8b9330f5585cf0a57661fb"/><file name="Service.php" hash="8f459e115ba5d2fbeba937852189e28b"/></dir><dir name="Model"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Backend"><dir name="ApiMember"><file name="Account.php" hash="09cfe4b6651eae737945ab16b25ce6bb"/><file name="Cron.php" hash="1e7a38db39c21d04b0249ec181c1993f"/><file name="Enabled.php" hash="19e91d89fa6a098010ea4d9582b72451"/></dir><dir name="BatchMember"><file name="Account.php" hash="844f3af6efd125d6b1d9ef8808984e79"/><file name="Cron.php" hash="572c1d835574039a9287da6760b7111d"/><file name="Enabled.php" hash="b00cce598c212933cc2fe1db4cc4d4b4"/></dir><dir name="Clean"><file name="Cron.php" hash="1e55644bb34417d3285bf9bca0aee646"/></dir></dir><dir name="Source"><file name="Fields.php" hash="5f469c279ddabaa6f1142616e6106089"/><file name="MemberCronTime.php" hash="0ed64e65649d2f8b783fcf2fb19f49f8"/></dir></dir></dir></dir><file name="Cron.php" hash="52bcf45cdad1c6d89f64ef242a5b085b"/><file name="Observer.php" hash="30d2a4ece7ebcf68ef04aa2caa74076c"/><dir name="Service"><file name="BatchMember.php" hash="de66836efdf1a913ce285f979c2930e7"/><file name="Member.php" hash="28176c130e55ee07fb93ece9c918c0af"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="DataSyncController.php" hash="c4e46f74ea35132f564587c798cc88cc"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="0d0ba154e5cf38895a2b2b0d907797fb"/><file name="config.xml" hash="331af61703669c4c1dca3c93899c6602"/><file name="system.xml" hash="4d5cf9fe165760476ccb273ea5693f26"/></dir><dir name="sql"><dir name="emvdatasync_setup"><file name="mysql4-install-0.0.1.php" hash="073ecf5a0c8aae1572e3ac91a35633ff"/></dir></dir></dir><dir name="Emt"><dir name="Block"><dir name="Adminhtml"><dir name="Log"><dir name="Grid"><dir name="Renderer"><file name="GetError.php" hash="a7fb7e3075e611b0e5b672d0ecee3ddd"/></dir></dir><file name="Grid.php" hash="82ca5fdaeb5403c0a39fe1b17e0d9958"/></dir><file name="Log.php" hash="24551f106915450e8e775b2bb1324451"/><dir name="Resending"><file name="Grid.php" hash="f56672b844f848df3414668ffa2855c5"/></dir><file name="Resending.php" hash="beaad1da5f136d403f8881e21dc9639e"/><dir name="Template"><dir name="Edit"><dir name="Tab"><file name="EmvContent.php" hash="a540805b70ec00fc6b5cdcc32b1a1cfb"/><file name="EmvDyn.php" hash="2c3f5c8f739691b3eeb6d53de6b64e46"/><file name="General.php" hash="776675c177b6a147fd90c5c6d8a3e601"/></dir><file name="Tabs.php" hash="320b4c3e740ba5aacbbd5c602ffb041c"/></dir><file name="Edit.php" hash="5c672e813e76cf81755c80f54c78ea13"/><dir name="Grid"><dir name="Renderer"><file name="Emvname.php" hash="1cf0f98ad194b33c4d9c91f0195c8146"/><file name="MageTemplate.php" hash="e284d93be818c24016bd462e31c226ee"/></dir></dir><file name="Grid.php" hash="19ab59d96e2925d6fe2b14aad3111498"/></dir><file name="Templates.php" hash="12bcab5abc0be49e4e04b0d92eecf61c"/></dir></dir><dir name="Helper"><file name="Data.php" hash="067567bd92ed2d9c5ccd0c2f2d7d8cd2"/><file name="Emvtemplate.php" hash="97463f51b60d133d30d0e3655486b9d0"/></dir><dir name="Model"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Backend"><file name="Account.php" hash="301e5056ac13f4d00ba5c047a6eb79a8"/></dir></dir></dir></dir><file name="Attribute.php" hash="b0c369fcc0bc47f48ba7c5866dc72260"/><file name="Cron.php" hash="c5cec405088a1b951d2767309adf3461"/><file name="Emt.php" hash="45ca86eb4dfa46ce78a53f9f66d79bb2"/><file name="Log.php" hash="16a2e7e2bd1039f39a66d9fb61a324e9"/><dir name="Mage"><dir name="Core"><dir name="Email"><file name="Template.php" hash="e5c31cf93c5b2aa0b88e8176463f5a77"/></dir></dir></dir><file name="MageTemplate.php" hash="ddf98c89b163c6e59ceed1ac5dbe8f69"/><file name="Mailmode.php" hash="e08c76d5d72b21d3bd8b6b441ec06527"/><dir name="Mysql4"><dir name="Attribute"><file name="Collection.php" hash="3e3308be1178e99162606a668eace8ed"/></dir><file name="Attribute.php" hash="bd2854ed8ee4fb207b994543a0ecf9ba"/><dir name="Emt"><file name="Collection.php" hash="bbc3368b7276bbff83c1770b6a097c26"/></dir><file name="Emt.php" hash="7fd5ff6b090587b56ac09366289b369f"/><dir name="Log"><file name="Collection.php" hash="dc04e8d73fa3df064453f7c7ee12a400"/></dir><file name="Log.php" hash="f379a53b42152472dded21708572bce8"/><dir name="Resending"><dir name="Queue"><dir name="Message"><file name="Collection.php" hash="8b165985970886c74aef0c9d62140098"/></dir><file name="Message.php" hash="63b4e07ee46f64d7f1c8284f5f789f71"/></dir></dir></dir><dir name="Resending"><dir name="Queue"><file name="Message.php" hash="4830bc5ef750efcd8973ee46f424ec51"/></dir><file name="Queue.php" hash="bb2128bf1a9ecd5cf9fb8d06f8de845b"/><file name="Rule.php" hash="3accdc868f171f3a328e41658871e31c"/></dir><dir name="Resource"><file name="Setup.php" hash="b5fc87772ed86c16c54eb9262dd291a3"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="LogController.php" hash="05fbabe704020cddc12a8656cc9220bd"/><file name="RescheduleController.php" hash="5331244d0bb14e448fbde3b797fb680d"/><file name="TemplateController.php" hash="71c335b0d6455bc51ba9f9e45d7639a4"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="193ed52e7bc6f002b4526d697166c84d"/><file name="config.xml" hash="f6fed0b59662a2b43b9271d9d3a9a046"/><file name="system.xml" hash="a6293b65fc0e398db437e443a992c3cc"/></dir><dir name="sql"><dir name="emvemt_setup"><file name="mysql4-install-0.1.0.php" hash="a7d12df049f2c1377a072fa7899dcb6c"/><file name="mysql4-upgrade-0.1.0-0.2.0.php" hash="3b52221a751b221ae98e16a03807335a"/><file name="mysql4-upgrade-0.2.0-0.3.0.php" hash="0108cecb8c995004987e869fc008bf34"/><file name="mysql4-upgrade-0.3.0-0.4.0.php" hash="7ef46dc220aeb7265ef43cab5b17156f"/><file name="mysql4-upgrade-0.4.0-0.4.1.php" hash="a6eb1e85d8773af9c0935bacabcc06dd"/></dir></dir></dir><dir name="Report"><dir name="Block"><dir name="Adminhtml"><dir name="Conversion"><file name="Form.php" hash="9c537aa62d666816058130d257f75bb8"/></dir><file name="Conversion.php" hash="79959891324dcc99448d93f9cfa01724"/><dir name="Details"><file name="Grid.php" hash="beb3a98688d554cb8d49aa5a8613bd5a"/></dir><file name="Details.php" hash="a765998cb0a765423f89cd652a2d1dab"/></dir></dir><dir name="Helper"><file name="Data.php" hash="14fd1c74a2de74a85190394166c1e684"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="ConversionController.php" hash="638f3ad969d3bc9fcec2f8e7b5c14854"/><file name="DetailsController.php" hash="653096279fbe200d6b5ac6208efe732a"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="973a0f60081aba81dc048f7a67963954"/><file name="config.xml" hash="f5a9c3e32da692808072c07be851a7de"/></dir></dir></dir><dir name="Mage"><dir name="SalesRule"><dir name="Helper"><file name="Coupon.php" hash="05d42b935bd31dad39c9e31052ef60c8"/></dir><dir name="Model"><dir name="Coupon"><file name="Massgenerator.php" hash="c5312f2a745bf79d2a8ac90c23fb79dc"/></dir><dir name="System"><dir name="Config"><dir name="Source"><dir name="Coupon"><file name="Format.php" hash="64236cb46364219d4a5702521898a249"/></dir></dir></dir></dir></dir></dir></dir></target></contents>
|
31 |
<compatible/>
|
32 |
<dependencies><required><php><min>5.2.6</min><max>5.5.4</max></php></required></dependencies>
|
33 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>Campaign_Commander_Transactional_Email_1_5</name>
|
4 |
+
<version>3.1.0</version>
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://www.opensource.org/licenses/academic.php">Academic Free License (AFL)</license>
|
7 |
<channel>community</channel>
|
19 |

|
20 |
3. Synchronize data for a complete view of the customer
|
21 |
* Automatically sychronize your Magento customer data with your SmartFocus marketing database</description>
|
22 |
+
<notes>General Enhancement :
|
23 |
+
* A list of the status of prerequisites and extensions is now available in the SmartFocus menu of the System Configuration section.
|
24 |
+
* Cron jobs can now be configured to run on specific days of the week or on a specific day of the month.
|
25 |
+
* The cron job processes scheduled in the Magento Connector can now be restarted even if a previous cron job process encountered an error and did not close. 
|
26 |

|
27 |
+
Data Synchronization : 
|
28 |
+
* Data synchronization can now be configured to synchronize based on member email addresses.
|
29 |
+
* The data synchronization process now runs faster than in previous versions of the Magento Connector.
|
30 |
+
* You can now configure data synchronization for different stores with different SmartFocus accounts.
|
31 |
+
* In the Mapping feature:
|
32 |
+
** fields have been arranged into different categories,
|
33 |
+
** the following new fields for Calculated Purchase Information category have been added:
|
34 |
+
Used Email Addresses
|
35 |
+
Base Currency Code
|
36 |
+
List of Order #
|
37 |
+
Total Orders Purchased
|
38 |
+
Total Items Purchased
|
39 |
+
Average Items Purchased per Order
|
40 |
+
Total Order Amount Spent
|
41 |
+
Average Order Amount Spent per Purchase
|
42 |
+
Total Discount Amount
|
43 |
+
Average Discount Amount per Purchase
|
44 |
+
Total Shipping Amount
|
45 |
+
Average Shipping Amount per Purchase
|
46 |
+
Minimum Purchase Total
|
47 |
+
Maximum Purchase Total
|
48 |
+
First Purchase
|
49 |
+
Last Purchase
|
50 |
+
Minimum Items Purchased
|
51 |
+
Maximum Items Purchased
|
52 |
+
Shipping Methods
|
53 |
+
Payment Methods
|
54 |
+
Used Coupons
|
55 |
+
Total Purchases With Discount 
|
56 |
+
* The menu Data Process List has been added to the Magento Connector, allowing you to monitor the progress of your scheduled synchronizations at a glance. 
|
57 |
+

|
58 |
+
Transactional Emails 
|
59 |
+
* You can now verify that your SmartFocus account is compatible with the Magento Connector in the Transactional Messages (NMP) menu and configure your account if you have modified the credentials for your account.
|
60 |
+
* A log clean-up process has been created. 
|
61 |
+

|
62 |
+

|
63 |
+
Abandoned Carts Feature
|
64 |
+
* You can now process more than 8,000 abandoned carts simultaneously.
|
65 |
+
* You can now enable the test mode to send abandoned cart reminders in minutes rather than hours, and configure how long the cart will be able to receive reminders in hours.
|
66 |
+
* In the new menu 'List in the Abandoned Cart menu, you can access the list of abandoned cart reminder information. </notes>
|
67 |
<authors><author><name>SmartFocus</name><user>itgemailvision</user><email>EMVIntegrationsDevelopment@smartfocus.com</email></author></authors>
|
68 |
+
<date>2014-06-09</date>
|
69 |
+
<time>09:10:14</time>
|
70 |
+
<contents><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><file name="campaign-commander.css" hash=""/><file name="smartfocus.css" hash="a01e61afdefd15460460cc2b4c0d256a"/><dir name="images"><dir name="smartfocus"><file name="tick.png" hash="9fb629c79fc4a487088ac4aeeb23e40b"/><file name="untick.gif" hash="017f884ab4a0fe9292b264bd0e219aa9"/><file name="warning.png" hash="aa8b5badc048b2e7111c8ec4bfcf7483"/></dir></dir></dir></dir></dir></target><target name="magelib"><dir name="EmailVision"><dir name="Api"><file name="BatchMemberService.php" hash="3aca1b0b9d1a7cb45a2063a33129d5d5"/><file name="Common.php" hash="aa50e6fab781d0431aece5ea77630f8b"/><file name="Exception.php" hash="fbe812474106cb6a694e2ec21d304d7b"/><file name="MemberService.php" hash="f3dc742201351e99b3eedfd06a0b9a9d"/><file name="NotificationService.php" hash="d5bd7b97e7272a015ceb0fffd9316fc1"/><file name="TransactionalService.php" hash="7aa5530026dbc8f3972b4ef543cef348"/></dir><file name="SoapClient.php" hash="a764db42192da691ab8d01aceb4d3e8d"/><dir name="Tools"><dir name="File"><file name="Csv.php" hash="843067dfbf1c5269661b02ec7b6b29de"/></dir></dir></dir></target><target name="magelocale"><dir name="en_US"><dir name="template"><dir name="email"><dir name="smartfocus"><dir name="abandonment"><file name="template1.html" hash="3eda1598c50876324609c0d634526624"/><file name="template2.html" hash="3eda1598c50876324609c0d634526624"/><file name="template3.html" hash="3eda1598c50876324609c0d634526624"/></dir><dir name="datasync"><file name="cron_errors.html" hash="f480c390cc733b7e0fd76198358a8af4"/></dir></dir></dir></dir><file name="Emv_CartAlert.csv" hash="cd92c0dac35ff9a37c5658c159ad9ad1"/><file name="Emv_Core.csv" hash="19398a647210dbadb44f1bab5120b1d5"/><file name="Emv_DataSync.csv" hash="e20d8614368bdb0f97935632ecfc2cea"/><file name="Emv_Emt.csv" hash="ea0dae37802a0ef00f92b77a2e033a50"/><file name="Emv_Report.csv" hash="5f25d083b33cd20697ac1190e626782a"/></dir><dir name="fr_FR"><file name="Emv_CartAlert.csv" hash="5d7c80d74dfc1f444c3c7a3e5c59dc04"/><file name="Emv_Core.csv" hash="6427a15fe17908c9fda4c2f643ccd8a8"/><file name="Emv_DataSync.csv" hash="48d852a65fa6835787b10f341fc6f853"/><file name="Emv_Emt.csv" hash="24ccd134f052439239a3688aaa41f219"/><file name="Emv_Report.csv" hash="5728ce4bb676a9351d0922ff9843dc4c"/></dir></target><target name="mageetc"><dir name="modules"><file name="Emv_CartAlert.xml" hash="7c23ed23c48254c30e4aad7c11db1b62"/><file name="Emv_Core.xml" hash="e25dd0ea40fad09e0d1f6260f46e65ac"/><file name="Emv_DataSync.xml" hash="089e2b362da3cb466e1ba2dc79e63289"/><file name="Emv_Emt.xml" hash="d1e26edb25bce0b78e6c14792c07ac03"/><file name="Emv_Report.xml" hash="b41b407bbd282fc33e0bf6970082a08b"/></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="smartfocus"><file name="abandonment_report.xml" hash="4a0422b60e5c5402bd84f78fd038d6fe"/><file name="core.xml" hash="e167045d8ae09689cfcb8235970dbc2a"/></dir></dir><dir name="template"><dir name="smartfocus"><dir name="abandonment"><dir name="grid"><file name="container.phtml" hash="3375ac98f71cab4a81bb59ef64b3d6fc"/></dir></dir><dir name="account"><file name="associated_urls.phtml" hash="b0f41cede2009e3728c819403cb28426"/></dir><dir name="cartalert"><dir name="system"><dir name="config"><file name="promo_rule.phtml" hash="f3951f3e4e4142743f68bef73a3a00bf"/></dir></dir></dir><dir name="config"><file name="extension_status.phtml" hash="968f83f3cddc81582b2214049cdb5d76"/></dir><dir name="datasync"><dir name="system"><dir name="config"><dir name="form"><dir name="field"><file name="array.phtml" hash="e809c2a4c2aecc27f5ec3f51faed3c0a"/></dir></dir><file name="getfields.phtml" hash="3eb4952d74ec7fcf688324b0075b5b97"/></dir></dir></dir><dir name="emt"><dir name="system"><dir name="config"><file name="account_validation.phtml" hash="8c978f3afe3ed3a0ee4d4cffb1106449"/></dir></dir><dir name="template"><file name="common_js.phtml" hash="b91b877122f3d48728c5c97423c3eb42"/><file name="edit.phtml" hash="f09b248f3187d2f83c90765ad17b7413"/><file name="mapped_attributes.phtml" hash="be2ea5d80b24ad044e351607aa76932e"/></dir></dir></dir></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="smartfocus"><file name="abandonment.xml" hash="b455deed2daab8c61fdeb9efdd339ce3"/></dir></dir><dir name="template"><dir name="smartfocus"><dir name="abandonment"><file name="customer.phtml" hash="d63198ab64858039aa5b23f9964dd6d3"/><dir name="reminder"><file name="items.phtml" hash="9139b91b3741db43aa60020e3764d0a7"/></dir></dir></dir></dir></dir></dir></dir></target><target name="magecommunity"><dir name="Emv"><file name="CHANGELOG" hash="091cadf2668aa522c5b01e230cb191b4"/><dir name="CartAlert"><dir name="Block"><dir name="Adminhtml"><dir name="List"><dir name="Grid"><dir name="Column"><dir name="Renderer"><file name="Currency.php" hash="cdca5ab59c34296803dbca2d60a22860"/></dir></dir></dir><file name="Grid.php" hash="797337ce3b749215540eeb9950daca02"/></dir><file name="List.php" hash="e3c1cc7e8602c882d9cd116df6e411a7"/><dir name="Quote"><file name="Grid.php" hash="693103ebe4a66130c54d23900b7fd091"/></dir><file name="Quote.php" hash="7fc83c25075b054bdd100ef6bdbdf61a"/><dir name="System"><dir name="Config"><file name="PromoRule.php" hash="f8aa6fc6087cde870648082f1dfce95f"/></dir></dir></dir><dir name="Cart"><file name="Items.php" hash="2cc9a9938786d5cecf96c7420bf8e67c"/></dir><dir name="Customer"><file name="Abandonment.php" hash="06dd3435302590f774d29271cea4d76e"/></dir></dir><file name="Constants.php" hash="2ab5ea9260640bed0fedfb8ba5d5e07b"/><dir name="Helper"><file name="Data.php" hash="de6ddbe68f2d54a96154628ed6f1521c"/></dir><dir name="Model"><file name="Abandonment.php" hash="ac7111c71d744dfc9713ae2894b41cc8"/><dir name="Mysql4"><dir name="Abandonment"><file name="Collection.php" hash="4f06a6c5528ff4d067dd963bab96fca2"/></dir><file name="Abandonment.php" hash="ef528abb65db08c6bed6f99cbe0947ca"/><dir name="Orderflag"><file name="Collection.php" hash="3fc55bad9566113db73b6e7632af4ec7"/></dir><file name="Orderflag.php" hash="5163bd389466708b84001fbeb85af913"/><dir name="Stats"><file name="Collection.php" hash="24178657849cf0bdffd939816f3c8ba9"/></dir><file name="Stats.php" hash="a54399b037a210a719abba376b0415bc"/></dir><file name="Observer.php" hash="3b3c7564754b4988c7131c747f628022"/><file name="Orderflag.php" hash="5a6e33fce2512ba3f4ee93e90fc6f4e8"/><dir name="Resource"><file name="Setup.php" hash="0724e1d2ed5fd1b5ef93a2a267a4ee21"/></dir><file name="Stats.php" hash="33e9f3578d961cd3db55ade1df61ef7b"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="AbandonmentController.php" hash="6901bbc8ae461ee6cb884df01ef9f467"/></dir><file name="CustomerController.php" hash="5c042b38b1a0dedd46cb7403ea9371cb"/><file name="GuestController.php" hash="8fa642676dc3fc057c44d1d870ff1f37"/></dir><dir name="etc"><file name="adminhtml.xml" hash="2e56a9df99da4eea8e587e3d7694fde8"/><file name="config.xml" hash="9eced8b4ba1b86e58963330fc3a3407c"/><file name="system.xml" hash="67f22e901da002039f599570aeda1d74"/></dir><dir name="sql"><dir name="abandonment_setup"><file name="mysql4-install-0.1.0.php" hash="ee9bc7cabf23bec2867ee1394562ce27"/><file name="mysql4-upgrade-0.1.0-0.2.0.php" hash="d77033018e89d437a229ef462c786f97"/><file name="mysql4-upgrade-0.2.0-0.3.0.php" hash="3ad1df3e579e6a5d1c18aa09f764937b"/><file name="mysql4-upgrade-0.3.0-0.4.0.php" hash="b2c7e93739a101f6f844db6f3548b080"/><file name="mysql4-upgrade-0.4.0-0.5.0.php" hash="7403b4f3b3edcc8665e85f3571abb58f"/><file name="mysql4-upgrade-0.5.0-0.5.1.php" hash="c893dd6a2b0d2304204dabf0659cc75c"/><file name="mysql4-upgrade-0.5.1-0.5.2.php" hash="35d81990131a6e9cd0bec82eeb8cbe68"/><file name="mysql4-upgrade-0.5.2-0.5.3.php" hash="d2e1816a3165241e61142506425a24b5"/><file name="mysql4-upgrade-0.5.3-0.5.4.php" hash="f43b364613d900c6d14ada3e41d1acc6"/></dir></dir></dir><dir name="Core"><dir name="Block"><dir name="Adminhtml"><dir name="Account"><dir name="Edit"><file name="AssociatedUrls.php" hash="648a706a7434c01d5206b1cace7d7afa"/><file name="Form.php" hash="64420bd3f05f502d84673aaf6fa0f1e9"/></dir><file name="Edit.php" hash="7817ac5fbe3d641c6e4bd49ea1a4cc45"/><file name="Grid.php" hash="d7d869a26decc54beb2fbc9574c10b00"/></dir><file name="Accounts.php" hash="078f85d162665246cf6d475b4c6cbc16"/><dir name="Config"><file name="ExtensionStatus.php" hash="6bb415f6c5615db0e02ad1e64f6745dd"/></dir><dir name="DataProcessing"><dir name="Process"><dir name="Grid"><dir name="Column"><dir name="Renderer"><file name="Links.php" hash="3bf7651e1898d36a3e39abde0dfb7a6d"/><file name="Output.php" hash="d3053e0ac56aac200e49f453ce7f403a"/></dir></dir></dir><file name="Grid.php" hash="f4cff586e899709902f9e26aff0520fb"/></dir><file name="Process.php" hash="3c5053cd7a0eef6ad6fd2e2d78f3fc07"/></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="aadeed8ac77c3430c9d982568c375803"/></dir><dir name="Model"><file name="Account.php" hash="1d8f3e158c0622caba50131886d7f771"/><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Backend"><dir name="Account"><file name="Abstract.php" hash="9d92fbd42157a62472a145c88bb032a0"/></dir><file name="Cron.php" hash="b34d3ace2db9784cc27e8efd4a483c38"/><file name="Enabled.php" hash="b5b9c77a30d98097777dac3434d381b3"/></dir><dir name="Source"><file name="Account.php" hash="46dbc9d51348e04cc5a052c97af0328c"/><file name="CronDate.php" hash="95205d5ebe42cff980390646ad072d8a"/><file name="CronDay.php" hash="604b0e9c32a03fdba91a2ed09747fb24"/></dir></dir></dir></dir><dir name="DataProcessing"><file name="Exception.php" hash="0cd21857de30348ee36f6f494a358a1a"/><dir name="Process"><file name="Log.php" hash="05eecaa8cff9719b229d0454bbd97100"/></dir><file name="Process.php" hash="c1318749346daae89912051b54413df7"/><dir name="Profile"><file name="Interface.php" hash="8a9f763fcce353aed2b57e4ec10a4ec2"/></dir><file name="Profile.php" hash="bb45569a4c72bbdb68199e2167b27a54"/></dir><dir name="Mysql4"><dir name="Account"><file name="Collection.php" hash="f9dbdbb023051a3e412be801e7c1d5ec"/></dir><file name="Account.php" hash="b7949c5e00cb29efe2b067087933c6a4"/><dir name="DataProcessing"><dir name="Process"><file name="Collection.php" hash="be74cb9e732fc382af4b1ed27bf00a2c"/></dir><file name="Process.php" hash="ed751ed6cae58c83af340e1bd34ce774"/></dir></dir><dir name="Resource"><file name="Setup.php" hash="1aed96e7fe8c8cb06b27b5ef56f8822f"/></dir><dir name="Service"><file name="Abstract.php" hash="8bf7819516d9c07dcd1d96effd1c923e"/><file name="BatchMember.php" hash="b6cc28b33e169b40ddbb37b093cf13a1"/><file name="Member.php" hash="b46d65f710d9dbee42e8f805006b65b8"/><file name="Notification.php" hash="40dfc88a9db3dbfbda6b712ed90b03b0"/><file name="Transactional.php" hash="6b4caa0898a437a1cf75256a71610506"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="AccountController.php" hash="6b36539b47115ac5f8f752e7cb4f75de"/><file name="DataProcessingController.php" hash="3d7c50f4157b64c064ddb80c6c9bf8ff"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="4d34e179b76354ddef639fcb5463977c"/><file name="config.xml" hash="b68de4615e2ab7844c135c5e2e58062e"/><file name="system.xml" hash="85d9908f748a15c6247582418a1b606c"/></dir><file name="functions.php" hash="66186dbf8024c0c2a0b291495d406c89"/><dir name="sql"><dir name="emvcore_setup"><file name="mysql4-install-0.1.0.php" hash="b1319057a975d8dd2c829d6c00affc74"/><file name="mysql4-upgrade-0.1.0-0.2.0.php" hash="af4506f20cd8cdfa11c0394fdd78a06c"/><file name="mysql4-upgrade-0.2.0-0.3.0.php" hash="faf42db141fd0e3a06916f33c9a7d5c6"/></dir></dir></dir><dir name="DataSync"><dir name="Block"><dir name="Adminhtml"><dir name="Form"><dir name="Field"><file name="CustomerAttributes.php" hash="0d7abe47b8c6af18d09d674f97df2dc7"/><file name="EmailVisionFields.php" hash="67d9bb70184bd844cba669d4ac5c04ed"/></dir></dir><dir name="Newsletter"><dir name="Subscriber"><file name="Grid.php" hash="d39d0f8cf8941e6eb2468838370d1578"/></dir><file name="Subscriber.php" hash="cd11fa85a33c2a5e10f497bfcf13db78"/></dir><dir name="System"><dir name="Config"><file name="CustomerAttributes.php" hash="4e5445a45a0ee3ddad4256dea2fdaa01"/><file name="Date.php" hash="1790331bd1bb06a441737ecf345df6da"/><file name="GetFields.php" hash="88dba41a38becc0861c172ddc6440893"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="45c8c81ecd1b5d87c46574c8c16c637b"/><file name="Service.php" hash="da0481194392ee400d5f030b0b958266"/></dir><dir name="Model"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Backend"><dir name="ApiMember"><file name="Account.php" hash="09cfe4b6651eae737945ab16b25ce6bb"/><file name="Cron.php" hash="1e7a38db39c21d04b0249ec181c1993f"/><file name="Enabled.php" hash="19e91d89fa6a098010ea4d9582b72451"/></dir><dir name="BatchMember"><file name="Account.php" hash="844f3af6efd125d6b1d9ef8808984e79"/><file name="Cron.php" hash="8b9dcd2ee474d2b779de240c000b1d82"/><file name="Enabled.php" hash="b00cce598c212933cc2fe1db4cc4d4b4"/></dir><dir name="Clean"><file name="Cron.php" hash="728bd3cfe90b303dd7944684d92748b7"/></dir><dir name="PurchaseProcess"><file name="Cron.php" hash="87c3e0a93e97bd9d10c685f140e46c8f"/></dir></dir><dir name="Source"><file name="Fields.php" hash="5f469c279ddabaa6f1142616e6106089"/><file name="MemberCronTime.php" hash="0ed64e65649d2f8b783fcf2fb19f49f8"/></dir></dir></dir></dir><dir name="AttributeProcessing"><file name="Config.php" hash="4dba5219305e882461a71b93ba80bf55"/><dir name="Handler"><file name="Abstract.php" hash="de180f7fcc0b4e0bff2980814a6d34e8"/><file name="Customer.php" hash="4235914c273f56ed183faeb7d9814604"/><file name="Newsletter.php" hash="7569eb7038d47432eb3aaba7ee6dd310"/><file name="PurchaseInformation.php" hash="9d9525d1e66d0aeeeec0b36ee964c47e"/></dir></dir><file name="Cron.php" hash="fd73cc2fa685b60b7f772a008b21c5c0"/><dir name="DataProcess"><file name="PurchaseInformation.php" hash="390c8d87f7f3570e8f452cf157ce8717"/></dir><dir name="Mysql4"><dir name="DataProcess"><dir name="PurchaseInformation"><file name="Collection.php" hash="48d6087490407cf456cfc7342bbe9e98"/></dir><file name="PurchaseInformation.php" hash="788e7740eb558b474c826dc89bc20723"/></dir></dir><file name="Observer.php" hash="a2ec393b456d2c2cc48ef9628e8091dc"/><dir name="Service"><file name="BatchMember.php" hash="bff9371be7498558211da6087588e96c"/><file name="DataProcess.php" hash="80caa339fc5c5a56b4091d0969c7f981"/><file name="Member.php" hash="e97677a37e170945160a4fe7c84a8fc9"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="DataSyncController.php" hash="4dc71b5186f049b06f9029a7029c5f76"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="f0caeee8c126f14e007ce5a9e8763017"/><file name="config.xml" hash="7c13a5266c6c12ab59cd41c2fb174ec6"/><file name="system.xml" hash="2c4dff513fbd45611f2e68c3baa93eec"/></dir><dir name="sql"><dir name="emvdatasync_setup"><file name="mysql4-install-0.0.1.php" hash="818dda964561417281aaa757f809664b"/><file name="mysql4-upgrade-0.1.0-0.2.0.php" hash="f452f8d95d30a1fc33049cc2ea90742d"/><file name="mysql4-upgrade-0.2.0-0.2.1.php" hash="7a876d71e9213f8031edc71e775bc07e"/></dir></dir></dir><dir name="Emt"><dir name="Block"><dir name="Adminhtml"><dir name="Config"><file name="ExtensionStatus.php" hash="12166dcdca2fd436b410889f8bea8afd"/></dir><dir name="Log"><dir name="Grid"><dir name="Renderer"><file name="GetError.php" hash="a7fb7e3075e611b0e5b672d0ecee3ddd"/></dir></dir><file name="Grid.php" hash="152ccd45c016803970f42008e3dd8880"/></dir><file name="Log.php" hash="24551f106915450e8e775b2bb1324451"/><dir name="Resending"><file name="Grid.php" hash="2a8b666807239ef14bf56475a69c8baa"/></dir><file name="Resending.php" hash="beaad1da5f136d403f8881e21dc9639e"/><dir name="System"><dir name="Config"><file name="ValidateAccount.php" hash="7b0e245225a48044e84ead1eaf87768a"/></dir></dir><dir name="Template"><dir name="Edit"><dir name="Tab"><file name="EmvContent.php" hash="a540805b70ec00fc6b5cdcc32b1a1cfb"/><file name="EmvDyn.php" hash="f12852b4e788197ba72d4e806f941798"/><file name="General.php" hash="aac30c1f6e0b85d08e42de4958bf3cf4"/></dir><file name="Tabs.php" hash="320b4c3e740ba5aacbbd5c602ffb041c"/></dir><file name="Edit.php" hash="1112cc25a74337a740647d4c5b6dc67e"/><dir name="Grid"><dir name="Renderer"><file name="Emvname.php" hash="1cf0f98ad194b33c4d9c91f0195c8146"/><file name="MageTemplate.php" hash="e284d93be818c24016bd462e31c226ee"/></dir></dir><file name="Grid.php" hash="19ab59d96e2925d6fe2b14aad3111498"/></dir><file name="Templates.php" hash="12bcab5abc0be49e4e04b0d92eecf61c"/></dir></dir><dir name="Helper"><file name="Data.php" hash="067567bd92ed2d9c5ccd0c2f2d7d8cd2"/><file name="Emvtemplate.php" hash="ab97b960d47434035b0664b0eb53ceb0"/></dir><dir name="Model"><dir name="Adminhtml"><dir name="System"><dir name="Config"><dir name="Backend"><file name="Account.php" hash="946f8389c4f2ef1a365757ced0707daa"/><dir name="Log"><file name="Cron.php" hash="bc0c0db43127e17c616b22f9d3d74dcc"/></dir></dir></dir></dir></dir><file name="Attribute.php" hash="b0c369fcc0bc47f48ba7c5866dc72260"/><file name="Cron.php" hash="e1b81f126a847170fe45b25e63aa22b3"/><file name="Emt.php" hash="86f759a61dd7d637ed41e635f6354625"/><file name="Log.php" hash="440c8bd3969f5e36d7d6402fb01d0246"/><dir name="Mage"><dir name="Core"><dir name="Email"><file name="Template.php" hash="e5c31cf93c5b2aa0b88e8176463f5a77"/></dir></dir></dir><file name="MageTemplate.php" hash="ddf98c89b163c6e59ceed1ac5dbe8f69"/><file name="Mailmode.php" hash="9f59dc4b0b797037fcb25553c19f2d49"/><dir name="Mysql4"><dir name="Attribute"><file name="Collection.php" hash="3e3308be1178e99162606a668eace8ed"/></dir><file name="Attribute.php" hash="bd2854ed8ee4fb207b994543a0ecf9ba"/><dir name="Emt"><file name="Collection.php" hash="bbc3368b7276bbff83c1770b6a097c26"/></dir><file name="Emt.php" hash="7fd5ff6b090587b56ac09366289b369f"/><dir name="Log"><file name="Collection.php" hash="dc04e8d73fa3df064453f7c7ee12a400"/></dir><file name="Log.php" hash="cec89e175333d33add521063b2aa96a9"/><dir name="Resending"><dir name="Queue"><dir name="Message"><file name="Collection.php" hash="8b165985970886c74aef0c9d62140098"/></dir><file name="Message.php" hash="63b4e07ee46f64d7f1c8284f5f789f71"/></dir></dir></dir><file name="Observer.php" hash="184b868bac92421a27a406bff438c938"/><dir name="Resending"><dir name="Queue"><file name="Message.php" hash="4830bc5ef750efcd8973ee46f424ec51"/></dir><file name="Queue.php" hash="bb2128bf1a9ecd5cf9fb8d06f8de845b"/><file name="Rule.php" hash="b48897eeb2ca670b90e6f3356a5f5b43"/></dir><dir name="Resource"><file name="Setup.php" hash="b5fc87772ed86c16c54eb9262dd291a3"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="LogController.php" hash="05fbabe704020cddc12a8656cc9220bd"/><file name="RescheduleController.php" hash="5331244d0bb14e448fbde3b797fb680d"/><file name="TemplateController.php" hash="98c751db95da7cbf62a2305946fcd1b1"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="193ed52e7bc6f002b4526d697166c84d"/><file name="config.xml" hash="62e761edea0e32139c26f93796ab29e7"/><file name="system.xml" hash="bb3dddf31ac07675beb0cdd448bb4dc6"/></dir><dir name="sql"><dir name="emvemt_setup"><file name="mysql4-install-0.1.0.php" hash="a7d12df049f2c1377a072fa7899dcb6c"/><file name="mysql4-upgrade-0.1.0-0.2.0.php" hash="3b52221a751b221ae98e16a03807335a"/><file name="mysql4-upgrade-0.2.0-0.3.0.php" hash="0108cecb8c995004987e869fc008bf34"/><file name="mysql4-upgrade-0.3.0-0.4.0.php" hash="7ef46dc220aeb7265ef43cab5b17156f"/><file name="mysql4-upgrade-0.4.0-0.4.1.php" hash="a6eb1e85d8773af9c0935bacabcc06dd"/></dir></dir></dir><dir name="Report"><dir name="Block"><dir name="Adminhtml"><dir name="Conversion"><file name="Form.php" hash="9c537aa62d666816058130d257f75bb8"/></dir><file name="Conversion.php" hash="79959891324dcc99448d93f9cfa01724"/><dir name="Details"><file name="Grid.php" hash="beb3a98688d554cb8d49aa5a8613bd5a"/></dir><file name="Details.php" hash="a765998cb0a765423f89cd652a2d1dab"/></dir></dir><dir name="Helper"><file name="Data.php" hash="14fd1c74a2de74a85190394166c1e684"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="ConversionController.php" hash="38723e8c66a90950ed814c93a9a71fc1"/><file name="DetailsController.php" hash="653096279fbe200d6b5ac6208efe732a"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="68373b55dda02598730b80d61d313758"/><file name="config.xml" hash="34763aa8d9413c592e698e479bf00a79"/></dir></dir></dir><dir name="Mage"><dir name="SalesRule"><dir name="Helper"><file name="Coupon.php" hash="05d42b935bd31dad39c9e31052ef60c8"/></dir><dir name="Model"><dir name="Coupon"><file name="Massgenerator.php" hash="c5312f2a745bf79d2a8ac90c23fb79dc"/></dir><dir name="System"><dir name="Config"><dir name="Source"><dir name="Coupon"><file name="Format.php" hash="64236cb46364219d4a5702521898a249"/></dir></dir></dir></dir></dir></dir></dir></target></contents>
|
71 |
<compatible/>
|
72 |
<dependencies><required><php><min>5.2.6</min><max>5.5.4</max></php></required></dependencies>
|
73 |
</package>
|
@@ -1,14 +0,0 @@
|
|
1 |
-
.emv_attributes .va-middle{
|
2 |
-
vertical-align: middle;
|
3 |
-
}
|
4 |
-
.emv_attributes .content-header {
|
5 |
-
margin-bottom: 10px;
|
6 |
-
border-bottom: 4px solid #FFF;
|
7 |
-
}
|
8 |
-
.emv_attributes textarea{
|
9 |
-
width: 90%;
|
10 |
-
margin-top: 2px;
|
11 |
-
}
|
12 |
-
.emv_attributes th{
|
13 |
-
height: 30px;
|
14 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.emv_attributes .va-middle{
|
2 |
+
vertical-align: middle;
|
3 |
+
}
|
4 |
+
.emv_attributes .content-header {
|
5 |
+
margin-bottom: 10px;
|
6 |
+
border-bottom: 4px solid #FFF;
|
7 |
+
}
|
8 |
+
.emv_attributes textarea{
|
9 |
+
width: 90%;
|
10 |
+
margin-top: 2px;
|
11 |
+
}
|
12 |
+
.emv_attributes th{
|
13 |
+
height: 30px;
|
14 |
+
}
|
15 |
+
.grid tr.on-progress { background-color: #fcf5dd; }
|
16 |
+
.smartfocus-selection { border-collapse:collapse; width:100%; }
|
17 |
+
.smartfocus-selection .smartfocus-selection-info { text-align:right; }
|
18 |
+
.smartfocus-selection th { font-size:13px; padding:5px 0; text-align:left; vertical-align:middle; }
|
19 |
+
.smartfocus-selection td { background:#f2f2f2; border-bottom:5px solid #fff; padding:5px; vertical-align:top; }
|
20 |
+
.smartfocus-selection .smartfocus-selection-simplified { background:#fff; padding-left:35px; }
|
21 |
+
.smartfocus-selection td a { color:#2997d8; }
|
22 |
+
.smartfocus-selection td strong { color:#3c616a; }
|
23 |
+
.smartfocus-selection td label { display:block; padding-left:30px; text-indent:-30px;padding-top:3px; }
|
24 |
+
.smartfocus-selection td div label { display:inline; padding:0; text-indent:0; }
|
25 |
+
.smartfocus-selection td input { height:13px; overflow:hidden; margin-right:15px; position:relative; top:-1px; width:13px; vertical-align:middle; }
|