Version Notes
Testing candidate
Download this release
Release Info
Developer | Rui Mendes |
Extension | SweOptipricer |
Version | 0.1.0 |
Comparing to | |
See all releases |
Version 0.1.0
- app/code/local/SWE/Optipricer/Block/Button.php +63 -0
- app/code/local/SWE/Optipricer/Block/Discount.php +320 -0
- app/code/local/SWE/Optipricer/Helper/Data.php +14 -0
- app/code/local/SWE/Optipricer/Model/Config.php +21 -0
- app/code/local/SWE/Optipricer/Model/Observer.php +408 -0
- app/code/local/SWE/Optipricer/controllers/Adminhtml/SweoptipricerController.php +15 -0
- app/code/local/SWE/Optipricer/etc/.gitignore +1 -0
- app/code/local/SWE/Optipricer/etc/system.xml +179 -0
- app/code/local/SWE/Optipricer/etc/widget.xml +72 -0
- app/design/frontend/base/default/template/swe/optipricer/widget.phtml +371 -0
- app/etc/modules/SWE_Optipricer.xml +13 -0
- app/locale/en_US/SWE_Optipricer.csv +5 -0
- app/locale/pt_PT/SWE_Optipricer.csv +5 -0
- js/swe/optialert.min.js +1 -0
- js/swe/optipricer.min.js +1 -0
- js/swe/optispin.min.js +2 -0
- package.xml +20 -0
app/code/local/SWE/Optipricer/Block/Button.php
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Widget to share the product in Facebook and get a personalized discount
|
4 |
+
*
|
5 |
+
* @package SWE_Optipricer
|
6 |
+
* @author Ubiprism Lda. / be.ubi <contact@beubi.com>
|
7 |
+
* @copyright 2014 be.ubi
|
8 |
+
* @license GNU Lesser General Public License (LGPL)
|
9 |
+
* @version v.0.2
|
10 |
+
*/
|
11 |
+
class SWE_Optipricer_Block_Button extends Mage_Adminhtml_Block_System_Config_Form_Field
|
12 |
+
{
|
13 |
+
const URL_ENDPOINT_CONTACT = 'contact/email';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Set template
|
17 |
+
*/
|
18 |
+
protected function _construct()
|
19 |
+
{
|
20 |
+
parent::_construct();
|
21 |
+
$this->setTemplate('swe/optipricer/system/config/button.phtml');
|
22 |
+
}
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Return element html
|
26 |
+
*
|
27 |
+
* @param Varien_Data_Form_Element_Abstract $element
|
28 |
+
* @return string
|
29 |
+
*/
|
30 |
+
protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
|
31 |
+
{
|
32 |
+
return $this->_toHtml();
|
33 |
+
}
|
34 |
+
|
35 |
+
/**
|
36 |
+
* Return ajax url for button
|
37 |
+
*
|
38 |
+
* @return string
|
39 |
+
*/
|
40 |
+
public function getAjaxCheckUrl()
|
41 |
+
{
|
42 |
+
$endPoint = Mage::getStoreConfig('swe/swe_group_activation/swe_endpoint', Mage::app()->getStore());
|
43 |
+
$uriPageView = $endPoint.self::URL_ENDPOINT_CONTACT;
|
44 |
+
return $uriPageView;
|
45 |
+
}
|
46 |
+
|
47 |
+
/**
|
48 |
+
* Generate button html
|
49 |
+
*
|
50 |
+
* @return string
|
51 |
+
*/
|
52 |
+
public function getButtonHtml()
|
53 |
+
{
|
54 |
+
$button = $this->getLayout()->createBlock('adminhtml/widget_button')
|
55 |
+
->setData(array(
|
56 |
+
'id' => 'swe_optipricer_button',
|
57 |
+
'label' => $this->helper('adminhtml')->__('Send Contact'),
|
58 |
+
'onclick' => 'javascript:check(); return false;'
|
59 |
+
));
|
60 |
+
|
61 |
+
return $button->toHtml();
|
62 |
+
}
|
63 |
+
}
|
app/code/local/SWE/Optipricer/Block/Discount.php
ADDED
@@ -0,0 +1,320 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Widget to share the product in Facebook and get a personalized discount
|
4 |
+
*
|
5 |
+
* @package SWE_Optipricer
|
6 |
+
* @author Ubiprism Lda. / be.ubi <contact@beubi.com>
|
7 |
+
* @copyright 2014 be.ubi
|
8 |
+
* @license GNU Lesser General Public License (LGPL)
|
9 |
+
* @version v.0.2
|
10 |
+
*/
|
11 |
+
class SWE_Optipricer_Block_Discount extends Mage_Core_Block_Template implements Mage_Widget_Block_Interface
|
12 |
+
{
|
13 |
+
/**
|
14 |
+
* A model to serialize attributes
|
15 |
+
* @var Varien_Object
|
16 |
+
*/
|
17 |
+
protected $_serializer = null;
|
18 |
+
|
19 |
+
private $token;
|
20 |
+
private $key;
|
21 |
+
private $enabledGlobal;
|
22 |
+
private $enabledLocal;
|
23 |
+
private $minDiscount;
|
24 |
+
private $maxDiscount;
|
25 |
+
private $text;
|
26 |
+
private $endPoint;
|
27 |
+
private $pageView;
|
28 |
+
private $renderView;
|
29 |
+
private $locale;
|
30 |
+
private $expiryOffset;
|
31 |
+
private $backgroundColor;
|
32 |
+
private $colorFont;
|
33 |
+
|
34 |
+
const HTTP_OK = 200;
|
35 |
+
const URL_ENDPOINT_COUPON = 'coupon';
|
36 |
+
const URL_ENDPOINT_PAGEVIEW = 'pageview';
|
37 |
+
|
38 |
+
/**
|
39 |
+
* Initialization
|
40 |
+
*/
|
41 |
+
protected function _construct()
|
42 |
+
{
|
43 |
+
$this->token = Mage::getStoreConfig('swe/swe_group_activation/swe_token', Mage::app()->getStore());
|
44 |
+
$this->key = Mage::getStoreConfig('swe/swe_group_activation/swe_key', Mage::app()->getStore());
|
45 |
+
$this->endPoint = Mage::getStoreConfig('swe/swe_group_activation/swe_endpoint', Mage::app()->getStore());
|
46 |
+
$this->enabledGlobal = Mage::getStoreConfig('swe/swe_group_activation/swe_enable', Mage::app()->getStore());
|
47 |
+
$this->minDiscount = Mage::getStoreConfig('swe/swe_group_parameters/swe_min', Mage::app()->getStore());
|
48 |
+
$this->maxDiscount = Mage::getStoreConfig('swe/swe_group_parameters/swe_max', Mage::app()->getStore());
|
49 |
+
$this->text = '';
|
50 |
+
$this->pageView = Mage::getStoreConfig('swe/swe_group_parameters/swe_pageview', Mage::app()->getStore());
|
51 |
+
$this->renderView = Mage::getStoreConfig('swe/swe_group_parameters/swe_renderview', Mage::app()->getStore());
|
52 |
+
$this->expiryOffset = Mage::getStoreConfig('swe/swe_group_parameters/swe_expiryoffset', Mage::app()->getStore());
|
53 |
+
$this->backgroundColor = Mage::getStoreConfig('swe/swe_group_parameters/swe_background_color', Mage::app()->getStore());
|
54 |
+
$this->colorFont = Mage::getStoreConfig('swe/swe_group_parameters/swe_font_color', Mage::app()->getStore());
|
55 |
+
$this->locale = Mage::app()->getLocale()->getLocaleCode();
|
56 |
+
$this->_serializer = new Varien_Object();
|
57 |
+
parent::_construct();
|
58 |
+
}
|
59 |
+
|
60 |
+
protected function _prepareLayout() {
|
61 |
+
$this->getLayout()->getBlock('head')->addJs('swe/optipricer.min.js');
|
62 |
+
$this->getLayout()->getBlock('head')->addJs('swe/optispin.min.js');
|
63 |
+
$this->getLayout()->getBlock('head')->addJs('swe/optialert.min.js');
|
64 |
+
}
|
65 |
+
|
66 |
+
/**
|
67 |
+
* Produces links list html
|
68 |
+
*
|
69 |
+
* @return string
|
70 |
+
*/
|
71 |
+
protected function _toHtml()
|
72 |
+
{
|
73 |
+
$this->loadLocalParameters();
|
74 |
+
|
75 |
+
//ToDo: remove Debug
|
76 |
+
$this->printDebug(false);
|
77 |
+
|
78 |
+
$result = $html = '';
|
79 |
+
//Global parameter of the service ($enabled)
|
80 |
+
if (!$this->enabledGlobal || !$this->enabledLocal || !$this->token || !$this->key) {
|
81 |
+
return $html;
|
82 |
+
}
|
83 |
+
|
84 |
+
//get ProductDetails and other relevant data to the requests
|
85 |
+
$data = $this->getProductDetails();
|
86 |
+
$data['min'] = $this->minDiscount;
|
87 |
+
$data['max'] = $this->maxDiscount;
|
88 |
+
$data['text'] = $this->text;
|
89 |
+
$data['discount_render'] = $this->renderView;
|
90 |
+
$data['expiry_offset'] = $this->expiryOffset;
|
91 |
+
//ToDo: get FacebookId if exists any info about it
|
92 |
+
$data['social_credentials'] = array('facebookId' => '', 'facebookToken' => '');
|
93 |
+
|
94 |
+
$securedData['data'] = $this->secureContent(json_encode($data));
|
95 |
+
$securedData['social_credentials'] = $data['social_credentials'];
|
96 |
+
|
97 |
+
//Check if pageView parameter is enabled
|
98 |
+
if ($this->pageView) {
|
99 |
+
$result = $this->updatePageView($securedData, $this->renderView);
|
100 |
+
}
|
101 |
+
|
102 |
+
$securedData['store_token'] = $this->token;
|
103 |
+
$securedData['product_id'] = $data['product_id'];
|
104 |
+
$securedData['name'] = json_encode($data['name']);
|
105 |
+
$securedData['url_api'] = $this->endPoint;
|
106 |
+
$securedData['o_price'] = $data['price'];
|
107 |
+
$securedData['locale'] = $this->locale;
|
108 |
+
$securedData['currency'] = $data['currency'];
|
109 |
+
$securedData['formatted_price'] = $data['formatted_price'];
|
110 |
+
|
111 |
+
//Generate the Optipricer Button
|
112 |
+
if ($result && $this->renderView) {
|
113 |
+
if ($result['http_code'] == self::HTTP_OK && $result['content']) {
|
114 |
+
return $result['content'];
|
115 |
+
}
|
116 |
+
}
|
117 |
+
//Get text variables
|
118 |
+
$transButton = $this->__('Share and get a discount!');
|
119 |
+
$transCommentInit = $this->__('Hey! Check this');
|
120 |
+
$transCommentMid = $this->__('I found on');
|
121 |
+
$transCommentEnd = $this->__('I loved it!');
|
122 |
+
$name = Mage::app()->getStore()->getFrontendName();
|
123 |
+
$transComment = $transCommentInit.' '.$data['name'].' '.$transCommentMid.' '.$name.'. '.$transCommentEnd;
|
124 |
+
|
125 |
+
//Assign variables to be rendered in the template
|
126 |
+
$this->assign('buttoncolor', '#'.$this->backgroundColor);
|
127 |
+
$this->assign('fontcolor', '#'.$this->colorFont);
|
128 |
+
$this->assign('transButton', $transButton);
|
129 |
+
$this->assign('transComment', $transComment);
|
130 |
+
$this->assign('offer', $securedData);
|
131 |
+
|
132 |
+
return parent::_toHtml();
|
133 |
+
}
|
134 |
+
|
135 |
+
private function updatePageView($data, $renderView = false)
|
136 |
+
{
|
137 |
+
$uriPageView = $this->endPoint.self::URL_ENDPOINT_PAGEVIEW;
|
138 |
+
$headers = array();
|
139 |
+
$headers[] = 'Authorization: Token '.$this->token;
|
140 |
+
$headers[] = 'Accept-Language: '.$this->locale;
|
141 |
+
if ($renderView) {
|
142 |
+
$headers[] = 'Accept: text/html';
|
143 |
+
}
|
144 |
+
// Get cURL resource
|
145 |
+
$response = $this->executeApiRequest($uriPageView, 'PUT', $headers, $data);
|
146 |
+
|
147 |
+
return $response;
|
148 |
+
}
|
149 |
+
|
150 |
+
private function executeApiRequest($uri, $method, $headers = array(), $rawData = '')
|
151 |
+
{
|
152 |
+
$curl = curl_init();
|
153 |
+
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
|
154 |
+
curl_setopt($curl, CURLOPT_URL, $uri);
|
155 |
+
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
|
156 |
+
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
|
157 |
+
//FixMe: delete ssl options
|
158 |
+
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
|
159 |
+
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
|
160 |
+
if ($headers) {
|
161 |
+
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
162 |
+
}
|
163 |
+
if ($rawData) {
|
164 |
+
$data = json_encode($rawData);
|
165 |
+
$headers[] = 'Content-Type: application/json';
|
166 |
+
$headers[] = 'Content-Length: ' . strlen($data);
|
167 |
+
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
|
168 |
+
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
|
169 |
+
}
|
170 |
+
// Send the request & save response to $content
|
171 |
+
$content = curl_exec($curl);
|
172 |
+
if(curl_errno($curl)) {
|
173 |
+
curl_close($curl);
|
174 |
+
//ToDo: send an email to alert the error
|
175 |
+
return false;
|
176 |
+
}
|
177 |
+
$info = curl_getinfo($curl);
|
178 |
+
$result['http_code'] = $info['http_code'];
|
179 |
+
$result['content'] = $content;
|
180 |
+
// Close request to clear up some resources
|
181 |
+
curl_close($curl);
|
182 |
+
return $result;
|
183 |
+
}
|
184 |
+
|
185 |
+
private function getProductDetails()
|
186 |
+
{
|
187 |
+
$product = Mage::registry('current_product');
|
188 |
+
$productDetails = array();
|
189 |
+
$productDetails['product_id'] = $product->getId();
|
190 |
+
$productDetails['name'] = $product->getName();
|
191 |
+
$productDetails['description'] = $product->description;
|
192 |
+
$productDetails['price'] = $product->getPrice();
|
193 |
+
$productDetails['product_barcode'] = $product->getBarcode();
|
194 |
+
$productDetails['image_url'] = $product->getImageUrl();
|
195 |
+
$productDetails['link'] = $product->getProductUrl();
|
196 |
+
$brand = $product->getAttributeText('manufacturer');
|
197 |
+
$productDetails['product_brand'] = $brand ? $brand : '';
|
198 |
+
$categories = $product->getCategoryIds();
|
199 |
+
$categoriesAux = array();
|
200 |
+
foreach ($categories as $category_id) {
|
201 |
+
$_cat = Mage::getModel('catalog/category')->load($category_id);
|
202 |
+
if ($_cat->getName() && !in_array($_cat->getName(), $categoriesAux)) {
|
203 |
+
$categoriesAux[] = $_cat->getName();
|
204 |
+
}
|
205 |
+
}
|
206 |
+
$productDetails['categories'] = $categoriesAux;
|
207 |
+
$currentCurrencyCode = Mage::app()->getStore()->getCurrentCurrencyCode();
|
208 |
+
$currentCurrencySymbol = Mage::app()->getLocale()->currency($currentCurrencyCode)->getSymbol();
|
209 |
+
$productDetails['currency'] = $currentCurrencySymbol;
|
210 |
+
$productDetails['formatted_price'] = Mage::helper('core')->formatPrice($product->getPrice(), false);
|
211 |
+
|
212 |
+
return $productDetails;
|
213 |
+
}
|
214 |
+
|
215 |
+
private function loadLocalParameters()
|
216 |
+
{
|
217 |
+
$this->enabledLocal = $this->getData('enable_service');
|
218 |
+
$colorFont = $this->getData('swe_font_color');
|
219 |
+
$backgroundColor = $this->getData('swe_background_color');
|
220 |
+
$expiryOffsetLocal = $this->getData('swe_expiryoffset');
|
221 |
+
|
222 |
+
if($colorFont) {
|
223 |
+
$this->colorFont = $colorFont;
|
224 |
+
}
|
225 |
+
if($backgroundColor){
|
226 |
+
$this->backgroundColor = $backgroundColor;
|
227 |
+
}
|
228 |
+
if ($expiryOffsetLocal) {
|
229 |
+
$this->expiryOffset = $expiryOffsetLocal;
|
230 |
+
}
|
231 |
+
$minimumLocal = $this->getData('swe_min');
|
232 |
+
if ($minimumLocal) {
|
233 |
+
$this->minDiscount = $minimumLocal;
|
234 |
+
}
|
235 |
+
$maximumLocal = $this->getData('swe_max');
|
236 |
+
if ($maximumLocal && !($maximumLocal < $this->minDiscount)) {
|
237 |
+
$this->maxDiscount = $maximumLocal;
|
238 |
+
}
|
239 |
+
if($this->maxDiscount < $this->minDiscount) {
|
240 |
+
$this->maxDiscount = $this->minDiscount;
|
241 |
+
}
|
242 |
+
}
|
243 |
+
|
244 |
+
private function secureContent($content, $task = 'encrypt')
|
245 |
+
{
|
246 |
+
if ($task == 'decrypt') {
|
247 |
+
$contentSecured = $this->decryptContent($this->key, $content);
|
248 |
+
} else {
|
249 |
+
$contentSecured = $this->encryptContent($this->key, $content);
|
250 |
+
}
|
251 |
+
|
252 |
+
return $contentSecured;
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Encrypt content
|
257 |
+
*
|
258 |
+
* @param String $key Key
|
259 |
+
* @param String $content Content
|
260 |
+
*
|
261 |
+
* @return string
|
262 |
+
*/
|
263 |
+
private function encryptContent($key, $content)
|
264 |
+
{
|
265 |
+
$ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
|
266 |
+
$iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_RANDOM);
|
267 |
+
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $content, MCRYPT_MODE_CBC, $iv);
|
268 |
+
$ciphertextArr = array('cipher' => base64_encode($ciphertext), 'iv' => base64_encode($iv));
|
269 |
+
$ciphertextArr = json_encode($ciphertextArr);
|
270 |
+
$ciphertextBase64 = base64_encode($ciphertextArr);
|
271 |
+
|
272 |
+
return $ciphertextBase64;
|
273 |
+
}
|
274 |
+
|
275 |
+
/**
|
276 |
+
* Decrypt content
|
277 |
+
*
|
278 |
+
* @param String $key Key
|
279 |
+
* @param String $cipher Cipher
|
280 |
+
*
|
281 |
+
* @return string
|
282 |
+
*/
|
283 |
+
private function decryptContent($key, $cipher)
|
284 |
+
{
|
285 |
+
$ciphertextDec = base64_decode($cipher);
|
286 |
+
$ciphertextDec = json_decode($ciphertextDec);
|
287 |
+
$content = trim(mcrypt_decrypt(
|
288 |
+
MCRYPT_RIJNDAEL_128,
|
289 |
+
$key,
|
290 |
+
base64_decode($ciphertextDec->cipher),
|
291 |
+
MCRYPT_MODE_CBC,
|
292 |
+
base64_decode($ciphertextDec->iv)
|
293 |
+
));
|
294 |
+
|
295 |
+
return $content;
|
296 |
+
}
|
297 |
+
|
298 |
+
//ToDo: remove
|
299 |
+
private function printDebug($debug) {
|
300 |
+
/*************** ToDo: remove *************/
|
301 |
+
if ($debug) {
|
302 |
+
echo "<br />--------- DEBUG -------<br/>";
|
303 |
+
echo "<b>Enabled Global</b>: ".$this->enabledGlobal;
|
304 |
+
echo "<br /><b>Enabled Local</b>: ".$this->enabledLocal;
|
305 |
+
echo "<br /><b>EndPoint</b>: ".$this->endPoint;
|
306 |
+
echo "<br /><b>Token</b>: ".$this->token;
|
307 |
+
echo "<br /><b>Key</b>: ".$this->key;
|
308 |
+
echo "<br /><b>Min</b>: ".$this->minDiscount;
|
309 |
+
echo "<br /><b>Max</b>: ".$this->maxDiscount;
|
310 |
+
echo "<br /><b>PageView</b>: ".$this->pageView;
|
311 |
+
echo "<br /><b>renderView</b>: ".$this->renderView;
|
312 |
+
echo "<br /><b>ExpiryOffset</b>: ".$this->expiryOffset;
|
313 |
+
echo "<br /><b>Locale</b>: ".$this->locale;
|
314 |
+
echo "<br /><b>ColorFont</b>: ".$this->colorFont;
|
315 |
+
echo "<br /><b>Background Color</b>: ".$this->backgroundColor;
|
316 |
+
echo "<br />-------- END DEBUG -----<br /><br />";
|
317 |
+
}
|
318 |
+
/*************** ToDo: remove *************/
|
319 |
+
}
|
320 |
+
}
|
app/code/local/SWE/Optipricer/Helper/Data.php
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Default helper of the module
|
4 |
+
*
|
5 |
+
* @package SWE_Optipricer
|
6 |
+
* @author Ubiprism Lda. / be.ubi <contact@beubi.com>
|
7 |
+
* @copyright 2014 be.ubi
|
8 |
+
* @license GNU Lesser General Public License (LGPL)
|
9 |
+
* @version v.0.2
|
10 |
+
*/
|
11 |
+
class SWE_Optipricer_Helper_Data extends Mage_Core_Helper_Abstract
|
12 |
+
{
|
13 |
+
|
14 |
+
}
|
app/code/local/SWE/Optipricer/Model/Config.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Class SWE_Optipricer_Model_Observer
|
4 |
+
*
|
5 |
+
* @package SWE_Optipricer
|
6 |
+
* @author Ubiprism Lda. / be.ubi <contact@beubi.com>
|
7 |
+
* @copyright 2014 be.ubi
|
8 |
+
* @license GNU Lesser General Public License (LGPL)
|
9 |
+
* @version v.0.2
|
10 |
+
*/
|
11 |
+
class SWE_Optipricer_Model_Config
|
12 |
+
{
|
13 |
+
public function toOptionArray()
|
14 |
+
{
|
15 |
+
$result = array();
|
16 |
+
$result[] = array('value' => '0', 'label'=>' Local');
|
17 |
+
$result[] = array('value' => '1', 'label'=>' Remote');
|
18 |
+
|
19 |
+
return $result;
|
20 |
+
}
|
21 |
+
}
|
app/code/local/SWE/Optipricer/Model/Observer.php
ADDED
@@ -0,0 +1,408 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class SWE_Optipricer_Model_Observer
|
5 |
+
*
|
6 |
+
* @package SWE_Optipricer
|
7 |
+
* @author Ubiprism Lda. / be.ubi <contact@beubi.com>
|
8 |
+
* @copyright 2014 be.ubi
|
9 |
+
* @license GNU Lesser General Public License (LGPL)
|
10 |
+
* @version v.0.2
|
11 |
+
*/
|
12 |
+
class SWE_Optipricer_Model_Observer extends Varien_Event_Observer
|
13 |
+
{
|
14 |
+
const STATE_CANCELED = 'canceled';
|
15 |
+
const SCENARIO_ONE_PAGE_CHECKOUT = 'one_page';
|
16 |
+
const SCENARIO_MULTIPLE_ADDRESSES_CHECKOUT = 'multiple_addresses';
|
17 |
+
const URL_ENDPOINT_COUPON = 'coupon';
|
18 |
+
const URL_ENDPOINT_REDEEM = 'redeem';
|
19 |
+
const URL_SEPARATOR = '/';
|
20 |
+
|
21 |
+
protected $_serializer = null;
|
22 |
+
private $token;
|
23 |
+
private $key;
|
24 |
+
private $enabledGlobal;
|
25 |
+
private $minDiscount;
|
26 |
+
private $maxDiscount;
|
27 |
+
private $text;
|
28 |
+
private $endPoint;
|
29 |
+
private $pageView;
|
30 |
+
private $renderView;
|
31 |
+
private $locale;
|
32 |
+
private $expiryOffset;
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Initialization
|
36 |
+
*/
|
37 |
+
protected function _construct()
|
38 |
+
{
|
39 |
+
$this->token = Mage::getStoreConfig('swe/swe_group_activation/swe_token',Mage::app()->getStore());
|
40 |
+
$this->key = Mage::getStoreConfig('swe/swe_group_activation/swe_key', Mage::app()->getStore());
|
41 |
+
$this->enabledGlobal = Mage::getStoreConfig('swe/swe_group_activation/swe_enable',Mage::app()->getStore());
|
42 |
+
$this->endPoint = Mage::getStoreConfig('swe/swe_group_activation/swe_endpoint',Mage::app()->getStore());
|
43 |
+
$this->minDiscount = Mage::getStoreConfig('swe/swe_group_parameters/swe_min',Mage::app()->getStore());
|
44 |
+
$this->maxDiscount = Mage::getStoreConfig('swe/swe_group_parameters/swe_max',Mage::app()->getStore());
|
45 |
+
$this->text = '';
|
46 |
+
$this->pageView = Mage::getStoreConfig('swe/swe_group_parameters/swe_pageview',Mage::app()->getStore());
|
47 |
+
$this->renderView = Mage::getStoreConfig('swe/swe_group_parameters/swe_renderview',Mage::app()->getStore());
|
48 |
+
$this->expiryOffset = Mage::getStoreConfig('swe/swe_group_parameters/swe_expiryoffset',Mage::app()->getStore());
|
49 |
+
$this->locale = Mage::app()->getLocale()->getLocaleCode();
|
50 |
+
$this->_serializer = new Varien_Object();
|
51 |
+
}
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Verify each price for each discount given
|
55 |
+
*
|
56 |
+
* @param Varien_Event_Observer $observer Observer
|
57 |
+
*
|
58 |
+
* @return void
|
59 |
+
*/
|
60 |
+
public function validateCart(Varien_Event_Observer $observer)
|
61 |
+
{
|
62 |
+
$session = Mage::getSingleton('checkout/session');
|
63 |
+
/** @var Mage_Sales_Model_Quote $quote */
|
64 |
+
$quote = $session->getQuote();
|
65 |
+
$quote->setIsMultiShipping(false);
|
66 |
+
$scenario = $this->getCurrentScenario($quote);
|
67 |
+
$this->_construct();
|
68 |
+
if (!$this->token) {
|
69 |
+
return;
|
70 |
+
}
|
71 |
+
try {
|
72 |
+
$errors = array();
|
73 |
+
foreach($quote->getAllItems() as $item) {
|
74 |
+
$error = $this->validateItem($item, $scenario);
|
75 |
+
if ($error) {
|
76 |
+
$errors[] = $error;
|
77 |
+
}
|
78 |
+
}
|
79 |
+
$quote->setTotalsCollectedFlag(false);
|
80 |
+
|
81 |
+
} catch (Exception $e) {
|
82 |
+
//ToDo: send email with the error
|
83 |
+
return;
|
84 |
+
}
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Send Order status to Optipricer System
|
89 |
+
*
|
90 |
+
* @param Varien_Event_Observer $observer Observer
|
91 |
+
*
|
92 |
+
* @return void
|
93 |
+
*/
|
94 |
+
public function sendOrderStatus(Varien_Event_Observer $observer)
|
95 |
+
{
|
96 |
+
$this->_construct();
|
97 |
+
if (!$this->token) {
|
98 |
+
return;
|
99 |
+
}
|
100 |
+
$cookiesToRemove = array();
|
101 |
+
$session = Mage::getSingleton('checkout/session');
|
102 |
+
/** @var Mage_Sales_Model_Quote $quote */
|
103 |
+
$quote = $session->getQuote();
|
104 |
+
$scenario = $this->getCurrentScenario($quote);
|
105 |
+
$errors = array();
|
106 |
+
try {
|
107 |
+
//Validate each product (that has a coupon assigned to it)
|
108 |
+
foreach($quote->getAllItems() as $item)
|
109 |
+
{
|
110 |
+
$error = $this->validateItem($item, $scenario);
|
111 |
+
if ($error) {
|
112 |
+
$errors[] = $item->getName();
|
113 |
+
} else {
|
114 |
+
$productId = $item->getProductId();
|
115 |
+
$oldProduct = Mage::getModel('catalog/product')->load($productId);
|
116 |
+
$originalPrice = round($oldProduct->getData('price'), 2);
|
117 |
+
list($discountToken, $priceWithDiscount) = $this->getDiscountTokenAndValueCookie($this->token, $productId);
|
118 |
+
// Price has changed and a Cookie exists
|
119 |
+
if ($discountToken) {
|
120 |
+
$products = $this->getAllQuoteProducts($scenario, $quote);
|
121 |
+
//Try to Redeem coupon
|
122 |
+
if (!$this->redeemCoupon($discountToken, $products)) {
|
123 |
+
$errors[] = $item->getName();
|
124 |
+
//Remove invalid cookie
|
125 |
+
setcookie('discount_'.$this->token.'_'.$productId, null, -1, '/');
|
126 |
+
$this->changeItemPrice($item, $originalPrice, $scenario);
|
127 |
+
} else {
|
128 |
+
$cookiesToRemove[] = 'discount_'.$this->token.'_'.$productId;
|
129 |
+
$this->changeItemPrice($item, $priceWithDiscount, $scenario);
|
130 |
+
}
|
131 |
+
}
|
132 |
+
}
|
133 |
+
}
|
134 |
+
} catch (Exception $e){
|
135 |
+
//ToDo: send email with the error
|
136 |
+
return;
|
137 |
+
}
|
138 |
+
|
139 |
+
//Process the error regarding the scenario
|
140 |
+
if (count($errors)) {
|
141 |
+
$result['success'] = false;
|
142 |
+
$result['error'] = true;
|
143 |
+
if (count($errors) > 1) {
|
144 |
+
$message = 'Products '.implode(', ', $errors).' are invalid!';
|
145 |
+
} elseif (count($errors) == 1) {
|
146 |
+
$message = 'Product '.$errors[0].' is invalid!';
|
147 |
+
}
|
148 |
+
$result['error_messages'] = $message;
|
149 |
+
$response = Mage::app()->getResponse();
|
150 |
+
$response->setBody(Mage::helper('core')->jsonEncode($result));
|
151 |
+
$response->sendResponse();
|
152 |
+
exit();
|
153 |
+
} else {
|
154 |
+
//Remove cookies of used coupons
|
155 |
+
foreach ($cookiesToRemove as $cookie) {
|
156 |
+
setcookie($cookie, null, -1, '/');
|
157 |
+
}
|
158 |
+
}
|
159 |
+
}
|
160 |
+
|
161 |
+
/************************* AUXILIARY METHODS ***************************/
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Method to manage secure content
|
165 |
+
*
|
166 |
+
* @param string $content Content
|
167 |
+
* @param string $task Task
|
168 |
+
*
|
169 |
+
* @return string
|
170 |
+
*/
|
171 |
+
private function secureContent($content, $task = 'encrypt')
|
172 |
+
{
|
173 |
+
if ($task == 'decrypt') {
|
174 |
+
$contentSecured = $this->decryptContent($this->key, $content);
|
175 |
+
} else {
|
176 |
+
$contentSecured = $this->encryptContent($this->key, $content);
|
177 |
+
}
|
178 |
+
|
179 |
+
return $contentSecured;
|
180 |
+
}
|
181 |
+
|
182 |
+
/**
|
183 |
+
* Encrypt content
|
184 |
+
*
|
185 |
+
* @param String $key Key
|
186 |
+
* @param String $content Content
|
187 |
+
*
|
188 |
+
* @return string
|
189 |
+
*/
|
190 |
+
private function encryptContent($key, $content)
|
191 |
+
{
|
192 |
+
$ivSize = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
|
193 |
+
$iv = mcrypt_create_iv($ivSize, MCRYPT_DEV_RANDOM);
|
194 |
+
$ciphertext = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $content, MCRYPT_MODE_CBC, $iv);
|
195 |
+
$ciphertextArr = array('cipher' => base64_encode($ciphertext), 'iv' => base64_encode($iv));
|
196 |
+
$ciphertextArr = json_encode($ciphertextArr);
|
197 |
+
$ciphertextBase64 = base64_encode($ciphertextArr);
|
198 |
+
|
199 |
+
return $ciphertextBase64;
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Decrypt content
|
204 |
+
*
|
205 |
+
* @param String $key Key
|
206 |
+
* @param String $cipher Cipher
|
207 |
+
*
|
208 |
+
* @return string
|
209 |
+
*/
|
210 |
+
private function decryptContent($key, $cipher)
|
211 |
+
{
|
212 |
+
$ciphertextDec = base64_decode($cipher);
|
213 |
+
$ciphertextDec = json_decode($ciphertextDec);
|
214 |
+
$content = trim(mcrypt_decrypt(
|
215 |
+
MCRYPT_RIJNDAEL_128,
|
216 |
+
$key,
|
217 |
+
base64_decode($ciphertextDec->cipher),
|
218 |
+
MCRYPT_MODE_CBC,
|
219 |
+
base64_decode($ciphertextDec->iv)
|
220 |
+
));
|
221 |
+
return $content;
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
* Method to get the DiscountToken and the Value from the cookie
|
226 |
+
*
|
227 |
+
* @param string $token Token Store
|
228 |
+
* @param int $productId Product Id
|
229 |
+
*
|
230 |
+
* @return array
|
231 |
+
*/
|
232 |
+
private function getDiscountTokenAndValueCookie($token, $productId)
|
233 |
+
{
|
234 |
+
$discountToken = '';
|
235 |
+
$finalPrice = 0;
|
236 |
+
if (isset($_COOKIE['discount_'.$token.'_'.$productId])) {
|
237 |
+
$cookie = $_COOKIE['discount_'.$token.'_'.$productId];
|
238 |
+
$dataAux = explode(':', $cookie);
|
239 |
+
$data = $this->secureContent(json_encode($dataAux[0]), 'decrypt');
|
240 |
+
$coupon = json_decode($data, true);
|
241 |
+
if (is_array($coupon)) {
|
242 |
+
if (array_key_exists('token', $coupon)) {
|
243 |
+
$discountToken = $coupon['token'];
|
244 |
+
}
|
245 |
+
} else {
|
246 |
+
//ToDo: alert that a cookie was violated
|
247 |
+
setcookie($cookie, null, -1, '/');
|
248 |
+
}
|
249 |
+
if (is_array($coupon)) {
|
250 |
+
if (array_key_exists('value', $coupon)) {
|
251 |
+
$finalPrice = $coupon['value'];
|
252 |
+
}
|
253 |
+
}
|
254 |
+
}
|
255 |
+
return array($discountToken, $finalPrice);
|
256 |
+
}
|
257 |
+
|
258 |
+
/**
|
259 |
+
* Method to redeem a given coupon
|
260 |
+
*
|
261 |
+
* @param string $discountToken Discount token
|
262 |
+
* @param array $products Products
|
263 |
+
* @param string $discountTokens
|
264 |
+
*
|
265 |
+
* @return bool
|
266 |
+
*/
|
267 |
+
private function redeemCoupon($discountToken, $products, $discountTokens = '')
|
268 |
+
{
|
269 |
+
$info = array();
|
270 |
+
if ($products) {
|
271 |
+
$info['products'] = $products;
|
272 |
+
}
|
273 |
+
$url = $this->endPoint.self::URL_ENDPOINT_COUPON.
|
274 |
+
self::URL_SEPARATOR.$discountToken.self::URL_SEPARATOR.self::URL_ENDPOINT_REDEEM;
|
275 |
+
|
276 |
+
$client = new Zend_Http_Client($url);
|
277 |
+
$client->setHeaders(Zend_Http_Client::CONTENT_TYPE, 'application/json');
|
278 |
+
$client->setHeaders('Authorization', 'Token '.$this->token);
|
279 |
+
if (!$discountTokens) {
|
280 |
+
$discountTokens = array($discountToken);
|
281 |
+
}
|
282 |
+
$data = array(
|
283 |
+
'tokens' => $discountTokens,
|
284 |
+
'notes' => $info,
|
285 |
+
'location' => ''
|
286 |
+
);
|
287 |
+
$securedData['data'] = $this->secureContent(json_encode($data));
|
288 |
+
$client->setRawData(json_encode($securedData));
|
289 |
+
try {
|
290 |
+
$response = $client->request('PUT');
|
291 |
+
if ($response->isSuccessful()) {
|
292 |
+
//$resp = $response->getBody();
|
293 |
+
$result = true;
|
294 |
+
} else {
|
295 |
+
$result = false;
|
296 |
+
}
|
297 |
+
} catch (Exception $e) {
|
298 |
+
//ToDo: send an email
|
299 |
+
$result = false;
|
300 |
+
}
|
301 |
+
return $result;
|
302 |
+
}
|
303 |
+
|
304 |
+
/**
|
305 |
+
* Method to change the price of the item/product
|
306 |
+
*
|
307 |
+
* @param Mage_Sales_Model_Quote_Item $item
|
308 |
+
* @param double $finalValue Final Price
|
309 |
+
* @param string $scenario Scenario
|
310 |
+
*
|
311 |
+
* @throws Exception
|
312 |
+
*/
|
313 |
+
private function changeItemPrice($item, $finalValue, $scenario='other')
|
314 |
+
{
|
315 |
+
try {
|
316 |
+
if ($finalValue > 0) {
|
317 |
+
$product = $item->getProduct();
|
318 |
+
$oldProduct = Mage::getModel('catalog/product')->load($product->getId());
|
319 |
+
$originalPrice = $oldProduct->getData('price');
|
320 |
+
//ToDo: discount field (amount)
|
321 |
+
$item->setOriginalPrice($product->getPrice());
|
322 |
+
$item->setCustomPrice($finalValue);
|
323 |
+
$item->setOriginalCustomPrice($finalValue);
|
324 |
+
$price = $product->getPrice();
|
325 |
+
$discount = $price - $finalValue;
|
326 |
+
$item->setBaseDiscountAmount($discount);
|
327 |
+
$perc = $discount / $price * 100;
|
328 |
+
$item->save();
|
329 |
+
}
|
330 |
+
} catch (Exception $e) {
|
331 |
+
throw $e;
|
332 |
+
}
|
333 |
+
}
|
334 |
+
|
335 |
+
/**
|
336 |
+
* Method to collect all products from the quote
|
337 |
+
*
|
338 |
+
* @param string $scenario Current Scenario
|
339 |
+
* @param Mage_Sales_Model_Service_Quote $quote Quote
|
340 |
+
*
|
341 |
+
* @throws Exception
|
342 |
+
*
|
343 |
+
* @return array
|
344 |
+
*/
|
345 |
+
private function getAllQuoteProducts($scenario, $quote)
|
346 |
+
{
|
347 |
+
$products = array();
|
348 |
+
foreach($quote->getAllItems() as $item)
|
349 |
+
{
|
350 |
+
$productId = $item->getProductId();
|
351 |
+
list($discountToken, $finalValue) = $this->getDiscountTokenAndValueCookie($this->token, $productId);
|
352 |
+
$productAux = array();
|
353 |
+
$productAux['productId'] = $productId;
|
354 |
+
$productAux['discountToken'] = $discountToken;
|
355 |
+
$productAux['finalValue'] = $finalValue;
|
356 |
+
$products[] = $productAux;
|
357 |
+
}
|
358 |
+
return $products;
|
359 |
+
}
|
360 |
+
|
361 |
+
/**
|
362 |
+
* Method to return current Scenario
|
363 |
+
*
|
364 |
+
* @return string
|
365 |
+
*/
|
366 |
+
private function getCurrentScenario($quote)
|
367 |
+
{
|
368 |
+
if ($quote->getIsMultiShipping()) {
|
369 |
+
$scenario = self::SCENARIO_MULTIPLE_ADDRESSES_CHECKOUT;
|
370 |
+
} else {
|
371 |
+
$scenario = self::SCENARIO_ONE_PAGE_CHECKOUT;
|
372 |
+
}
|
373 |
+
return $scenario;
|
374 |
+
}
|
375 |
+
|
376 |
+
/**
|
377 |
+
* Method to validate an item
|
378 |
+
*
|
379 |
+
* @param Mage_Sales_Model_Quote_Item $item Item
|
380 |
+
* @param string $scenario Current Scenario
|
381 |
+
*
|
382 |
+
* @throws Exception
|
383 |
+
*
|
384 |
+
* @return string
|
385 |
+
*/
|
386 |
+
private function validateItem($item, $scenario='other')
|
387 |
+
{
|
388 |
+
$error = '';
|
389 |
+
$productId = $item->getProductId();
|
390 |
+
$newProduct = $item->getProduct();
|
391 |
+
$oldProduct = Mage::getModel('catalog/product')->load($newProduct->getId());
|
392 |
+
list($discountToken, $priceWithDiscount) = $this->getDiscountTokenAndValueCookie($this->token, $productId);
|
393 |
+
$originalPrice = round($oldProduct->getData('price'), 2);
|
394 |
+
$currentProductPrice = round($newProduct->getData('price'), 2);
|
395 |
+
$currentItemPrice = round($item->getCustomPrice(), 2);
|
396 |
+
if ($originalPrice != $currentProductPrice || $originalPrice != $currentItemPrice || $discountToken) {
|
397 |
+
// Price has changed and cookie was deleted/violated
|
398 |
+
if (!$discountToken) {
|
399 |
+
$error = $item->getName();
|
400 |
+
$this->changeItemPrice($item, $originalPrice, $scenario);
|
401 |
+
setcookie('discount_'.$this->token.'_'.$productId, null, -1, '/');
|
402 |
+
} else {
|
403 |
+
$this->changeItemPrice($item, $priceWithDiscount, $scenario);
|
404 |
+
}
|
405 |
+
}
|
406 |
+
return $error;
|
407 |
+
}
|
408 |
+
}
|
app/code/local/SWE/Optipricer/controllers/Adminhtml/SweoptipricerController.php
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class SWE_Optipricer_Adminhtml_SweoptipricerController extends Mage_Adminhtml_Controller_Action
|
4 |
+
{
|
5 |
+
/**
|
6 |
+
* Return some checking result
|
7 |
+
*
|
8 |
+
* @return void
|
9 |
+
*/
|
10 |
+
public function checkAction()
|
11 |
+
{
|
12 |
+
$result = 1;
|
13 |
+
Mage::app()->getResponse()->setBody($result);
|
14 |
+
}
|
15 |
+
}
|
app/code/local/SWE/Optipricer/etc/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
config.xml
|
app/code/local/SWE/Optipricer/etc/system.xml
ADDED
@@ -0,0 +1,179 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<config>
|
3 |
+
<tabs>
|
4 |
+
<swe translate="label" module="optipricer">
|
5 |
+
<label>SWE - Optipricer</label>
|
6 |
+
<sort_order>100</sort_order>
|
7 |
+
</swe>
|
8 |
+
</tabs>
|
9 |
+
<sections>
|
10 |
+
<swe translate="label" module="optipricer">
|
11 |
+
<label>Configuration</label>
|
12 |
+
<tab>swe</tab>
|
13 |
+
<sort_order>1000</sort_order>
|
14 |
+
<show_in_default>1</show_in_default>
|
15 |
+
<show_in_website>1</show_in_website>
|
16 |
+
<show_in_store>1</show_in_store>
|
17 |
+
|
18 |
+
<groups>
|
19 |
+
<swe_group_activation translate="label" module="optipricer">
|
20 |
+
<label>Optipricer - Activation</label>
|
21 |
+
<sort_order>10</sort_order>
|
22 |
+
<show_in_default>1</show_in_default>
|
23 |
+
<show_in_website>1</show_in_website>
|
24 |
+
<show_in_store>1</show_in_store>
|
25 |
+
<expanded>0</expanded>
|
26 |
+
<fields>
|
27 |
+
<swe_name translate="label">
|
28 |
+
<label>Name</label>
|
29 |
+
<frontend_type>text</frontend_type>
|
30 |
+
<validate>required-entry</validate>
|
31 |
+
<sort_order>5</sort_order>
|
32 |
+
<show_in_default>1</show_in_default>
|
33 |
+
<show_in_website>1</show_in_website>
|
34 |
+
<show_in_store>1</show_in_store>
|
35 |
+
</swe_name>
|
36 |
+
<swe_email translate="label">
|
37 |
+
<label>Email</label>
|
38 |
+
<frontend_type>text</frontend_type>
|
39 |
+
<validate>validate-email required-entry</validate>
|
40 |
+
<sort_order>10</sort_order>
|
41 |
+
<show_in_default>1</show_in_default>
|
42 |
+
<show_in_website>1</show_in_website>
|
43 |
+
<show_in_store>1</show_in_store>
|
44 |
+
</swe_email>
|
45 |
+
<swe_message translate="label">
|
46 |
+
<label>Message</label>
|
47 |
+
<frontend_type>textarea</frontend_type>
|
48 |
+
<sort_order>15</sort_order>
|
49 |
+
<show_in_default>1</show_in_default>
|
50 |
+
<show_in_website>1</show_in_website>
|
51 |
+
<show_in_store>1</show_in_store>
|
52 |
+
</swe_message>
|
53 |
+
<swe_contact translate="label">
|
54 |
+
<label>Activate service</label>
|
55 |
+
<frontend_type>button</frontend_type>
|
56 |
+
<frontend_model>optipricer/button</frontend_model>
|
57 |
+
<sort_order>20</sort_order>
|
58 |
+
<show_in_default>1</show_in_default>
|
59 |
+
<show_in_website>1</show_in_website>
|
60 |
+
<show_in_store>1</show_in_store>
|
61 |
+
</swe_contact>
|
62 |
+
<swe_token translate="label">
|
63 |
+
<label>Store Token </label>
|
64 |
+
<comment>Store Token (given by be.ubi)</comment>
|
65 |
+
<frontend_type>text</frontend_type>
|
66 |
+
<sort_order>24</sort_order>
|
67 |
+
<show_in_default>1</show_in_default>
|
68 |
+
<show_in_website>1</show_in_website>
|
69 |
+
<show_in_store>1</show_in_store>
|
70 |
+
</swe_token>
|
71 |
+
<swe_key translate="label">
|
72 |
+
<label>Store Key </label>
|
73 |
+
<comment>Key for encrypt/decrypt data (given by be.ubi)</comment>
|
74 |
+
<frontend_type>text</frontend_type>
|
75 |
+
<sort_order>30</sort_order>
|
76 |
+
<show_in_default>1</show_in_default>
|
77 |
+
<show_in_website>1</show_in_website>
|
78 |
+
<show_in_store>1</show_in_store>
|
79 |
+
</swe_key>
|
80 |
+
<swe_enable translate="label">
|
81 |
+
<label>Enable Service </label>
|
82 |
+
<comment>Enable or Disable the service.</comment>
|
83 |
+
<frontend_type>select</frontend_type>
|
84 |
+
<sort_order>40</sort_order>
|
85 |
+
<show_in_default>1</show_in_default>
|
86 |
+
<show_in_website>1</show_in_website>
|
87 |
+
<show_in_store>1</show_in_store>
|
88 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
89 |
+
</swe_enable>
|
90 |
+
<swe_endpoint translate="label">
|
91 |
+
<label>Swe Endpoint </label>
|
92 |
+
<comment>Don't change this endpoint! Unless it was requested by the widget develop team.</comment>
|
93 |
+
<frontend_type>text</frontend_type>
|
94 |
+
<sort_order>90</sort_order>
|
95 |
+
<show_in_default>1</show_in_default>
|
96 |
+
<show_in_website>1</show_in_website>
|
97 |
+
<show_in_store>1</show_in_store>
|
98 |
+
</swe_endpoint>
|
99 |
+
</fields>
|
100 |
+
</swe_group_activation>
|
101 |
+
<swe_group_parameters translate="label" module="optipricer">
|
102 |
+
<label>Optipricer - Parameters</label>
|
103 |
+
<sort_order>20</sort_order>
|
104 |
+
<show_in_default>1</show_in_default>
|
105 |
+
<show_in_website>1</show_in_website>
|
106 |
+
<show_in_store>1</show_in_store>
|
107 |
+
<expanded>1</expanded>
|
108 |
+
<fields>
|
109 |
+
<swe_expiryoffset translate="label">
|
110 |
+
<label>Expiry Offset (in minutes)</label>
|
111 |
+
<comment>Time limit for the Coupon. Example: 2880=2 days</comment>
|
112 |
+
<frontend_type>text</frontend_type>
|
113 |
+
<sort_order>50</sort_order>
|
114 |
+
<show_in_default>1</show_in_default>
|
115 |
+
<show_in_website>1</show_in_website>
|
116 |
+
<show_in_store>1</show_in_store>
|
117 |
+
</swe_expiryoffset>
|
118 |
+
<swe_min translate="label">
|
119 |
+
<label>Minimum Discount </label>
|
120 |
+
<comment>Minimum value of the discount range.</comment>
|
121 |
+
<frontend_type>text</frontend_type>
|
122 |
+
<sort_order>60</sort_order>
|
123 |
+
<show_in_default>1</show_in_default>
|
124 |
+
<show_in_website>1</show_in_website>
|
125 |
+
<show_in_store>1</show_in_store>
|
126 |
+
</swe_min>
|
127 |
+
<swe_max translate="label">
|
128 |
+
<label>Maximum Discount </label>
|
129 |
+
<comment>Maximum value of the discount range.</comment>
|
130 |
+
<frontend_type>text</frontend_type>
|
131 |
+
<sort_order>70</sort_order>
|
132 |
+
<show_in_default>1</show_in_default>
|
133 |
+
<show_in_website>1</show_in_website>
|
134 |
+
<show_in_store>1</show_in_store>
|
135 |
+
</swe_max>
|
136 |
+
<swe_pageview translate="label">
|
137 |
+
<label>Enable Page Views </label>
|
138 |
+
<comment>Enable or Disable the feature "Page Views".</comment>
|
139 |
+
<frontend_type>select</frontend_type>
|
140 |
+
<sort_order>80</sort_order>
|
141 |
+
<show_in_default>1</show_in_default>
|
142 |
+
<show_in_website>1</show_in_website>
|
143 |
+
<show_in_store>1</show_in_store>
|
144 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
145 |
+
</swe_pageview>
|
146 |
+
<swe_renderview translate="label">
|
147 |
+
<label>Render Template </label>
|
148 |
+
<comment>Render templates from local or remote sources.</comment>
|
149 |
+
<frontend_type>radios</frontend_type>
|
150 |
+
<source_model>optipricer/config</source_model>
|
151 |
+
<sort_order>90</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 |
+
</swe_renderview>
|
156 |
+
<swe_background_color translate="label">
|
157 |
+
<label>Background color (Button)</label>
|
158 |
+
<comment>If empty, the color 660066 (purple) will be used</comment>
|
159 |
+
<frontend_type>text</frontend_type>
|
160 |
+
<sort_order>100</sort_order>
|
161 |
+
<show_in_default>1</show_in_default>
|
162 |
+
<show_in_website>1</show_in_website>
|
163 |
+
<show_in_store>1</show_in_store>
|
164 |
+
</swe_background_color>
|
165 |
+
<swe_font_color translate="label">
|
166 |
+
<label>Font color (Button)</label>
|
167 |
+
<comment>If empty, the color FFFFFF (white) will be used</comment>
|
168 |
+
<frontend_type>text</frontend_type>
|
169 |
+
<sort_order>110</sort_order>
|
170 |
+
<show_in_default>1</show_in_default>
|
171 |
+
<show_in_website>1</show_in_website>
|
172 |
+
<show_in_store>1</show_in_store>
|
173 |
+
</swe_font_color>
|
174 |
+
</fields>
|
175 |
+
</swe_group_parameters>
|
176 |
+
</groups>
|
177 |
+
</swe>
|
178 |
+
</sections>
|
179 |
+
</config>
|
app/code/local/SWE/Optipricer/etc/widget.xml
ADDED
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<widgets>
|
3 |
+
<optipricer_discount type="optipricer/discount" translate="Optipricer Discount" module="optipricer">
|
4 |
+
<name>Optipricer Discount</name>
|
5 |
+
|
6 |
+
<description>Get a personalized discount</description>
|
7 |
+
|
8 |
+
<!-- Additional javascript files to be loaded
|
9 |
+
on the widget configuration edit form if needed. -->
|
10 |
+
<!--<js>mage/adminhtml/first.js,mage/adminhtml/second.js</js>-->
|
11 |
+
|
12 |
+
<!--
|
13 |
+
It should contain comma separated list
|
14 |
+
of javascript files paths under the /js directory.
|
15 |
+
This tag is optional.
|
16 |
+
-->
|
17 |
+
|
18 |
+
<parameters>
|
19 |
+
<enable_service translate="label">
|
20 |
+
<label>Enable Service</label>
|
21 |
+
<visible>1</visible>
|
22 |
+
<required>1</required>
|
23 |
+
<type>select</type>
|
24 |
+
<value>1</value>
|
25 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
26 |
+
</enable_service>
|
27 |
+
<swe_font_color translate="label">
|
28 |
+
<label>Font color (Button)</label>
|
29 |
+
<visible>1</visible>
|
30 |
+
<type>text</type>
|
31 |
+
<description>If empty, the color FFFFFF (white) will be used</description>
|
32 |
+
</swe_font_color>
|
33 |
+
<swe_background_color translate="label">
|
34 |
+
<label>Background color (Button)</label>
|
35 |
+
<visible>1</visible>
|
36 |
+
<type>text</type>
|
37 |
+
<!-- <value>5D2D87</value> -->
|
38 |
+
<description>If empty, the color 660066 (purple) will be used</description>
|
39 |
+
</swe_background_color>
|
40 |
+
<swe_expiryoffset translate="label">
|
41 |
+
<label>Expiry Offset (in minutes)</label>
|
42 |
+
<visible>1</visible>
|
43 |
+
<type>text</type>
|
44 |
+
<description>If empty, it uses the default value defined in the configuration.</description>
|
45 |
+
</swe_expiryoffset>
|
46 |
+
<swe_min translate="label">
|
47 |
+
<label>Minimum Discount </label>
|
48 |
+
<description>If empty, it uses the default value defined in the configuration.</description>
|
49 |
+
<type>text</type>
|
50 |
+
<visible>1</visible>
|
51 |
+
</swe_min>
|
52 |
+
<swe_max translate="label">
|
53 |
+
<label>Maximum Discount </label>
|
54 |
+
<description>If empty, it uses the default value defined in the configuration.</description>
|
55 |
+
<visible>1</visible>
|
56 |
+
<type>text</type>
|
57 |
+
</swe_max>
|
58 |
+
<template translate="label">
|
59 |
+
<label>Frontend Template</label>
|
60 |
+
<visible>1</visible>
|
61 |
+
<required>1</required>
|
62 |
+
<type>select</type>
|
63 |
+
<values>
|
64 |
+
<button translate="label">
|
65 |
+
<value>swe/optipricer/widget.phtml</value>
|
66 |
+
<label>Share Button (Optipricer)</label>
|
67 |
+
</button>
|
68 |
+
</values>
|
69 |
+
</template>
|
70 |
+
</parameters>
|
71 |
+
</optipricer_discount>
|
72 |
+
</widgets>
|
app/design/frontend/base/default/template/swe/optipricer/widget.phtml
ADDED
@@ -0,0 +1,371 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<style>
|
2 |
+
|
3 |
+
/** =====================
|
4 |
+
* Default Look and Feel
|
5 |
+
====================== **/
|
6 |
+
|
7 |
+
.alertify-logs {
|
8 |
+
position: fixed;
|
9 |
+
z-index: 5000;
|
10 |
+
top: 10px;
|
11 |
+
right: 10px;
|
12 |
+
width: 300px;
|
13 |
+
}
|
14 |
+
.alertify,
|
15 |
+
.alertify-log {
|
16 |
+
font-family: sans-serif;
|
17 |
+
}
|
18 |
+
.alertify {
|
19 |
+
background: #FFF;
|
20 |
+
border: 10px solid #333; /* browsers that don't support rgba */
|
21 |
+
border: 10px solid rgba(0,0,0,.7);
|
22 |
+
border-radius: 8px;
|
23 |
+
box-shadow: 0 3px 3px rgba(0,0,0,.3);
|
24 |
+
-webkit-background-clip: padding; /* Safari 4? Chrome 6? */
|
25 |
+
-moz-background-clip: padding; /* Firefox 3.6 */
|
26 |
+
background-clip: padding-box; /* Firefox 4, Safari 5, Opera 10, IE 9 */
|
27 |
+
}
|
28 |
+
.alertify-text {
|
29 |
+
border: 1px solid #CCC;
|
30 |
+
padding: 10px;
|
31 |
+
border-radius: 4px;
|
32 |
+
}
|
33 |
+
.alertify-button {
|
34 |
+
border-radius: 4px;
|
35 |
+
color: #FFF;
|
36 |
+
font-weight: bold;
|
37 |
+
padding: 6px 15px;
|
38 |
+
text-decoration: none;
|
39 |
+
text-shadow: 1px 1px 0 rgba(0,0,0,.5);
|
40 |
+
box-shadow: inset 0 1px 0 0 rgba(255,255,255,.5);
|
41 |
+
background-image: -webkit-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
|
42 |
+
background-image: -moz-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
|
43 |
+
background-image: -ms-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
|
44 |
+
background-image: -o-linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
|
45 |
+
background-image: linear-gradient(top, rgba(255,255,255,.3), rgba(255,255,255,0));
|
46 |
+
}
|
47 |
+
.alertify-button:hover,
|
48 |
+
.alertify-button:focus {
|
49 |
+
outline: none;
|
50 |
+
background-image: -webkit-linear-gradient(top, rgba(0,0,0,.1), rgba(0,0,0,0));
|
51 |
+
background-image: -moz-linear-gradient(top, rgba(0,0,0,.1), rgba(0,0,0,0));
|
52 |
+
background-image: -ms-linear-gradient(top, rgba(0,0,0,.1), rgba(0,0,0,0));
|
53 |
+
background-image: -o-linear-gradient(top, rgba(0,0,0,.1), rgba(0,0,0,0));
|
54 |
+
background-image: linear-gradient(top, rgba(0,0,0,.1), rgba(0,0,0,0));
|
55 |
+
}
|
56 |
+
.alertify-button:focus {
|
57 |
+
box-shadow: 0 0 15px #2B72D5;
|
58 |
+
}
|
59 |
+
.alertify-button:active {
|
60 |
+
position: relative;
|
61 |
+
box-shadow: inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);
|
62 |
+
}
|
63 |
+
.alertify-button-cancel,
|
64 |
+
.alertify-button-cancel:hover,
|
65 |
+
.alertify-button-cancel:focus {
|
66 |
+
background-color: #FE1A00;
|
67 |
+
border: 1px solid #D83526;
|
68 |
+
}
|
69 |
+
.alertify-button-ok,
|
70 |
+
.alertify-button-ok:hover,
|
71 |
+
.alertify-button-ok:focus {
|
72 |
+
background-color: #5CB811;
|
73 |
+
border: 1px solid #3B7808;
|
74 |
+
}
|
75 |
+
|
76 |
+
.alertify-log {
|
77 |
+
background: #1F1F1F;
|
78 |
+
background: rgba(0,0,0,.9);
|
79 |
+
padding: 15px;
|
80 |
+
border-radius: 4px;
|
81 |
+
color: #FFF;
|
82 |
+
text-shadow: -1px -1px 0 rgba(0,0,0,.5);
|
83 |
+
}
|
84 |
+
.alertify-log-error {
|
85 |
+
background: #FE1A00;
|
86 |
+
background: rgba(254,26,0,.9);
|
87 |
+
}
|
88 |
+
.alertify-log-success {
|
89 |
+
background: #5CB811;
|
90 |
+
background: rgba(92,184,17,.9);
|
91 |
+
}
|
92 |
+
|
93 |
+
.alertify,
|
94 |
+
.alertify-show,
|
95 |
+
.alertify-log {
|
96 |
+
-webkit-transition: all 500ms cubic-bezier(0.175, 0.885, 0.320, 1.275);
|
97 |
+
-moz-transition: all 500ms cubic-bezier(0.175, 0.885, 0.320, 1.275);
|
98 |
+
-ms-transition: all 500ms cubic-bezier(0.175, 0.885, 0.320, 1.275);
|
99 |
+
-o-transition: all 500ms cubic-bezier(0.175, 0.885, 0.320, 1.275);
|
100 |
+
transition: all 500ms cubic-bezier(0.175, 0.885, 0.320, 1.275); /* easeOutBack */
|
101 |
+
}
|
102 |
+
.alertify-hide {
|
103 |
+
-webkit-transition: all 250ms cubic-bezier(0.600, -0.280, 0.735, 0.045);
|
104 |
+
-moz-transition: all 250ms cubic-bezier(0.600, -0.280, 0.735, 0.045);
|
105 |
+
-ms-transition: all 250ms cubic-bezier(0.600, -0.280, 0.735, 0.045);
|
106 |
+
-o-transition: all 250ms cubic-bezier(0.600, -0.280, 0.735, 0.045);
|
107 |
+
transition: all 250ms cubic-bezier(0.600, -0.280, 0.735, 0.045); /* easeInBack */
|
108 |
+
}
|
109 |
+
.alertify-log-hide {
|
110 |
+
-webkit-transition: all 500ms cubic-bezier(0.600, -0.280, 0.735, 0.045);
|
111 |
+
-moz-transition: all 500ms cubic-bezier(0.600, -0.280, 0.735, 0.045);
|
112 |
+
-ms-transition: all 500ms cubic-bezier(0.600, -0.280, 0.735, 0.045);
|
113 |
+
-o-transition: all 500ms cubic-bezier(0.600, -0.280, 0.735, 0.045);
|
114 |
+
transition: all 500ms cubic-bezier(0.600, -0.280, 0.735, 0.045); /* easeInBack */
|
115 |
+
}
|
116 |
+
.alertify-cover {
|
117 |
+
position: fixed; z-index: 99999;
|
118 |
+
top: 0; right: 0; bottom: 0; left: 0;
|
119 |
+
background-color:white;
|
120 |
+
filter:alpha(opacity=0);
|
121 |
+
opacity:0;
|
122 |
+
}
|
123 |
+
.alertify-cover-hidden {
|
124 |
+
display: none;
|
125 |
+
}
|
126 |
+
.alertify {
|
127 |
+
position: fixed; z-index: 99999;
|
128 |
+
top: 50px; left: 50%;
|
129 |
+
width: 550px;
|
130 |
+
margin-left: -275px;
|
131 |
+
opacity: 1;
|
132 |
+
}
|
133 |
+
.alertify-hidden {
|
134 |
+
-webkit-transform: translate(0,-150px);
|
135 |
+
-moz-transform: translate(0,-150px);
|
136 |
+
-ms-transform: translate(0,-150px);
|
137 |
+
-o-transform: translate(0,-150px);
|
138 |
+
transform: translate(0,-150px);
|
139 |
+
opacity: 0;
|
140 |
+
display: none;
|
141 |
+
}
|
142 |
+
/* overwrite display: none; for everything except IE6-8 */
|
143 |
+
:root *> .alertify-hidden {
|
144 |
+
display: block;
|
145 |
+
visibility: hidden;
|
146 |
+
}
|
147 |
+
.alertify-logs {
|
148 |
+
position: fixed;
|
149 |
+
z-index: 5000;
|
150 |
+
bottom: 10px;
|
151 |
+
right: 10px;
|
152 |
+
width: 300px;
|
153 |
+
}
|
154 |
+
.alertify-logs-hidden {
|
155 |
+
display: none;
|
156 |
+
}
|
157 |
+
.alertify-log {
|
158 |
+
display: block;
|
159 |
+
margin-top: 10px;
|
160 |
+
position: relative;
|
161 |
+
right: -300px;
|
162 |
+
opacity: 0;
|
163 |
+
}
|
164 |
+
.alertify-log-show {
|
165 |
+
right: 0;
|
166 |
+
opacity: 1;
|
167 |
+
}
|
168 |
+
.alertify-log-hide {
|
169 |
+
-webkit-transform: translate(300px, 0);
|
170 |
+
-moz-transform: translate(300px, 0);
|
171 |
+
-ms-transform: translate(300px, 0);
|
172 |
+
-o-transform: translate(300px, 0);
|
173 |
+
transform: translate(300px, 0);
|
174 |
+
opacity: 0;
|
175 |
+
}
|
176 |
+
.alertify-dialog {
|
177 |
+
padding: 25px;
|
178 |
+
}
|
179 |
+
.alertify-resetFocus {
|
180 |
+
border: 0;
|
181 |
+
clip: rect(0 0 0 0);
|
182 |
+
height: 1px;
|
183 |
+
margin: -1px;
|
184 |
+
overflow: hidden;
|
185 |
+
padding: 0;
|
186 |
+
position: absolute;
|
187 |
+
width: 1px;
|
188 |
+
}
|
189 |
+
.alertify-inner {
|
190 |
+
text-align: center;
|
191 |
+
}
|
192 |
+
.alertify-text {
|
193 |
+
margin-bottom: 15px;
|
194 |
+
width: 100%;
|
195 |
+
-webkit-box-sizing: border-box;
|
196 |
+
-moz-box-sizing: border-box;
|
197 |
+
box-sizing: border-box;
|
198 |
+
font-size: 100%;
|
199 |
+
}
|
200 |
+
.alertify-buttons {
|
201 |
+
}
|
202 |
+
.alertify-button,
|
203 |
+
.alertify-button:hover,
|
204 |
+
.alertify-button:active,
|
205 |
+
.alertify-button:visited {
|
206 |
+
background: none;
|
207 |
+
text-decoration: none;
|
208 |
+
border: none;
|
209 |
+
/* line-height and font-size for input button */
|
210 |
+
line-height: 1.5;
|
211 |
+
font-size: 100%;
|
212 |
+
display: inline-block;
|
213 |
+
cursor: pointer;
|
214 |
+
margin-left: 5px;
|
215 |
+
}
|
216 |
+
|
217 |
+
@media only screen and (max-width: 680px) {
|
218 |
+
.alertify,
|
219 |
+
.alertify-logs {
|
220 |
+
width: 90%;
|
221 |
+
-webkit-box-sizing: border-box;
|
222 |
+
-moz-box-sizing: border-box;
|
223 |
+
box-sizing: border-box;
|
224 |
+
}
|
225 |
+
.alertify {
|
226 |
+
left: 5%;
|
227 |
+
margin: 0;
|
228 |
+
}
|
229 |
+
}
|
230 |
+
|
231 |
+
|
232 |
+
textarea {
|
233 |
+
resize: none;
|
234 |
+
display: block;
|
235 |
+
width: 100%;
|
236 |
+
max-width:none;
|
237 |
+
}
|
238 |
+
|
239 |
+
.fade{
|
240 |
+
position: absolute;
|
241 |
+
display: none;
|
242 |
+
background-color:#FFF;
|
243 |
+
opacity: 0.7;
|
244 |
+
filter: alpha(opacity=70);
|
245 |
+
}
|
246 |
+
|
247 |
+
.form-control {
|
248 |
+
display: block;
|
249 |
+
width: 100%;
|
250 |
+
height: 34px;
|
251 |
+
padding: 6px;
|
252 |
+
font-size: 14px;
|
253 |
+
line-height: 1.42857143;
|
254 |
+
color: #555555;
|
255 |
+
background-color: #ffffff;
|
256 |
+
background-image: none;
|
257 |
+
border: 1px solid #cccccc;
|
258 |
+
border-radius: 4px;
|
259 |
+
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
260 |
+
box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
|
261 |
+
-webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
262 |
+
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
263 |
+
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
|
264 |
+
}
|
265 |
+
.form-control:focus {
|
266 |
+
border-color: #66afe9;
|
267 |
+
background-color: #fff;
|
268 |
+
outline: 0;
|
269 |
+
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
|
270 |
+
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);
|
271 |
+
}
|
272 |
+
.form-control::-moz-placeholder {
|
273 |
+
color: #999999;
|
274 |
+
opacity: 1;
|
275 |
+
}
|
276 |
+
.form-control:-ms-input-placeholder {
|
277 |
+
color: #999999;
|
278 |
+
}
|
279 |
+
.form-control::-webkit-input-placeholder {
|
280 |
+
color: #999999;
|
281 |
+
}
|
282 |
+
.form-control[disabled],
|
283 |
+
.form-control[readonly],
|
284 |
+
fieldset[disabled] .form-control {
|
285 |
+
cursor: not-allowed;
|
286 |
+
background-color: #eeeeee;
|
287 |
+
opacity: 1;
|
288 |
+
}
|
289 |
+
textarea.form-control {
|
290 |
+
height: auto;
|
291 |
+
}
|
292 |
+
|
293 |
+
.buttons-opti,
|
294 |
+
.buttons-opti:hover{
|
295 |
+
height: auto;
|
296 |
+
width: 100%;
|
297 |
+
color: <?php echo $fontcolor; ?> ;
|
298 |
+
padding: 12px 30px;
|
299 |
+
font-size: 14px;
|
300 |
+
font-weight: bold;
|
301 |
+
text-transform: uppercase;
|
302 |
+
border: 0;
|
303 |
+
border-radius: 10px;
|
304 |
+
text-decoration: none;
|
305 |
+
-moz-border-radius: 10px;
|
306 |
+
-webkit-border-radius: 10px;
|
307 |
+
cursor: pointer;
|
308 |
+
}
|
309 |
+
|
310 |
+
.discount-opti{
|
311 |
+
color:green;
|
312 |
+
font-weight: bold;
|
313 |
+
}
|
314 |
+
|
315 |
+
.buttons-purple{
|
316 |
+
background-color: <?php echo $buttoncolor; ?> ;
|
317 |
+
}
|
318 |
+
|
319 |
+
.form-group{
|
320 |
+
margin-bottom:20px;
|
321 |
+
}
|
322 |
+
|
323 |
+
</style>
|
324 |
+
|
325 |
+
<div id="main-optipricer">
|
326 |
+
<div class="fade"></div>
|
327 |
+
<div id="background1">
|
328 |
+
<form name="widget-form" action="#" method="post">
|
329 |
+
<textarea id="form_comment" rows="5" class="form-group form-control"><?php echo $transComment;?></textarea>
|
330 |
+
<button id="optibutton" type="button" class="buttons-opti buttons-purple form-group"><?php echo $transButton;?></button>
|
331 |
+
</form>
|
332 |
+
</div>
|
333 |
+
</div>
|
334 |
+
<hr>
|
335 |
+
<script>
|
336 |
+
var cp = new Coupon(<?php echo $offer['name'];?>, "<?php echo $offer['data'];?>", "<?php echo $offer['store_token'];?>", "<?php echo $offer['product_id']; ?>", <?php echo $offer['o_price']; ?>, "<?php echo $offer['formatted_price']?>", "<?php echo $offer['url_api'];?>", "<?php echo $offer['currency'];?>");
|
337 |
+
|
338 |
+
function statusChangeCallback(response) {
|
339 |
+
cp.readCookie();
|
340 |
+
var logged = cp.getLoginStatus(response);
|
341 |
+
if (cp.cookie && logged) {
|
342 |
+
cp.handleRequest(null);
|
343 |
+
} else {
|
344 |
+
cp.removeSpin();
|
345 |
+
}
|
346 |
+
}
|
347 |
+
window.fbAsyncInit = function () {
|
348 |
+
FB.init({
|
349 |
+
appId: '263200773711733',
|
350 |
+
xfbml: true,
|
351 |
+
version: 'v2.2'
|
352 |
+
});
|
353 |
+
|
354 |
+
FB.getLoginStatus(function (response) {
|
355 |
+
statusChangeCallback(response);
|
356 |
+
});
|
357 |
+
};
|
358 |
+
|
359 |
+
(function (d, s, id) {
|
360 |
+
var js, fjs = d.getElementsByTagName(s)[0];
|
361 |
+
if (d.getElementById(id)) {
|
362 |
+
return;
|
363 |
+
}
|
364 |
+
js = d.createElement(s);
|
365 |
+
js.id = id;
|
366 |
+
js.src = "//connect.facebook.net/<?php echo $offer['locale'];?>/all.js";
|
367 |
+
fjs.parentNode.insertBefore(js, fjs);
|
368 |
+
}(document, 'script', 'facebook-jssdk'));
|
369 |
+
</script>
|
370 |
+
|
371 |
+
|
app/etc/modules/SWE_Optipricer.xml
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<SWE_Optipricer>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>local</codePool>
|
7 |
+
<depends>
|
8 |
+
<Mage_Cms />
|
9 |
+
</depends>
|
10 |
+
<version>1.0.0</version>
|
11 |
+
</SWE_Optipricer>
|
12 |
+
</modules>
|
13 |
+
</config>
|
app/locale/en_US/SWE_Optipricer.csv
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Share and get a discount!"
|
2 |
+
"Hey! Check this"
|
3 |
+
"I found on"
|
4 |
+
"I loved it!"
|
5 |
+
"cennasssss"
|
app/locale/pt_PT/SWE_Optipricer.csv
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
"Share and get a discount!", "Partilhe e ganhe um desconto!"
|
2 |
+
"Hey! Check this", "Hey! Vê este produto"
|
3 |
+
"I found on", "que encontrei na loja"
|
4 |
+
"I loved it!", "Eu achei o máximo!"
|
5 |
+
"cennasssss", "coisasss"
|
js/swe/optialert.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
!function(a,b){"use strict";var c,d=a.document;c=function(){var c,e,f,g,h,i,j,k,l,m,n,o,p,q={},r={},s=!1,t={ENTER:13,ESC:27,SPACE:32},u=[];return r={buttons:{holder:'<nav class="alertify-buttons">{{buttons}}</nav>',submit:'<button type="submit" class="alertify-button alertify-button-ok" id="alertify-ok">{{ok}}</button>',ok:'<button class="alertify-button alertify-button-ok" id="alertify-ok">{{ok}}</button>',cancel:'<button class="alertify-button alertify-button-cancel" id="alertify-cancel">{{cancel}}</button>'},input:'<div class="alertify-text-wrapper"><input type="text" class="alertify-text" id="alertify-text"></div>',message:'<p class="alertify-message">{{message}}</p>',log:'<article class="alertify-log{{class}}">{{message}}</article>'},p=function(){var a,c,e=!1,f=d.createElement("fakeelement"),g={WebkitTransition:"webkitTransitionEnd",MozTransition:"transitionend",OTransition:"otransitionend",transition:"transitionend"};for(a in g)if(f.style[a]!==b){c=g[a],e=!0;break}return{type:c,supported:e}},c=function(a){return d.getElementById(a)},q={labels:{ok:"OK",cancel:"Cancel"},delay:5e3,buttonReverse:!1,buttonFocus:"ok",transition:b,addListeners:function(a){var b,c,i,j,k,l="undefined"!=typeof f,m="undefined"!=typeof e,n="undefined"!=typeof o,p="",q=this;b=function(b){return"undefined"!=typeof b.preventDefault&&b.preventDefault(),i(b),"undefined"!=typeof o&&(p=o.value),"function"==typeof a&&("undefined"!=typeof o?a(!0,p):a(!0)),!1},c=function(b){return"undefined"!=typeof b.preventDefault&&b.preventDefault(),i(b),"function"==typeof a&&a(!1),!1},i=function(){q.hide(),q.unbind(d.body,"keyup",j),q.unbind(g,"focus",k),l&&q.unbind(f,"click",b),m&&q.unbind(e,"click",c)},j=function(a){var d=a.keyCode;(d===t.SPACE&&!n||n&&d===t.ENTER)&&b(a),d===t.ESC&&m&&c(a)},k=function(){n?o.focus():!m||q.buttonReverse?f.focus():e.focus()},this.bind(g,"focus",k),this.bind(h,"focus",k),l&&this.bind(f,"click",b),m&&this.bind(e,"click",c),this.bind(d.body,"keyup",j),this.transition.supported||this.setFocus()},bind:function(a,b,c){"function"==typeof a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,c)},handleErrors:function(){if("undefined"!=typeof a.onerror){var b=this;return a.onerror=function(a,c,d){b.error("["+a+" on line "+d+" of "+c+"]",0)},!0}return!1},appendButtons:function(a,b){return this.buttonReverse?b+a:a+b},build:function(a){var b="",c=a.type,d=a.message,e=a.cssClass||"";switch(b+='<div class="alertify-dialog">',b+='<a id="alertify-resetFocusBack" class="alertify-resetFocus" href="#">Reset Focus</a>',"none"===q.buttonFocus&&(b+='<a href="#" id="alertify-noneFocus" class="alertify-hidden"></a>'),"prompt"===c&&(b+='<div id="alertify-form">'),b+='<article class="alertify-inner">',b+=r.message.replace("{{message}}",d),"prompt"===c&&(b+=r.input),b+=r.buttons.holder,b+="</article>","prompt"===c&&(b+="</div>"),b+='<a id="alertify-resetFocus" class="alertify-resetFocus" href="#">Reset Focus</a>',b+="</div>",c){case"confirm":b=b.replace("{{buttons}}",this.appendButtons(r.buttons.cancel,r.buttons.ok)),b=b.replace("{{ok}}",this.labels.ok).replace("{{cancel}}",this.labels.cancel);break;case"prompt":b=b.replace("{{buttons}}",this.appendButtons(r.buttons.cancel,r.buttons.submit)),b=b.replace("{{ok}}",this.labels.ok).replace("{{cancel}}",this.labels.cancel);break;case"alert":b=b.replace("{{buttons}}",r.buttons.ok),b=b.replace("{{ok}}",this.labels.ok)}return l.className="alertify alertify-"+c+" "+e,k.className="alertify-cover",b},close:function(a,b){var c,d,e=b&&!isNaN(b)?+b:this.delay,f=this;this.bind(a,"click",function(){c(a)}),d=function(a){a.stopPropagation(),f.unbind(this,f.transition.type,d),m.removeChild(this),m.hasChildNodes()||(m.className+=" alertify-logs-hidden")},c=function(a){"undefined"!=typeof a&&a.parentNode===m&&(f.transition.supported?(f.bind(a,f.transition.type,d),a.className+=" alertify-log-hide"):(m.removeChild(a),m.hasChildNodes()||(m.className+=" alertify-logs-hidden")))},0!==b&&setTimeout(function(){c(a)},e)},dialog:function(a,b,c,e,f){j=d.activeElement;var g=function(){m&&null!==m.scrollTop&&k&&null!==k.scrollTop||g()};if("string"!=typeof a)throw new Error("message must be a string");if("string"!=typeof b)throw new Error("type must be a string");if("undefined"!=typeof c&&"function"!=typeof c)throw new Error("fn must be a function");return this.init(),g(),u.push({type:b,message:a,callback:c,placeholder:e,cssClass:f}),s||this.setup(),this},extend:function(a){if("string"!=typeof a)throw new Error("extend method must have exactly one paramter");return function(b,c){return this.log(b,a,c),this}},hide:function(){var a,b=this;u.splice(0,1),u.length>0?this.setup(!0):(s=!1,a=function(c){c.stopPropagation(),b.unbind(l,b.transition.type,a)},this.transition.supported?(this.bind(l,this.transition.type,a),l.className="alertify alertify-hide alertify-hidden"):l.className="alertify alertify-hide alertify-hidden alertify-isHidden",k.className="alertify-cover alertify-cover-hidden",j.focus())},init:function(){d.createElement("nav"),d.createElement("article"),d.createElement("section"),null==c("alertify-cover")&&(k=d.createElement("div"),k.setAttribute("id","alertify-cover"),k.className="alertify-cover alertify-cover-hidden",d.body.appendChild(k)),null==c("alertify")&&(s=!1,u=[],l=d.createElement("section"),l.setAttribute("id","alertify"),l.className="alertify alertify-hidden",d.body.appendChild(l)),null==c("alertify-logs")&&(m=d.createElement("section"),m.setAttribute("id","alertify-logs"),m.className="alertify-logs alertify-logs-hidden",d.body.appendChild(m)),d.body.setAttribute("tabindex","0"),this.transition=p()},log:function(a,b,c){var d=function(){m&&null!==m.scrollTop||d()};return this.init(),d(),m.className="alertify-logs",this.notify(a,b,c),this},notify:function(a,b,c){var e=d.createElement("article");e.className="alertify-log"+("string"==typeof b&&""!==b?" alertify-log-"+b:""),e.innerHTML=a,m.appendChild(e),setTimeout(function(){e.className=e.className+" alertify-log-show"},50),this.close(e,c)},set:function(a){var b;if("object"!=typeof a&&a instanceof Array)throw new Error("args must be an object");for(b in a)a.hasOwnProperty(b)&&(this[b]=a[b])},setFocus:function(){o?(o.focus(),o.select()):i.focus()},setup:function(a){var d,j=u[0],k=this;s=!0,d=function(a){a.stopPropagation(),k.setFocus(),k.unbind(l,k.transition.type,d)},this.transition.supported&&!a&&this.bind(l,this.transition.type,d),l.innerHTML=this.build(j),g=c("alertify-resetFocus"),h=c("alertify-resetFocusBack"),f=c("alertify-ok")||b,e=c("alertify-cancel")||b,i="cancel"===q.buttonFocus?e:"none"===q.buttonFocus?c("alertify-noneFocus"):f,o=c("alertify-text")||b,n=c("alertify-form")||b,"string"==typeof j.placeholder&&""!==j.placeholder&&(o.value=j.placeholder),a&&this.setFocus(),this.addListeners(j.callback)},unbind:function(a,b,c){"function"==typeof a.removeEventListener?a.removeEventListener(b,c,!1):a.detachEvent&&a.detachEvent("on"+b,c)}},{alert:function(a,b,c){return q.dialog(a,"alert",b,"",c),this},confirm:function(a,b,c){return q.dialog(a,"confirm",b,"",c),this},extend:q.extend,init:q.init,log:function(a,b,c){return q.log(a,b,c),this},prompt:function(a,b,c,d){return q.dialog(a,"prompt",b,c,d),this},success:function(a,b){return q.log(a,"success",b),this},error:function(a,b){return q.log(a,"error",b),this},set:function(a){q.set(a)},labels:q.labels,debug:q.handleErrors}},"function"==typeof define?define([],function(){return new c}):"undefined"==typeof a.alertify&&(a.alertify=new c)}(this);
|
js/swe/optipricer.min.js
ADDED
@@ -0,0 +1 @@
|
|
|
1 |
+
function Coupon(e,t,i,s,n,o,r,a){var c={n:e,d:t,st:i,p:s,o_p:n,o_pf:o,url:r,ps:a};this._initialize(c),this.setSpin();var h=this;document.getElementById("optibutton").addEventListener("click",function(e){e.preventDefault(),e.stopPropagation(),h.socialCredentials&&h.socialCredentials.facebookToken?(h.sendForm(),h.lockPermissions=!0):(h.checkLogin(h.perms,!0),h.lockPermissions=!1)})}function treatError(e,t,i){var s='{"msg":"'+e+'", "url":"'+t+'", "line":'+i+"}";sendRequest("logs/create","post",s,500,1,function(){})}function sendRequest(e,t,i,s,n,o){var r=cp.url+""+e,a="Token "+cp.st,c=null,h=new XMLHttpRequest;h.open(t.toUpperCase(),encodeURI(r),!0),h.setRequestHeader("Authorization",a),h.onreadystatechange=function l(){200!=h.status&&201!=h.status&&204!=h.status&&304!=h.status?(n++,s=4*s,6>n&&(c=window.setTimeout(function(){h.open(t.toUpperCase(),encodeURI(r),!0),h.onreadystatechange=l(),h.send(i)},s))):(c&&clearTimeout(c),o(h))},null!==i&&h.send(i)}var coupon={_initialize:function(e){this.d=e.d,this.n=e.n,this.st=e.st,this.p=e.p,this.ck_n="discount_"+this.st+"_"+this.p,this.url=e.url,this.o_p=e.o_p,this.o_pf=e.o_pf,this.p_s=e.ps,this.v=null,this.html=null,this.opts={lines:13,length:10,width:5,radius:10,corners:1,rotate:0,direction:1,color:"#010046",speed:1,trail:60,shadow:!0,hwaccel:!1,className:"spinner",zIndex:2e9,top:"43%",left:"54%"},this.spinner=new Spinner(this.opts),this.perms=["email","read_stream","user_interests","user_relationships","user_birthday","user_likes","user_work_history","user_education_history","publish_actions"]},_findRiskPrice:function(e){var t=this._htmlTree(document.getElementById("main-optipricer"),this.n);t&&this._riskPrice(t,e)},_htmlTree:function(e,t){var i=null;if(e.parentNode){var s=e.parentNode;s.childNodes.length>1&&(i=this._searchParent(s,t)),null===i&&this._htmlTree(s.parentNode,t)}return i},_replaceDiv:function(e,t,i){var s=document.getElementById(e);if(i)s.innerHTML="",s.innerHTML=t;else{var n=document.getElementById("opti-fbmessage");n?n.innerText=t:(n=document.createElement("h4"),n.id="opti-fbmessage",n.innerText=t,s.appendChild(n))}},_riskPrice:function(e,t){var i,s,n,o,r=e.childNodes,a=this.o_p.toString().replace(".",",");for(i=0;i<r.length;i++)r[i].hasChildNodes()&&r[i].innerHTML?this._riskPrice(r[i],t):(o=void 0!==r[i].innerHTML?r[i].innerHTML:r[i].data,n=e.parentNode,-1===o.indexOf(this.p_s)||-1===o.indexOf(this.o_pf)&&-1===o.indexOf(a)||-1!==n.className.indexOf("opti-discount")||(this.p_symbol=o.indexOf(this.p_s)>3?!0:!1,s=e.cloneNode(!0),s.innerHTML=this.getPriceToPrint(-1!==o.indexOf(".")?!0:!1),s.style.display="block",n.className=n.className+" opti-discount",n.appendChild(s),e.style.textDecoration="line-through"))},_searchParent:function(e,t){var i,s=e.childNodes;for(i=0;i<s.length;i++)if(void 0!==s[i].tagName&&"main-optipricer"!==s[i].id){if(-1!==s[i].innerHTML.indexOf(t))return e;s[i].hasChildNodes()&&this._searchParent(s[i],t)}return null},_toHtml:function(){var e=document.createElement("h2"),t=document.createElement("div");return t.id="optipricerdiscount"," "+e.outerHTML+" "+t.outerHTML},_missingPermissions:function(e){var t,i,s=[];if(e){for(i=0;i<this.perms.length;i++){var n=!1;for(t=0;t<e.length;t++)e[t].permission===this.perms[i]&&"granted"===e[t].status&&(n=!0,t=e.length);n||s.push(this.perms[i])}return s}return void 0},checkLogin:function(e,t){var i=this;FB.login(function(e){i.getLoginStatus(e)&&(i.cookie?i.handleRequest(null):FB.api("/v2.2/"+i.socialCredentials.facebookId+"/permissions","GET",function(e){var s=i._missingPermissions(e.data);0===s.length?i.sendForm():t&&i.sendForm()}))},{scope:e.join(",")})},checkPermissions:function(e){if(this.lockPermissions){var t=this,i=[];FB.api("/v2.2/"+t.socialCredentials.facebookId+"/permissions","GET",function(s){i=t._missingPermissions(s.data),void 0===i?t.checkLogin(t.perms,!0):i.length>0&&(t._replaceDiv("background1",e,!1),t.checkLogin(i,!1))}),this.removeSpin()}else this._replaceDiv("background1",e,!1),this.removeSpin()},createCookie:function(){document.cookie=this.ck_n+"="+this.c+":"+this.n+":"+this.v+":"+this.socialCredentials.facebookId+"; expires="+this.expires+"; path=/"},getLoginStatus:function(e){if("connected"===e.status){var t={facebookId:e.authResponse.userID,facebookToken:e.authResponse.accessToken};return this.setSocialCredentials(t),!0}return!1},getPriceToPrint:function(e){var t=e?this.v.toString():this.v.toString().replace(".",",");return this.p_symbol?t+" "+this.p_s:this.p_s+" "+t},handleErrors:function(e){var t=JSON.parse(e.responseText);switch(t.errorCode){case 1:case 2:case 3:case 4:case 6:this.removeSpin(),this._replaceDiv("main-optipricer",t.html,!0);break;case 5:this.checkPermissions(t.message)}},handleRequest:function(e){var t;e&&(t=JSON.parse(e.response),this.c=t.coupon,this.v=t.value,this.expires=new Date(1e3*t.expiryTime).toString(),this.createCookie()),this._findRiskPrice(this.v),this.removeSpin(),this.html=t&&t.html?t.html:this.html?this.html:this._toHtml(),this._replaceDiv("background1",this.html,!0);var i=(this.o_p-this.v)/this.o_p*100;document.getElementById("optipricerdiscount").innerHTML="<h5>You got a <span class='discount-opti'>"+i.toFixed(0)+"%</span> discount</h5>"},readCookie:function(){this.setSpin();var e="; "+document.cookie,t=e.split("; "+this.ck_n+"=");if(2===t.length){var i=t[1].split(":");this.cookie=!0,this.c=i[0],this.n=i[1],this.v=i[2],this.socialCredentials={},this.socialCredentials.facebookId=i[3].split(";")[0]}else this.cookie=!1},removeSpin:function(){var e=document.getElementsByClassName("fade")[0];e.style.display="none",this.spinner.stop()},sendForm:function(){this.setComment(document.getElementById("form_comment").value);var e=this.toJson();if(this.comment.length>2){document.getElementById("form_comment").setCustomValidity("");var t=this.url+"coupon/",i=[["Authorization","Token "+this.st]];i.push(["Accept","application/json"]),this.setSpin(),this.sendRequest(t,"POST",i,e,this)}else alertify.custom=alertify.extend("custom"),alertify.custom("You must comment something about the product..")},sendRequest:function(e,t,i,s,n){var o,r=new XMLHttpRequest,a=!0;for(r.open(t.toUpperCase(),encodeURI(e),!0),o=0;o<i.length;o++)2===i[o].length?r.setRequestHeader(i[o][0],i[o][1]):a=!1;if(a){var c=0;r.onreadystatechange=function(){if(200!=r.status&&201!=r.status&&204!=r.status&&304!=r.status)try{JSON.parse(r.responseText),""!==r.responseText&&0===c&&(c++,n.handleErrors(r))}catch(t){n.removeSpin(),treatError("[widget-magento]"+t.message,e,0)}else n.handleRequest(r)},null!==s&&r.send(new Blob([s],{type:"application/json"}))}else console.log("The input headers are defined wrong, must be a bi dimensional array, header[x][2]")},setComment:function(e){this.comment=e},setSocialCredentials:function(e){this.socialCredentials?this.socialCredentials.facebookId===e.facebookId?this.socialCredentials.facebookToken=e.facebookToken:(this.cookie=!1,this.socialCredentials.facebookId=e.facebookId,this.socialCredentials.facebookToken=e.facebookToken):(this.socialCredentials={},this.socialCredentials.facebookId=e.facebookId,this.socialCredentials.facebookToken=e.facebookToken)},setSpin:function(){var e=document.getElementsByClassName("fade")[0],t=document.getElementById("main-optipricer");e.style.display="block",e.style.width=t.offsetWidth+"px",e.style.height=t.offsetHeight+"px",this.spinner.spin(e)},toJson:function(){var e={data:this.d,social_credentials:this.socialCredentials,comment:this.comment};return JSON.stringify(e)}};Coupon.prototype=coupon,window.onerror=function(e,t,i){treatError(e,t,i)};
|
js/swe/optispin.min.js
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
1 |
+
//fgnass.github.com/spin.js#v2.0.1
|
2 |
+
!function(a,b){"object"==typeof exports?module.exports=b():"function"==typeof define&&define.amd?define(b):a.Spinner=b()}(this,function(){"use strict";function a(a,b){var c,d=document.createElement(a||"div");for(c in b)d[c]=b[c];return d}function b(a){for(var b=1,c=arguments.length;c>b;b++)a.appendChild(arguments[b]);return a}function c(a,b,c,d){var e=["opacity",b,~~(100*a),c,d].join("-"),f=.01+c/d*100,g=Math.max(1-(1-a)/b*(100-f),a),h=j.substring(0,j.indexOf("Animation")).toLowerCase(),i=h&&"-"+h+"-"||"";return l[e]||(m.insertRule("@"+i+"keyframes "+e+"{0%{opacity:"+g+"}"+f+"%{opacity:"+a+"}"+(f+.01)+"%{opacity:1}"+(f+b)%100+"%{opacity:"+a+"}100%{opacity:"+g+"}}",m.cssRules.length),l[e]=1),e}function d(a,b){var c,d,e=a.style;for(b=b.charAt(0).toUpperCase()+b.slice(1),d=0;d<k.length;d++)if(c=k[d]+b,void 0!==e[c])return c;return void 0!==e[b]?b:void 0}function e(a,b){for(var c in b)a.style[d(a,c)||c]=b[c];return a}function f(a){for(var b=1;b<arguments.length;b++){var c=arguments[b];for(var d in c)void 0===a[d]&&(a[d]=c[d])}return a}function g(a,b){return"string"==typeof a?a:a[b%a.length]}function h(a){this.opts=f(a||{},h.defaults,n)}function i(){function c(b,c){return a("<"+b+' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">',c)}m.addRule(".spin-vml","behavior:url(#default#VML)"),h.prototype.lines=function(a,d){function f(){return e(c("group",{coordsize:k+" "+k,coordorigin:-j+" "+-j}),{width:k,height:k})}function h(a,h,i){b(m,b(e(f(),{rotation:360/d.lines*a+"deg",left:~~h}),b(e(c("roundrect",{arcsize:d.corners}),{width:j,height:d.width,left:d.radius,top:-d.width>>1,filter:i}),c("fill",{color:g(d.color,a),opacity:d.opacity}),c("stroke",{opacity:0}))))}var i,j=d.length+d.width,k=2*j,l=2*-(d.width+d.length)+"px",m=e(f(),{position:"absolute",top:l,left:l});if(d.shadow)for(i=1;i<=d.lines;i++)h(i,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(i=1;i<=d.lines;i++)h(i);return b(a,m)},h.prototype.opacity=function(a,b,c,d){var e=a.firstChild;d=d.shadow&&d.lines||0,e&&b+d<e.childNodes.length&&(e=e.childNodes[b+d],e=e&&e.firstChild,e=e&&e.firstChild,e&&(e.opacity=c))}}var j,k=["webkit","Moz","ms","O"],l={},m=function(){var c=a("style",{type:"text/css"});return b(document.getElementsByTagName("head")[0],c),c.sheet||c.styleSheet}(),n={lines:12,length:7,width:5,radius:10,rotate:0,corners:1,color:"#000",direction:1,speed:1,trail:100,opacity:.25,fps:20,zIndex:2e9,className:"spinner",top:"50%",left:"50%",position:"absolute"};h.defaults={},f(h.prototype,{spin:function(b){this.stop();{var c=this,d=c.opts,f=c.el=e(a(0,{className:d.className}),{position:d.position,width:0,zIndex:d.zIndex});d.radius+d.length+d.width}if(e(f,{left:d.left,top:d.top}),b&&b.insertBefore(f,b.firstChild||null),f.setAttribute("role","progressbar"),c.lines(f,c.opts),!j){var g,h=0,i=(d.lines-1)*(1-d.direction)/2,k=d.fps,l=k/d.speed,m=(1-d.opacity)/(l*d.trail/100),n=l/d.lines;!function o(){h++;for(var a=0;a<d.lines;a++)g=Math.max(1-(h+(d.lines-a)*n)%l*m,d.opacity),c.opacity(f,a*d.direction+i,g,d);c.timeout=c.el&&setTimeout(o,~~(1e3/k))}()}return c},stop:function(){var a=this.el;return a&&(clearTimeout(this.timeout),a.parentNode&&a.parentNode.removeChild(a),this.el=void 0),this},lines:function(d,f){function h(b,c){return e(a(),{position:"absolute",width:f.length+f.width+"px",height:f.width+"px",background:b,boxShadow:c,transformOrigin:"left",transform:"rotate("+~~(360/f.lines*k+f.rotate)+"deg) translate("+f.radius+"px,0)",borderRadius:(f.corners*f.width>>1)+"px"})}for(var i,k=0,l=(f.lines-1)*(1-f.direction)/2;k<f.lines;k++)i=e(a(),{position:"absolute",top:1+~(f.width/2)+"px",transform:f.hwaccel?"translate3d(0,0,0)":"",opacity:f.opacity,animation:j&&c(f.opacity,f.trail,l+k*f.direction,f.lines)+" "+1/f.speed+"s linear infinite"}),f.shadow&&b(i,e(h("#000","0 0 4px #000"),{top:"2px"})),b(d,b(i,h(g(f.color,k),"0 0 1px rgba(0,0,0,.1)")));return d},opacity:function(a,b,c){b<a.childNodes.length&&(a.childNodes[b].style.opacity=c)}});var o=e(a("group"),{behavior:"url(#default#VML)"});return!d(o,"transform")&&o.adj?i():j=d(o,"animation"),h});
|
package.xml
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>SweOptipricer</name>
|
4 |
+
<version>0.1.0</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="http://opensource.org/licenses/LGPL-3.0">GNU Lesser General Public License (LGPL)</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>Calculate best price for each customer</summary>
|
10 |
+
<description>The extension provides a widget that uses the Optipricer API to create promotions for your products.
|
11 |
+
Customers will receive a discount after a successful product share on Facebook.
|
12 |
+
For more information www.optipricer.com</description>
|
13 |
+
<notes>Testing candidate</notes>
|
14 |
+
<authors><author><name>Rui Mendes</name><user>ruidamendes</user><email>rui.mendes@beubi.com</email></author><author><name>beubi</name><user>beubi</user><email>swe@beubi.com</email></author></authors>
|
15 |
+
<date>2015-02-13</date>
|
16 |
+
<time>18:58:31</time>
|
17 |
+
<contents><target name="magelocal"><dir name="SWE"><dir name="Optipricer"><dir name="Block"><file name="Button.php" hash="8ed206abaf5cb543c1ecdee14edffeb8"/><file name="Discount.php" hash="94eeb6ed1d031ce824b7979ac684e882"/></dir><dir name="Helper"><file name="Data.php" hash="d0fe8d14d8322200cd61852652572f2c"/></dir><dir name="Model"><file name="Config.php" hash="b3b4dbb1fcae77bf0b06cbb51b688269"/><file name="Observer.php" hash="0d822491b36a5a11770232bc688ba1b8"/></dir><dir name="controllers"><dir name="Adminhtml"><file name="SweoptipricerController.php" hash="a8298c06a29de784667fab43874d7bfa"/></dir></dir><dir name="etc"><file name="config.xml" hash="ac94752d4f796ccd3b9646503d15b25c"/><file name="system.xml" hash="e3c6666a5bea0b84720648ff0f8a0930"/><file name="widget.xml" hash="fbc9c4137471aaffb1d6a39d6bbaca56"/><file name=".gitignore" hash="8bbba098c1565b7ecf097c21a8df20c7"/></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="swe"><dir name="optipricer"><file name="widget.phtml" hash="d0b4396cdfc3ac7ec21cd88626935315"/></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="SWE_Optipricer.xml" hash="225863b467db416b4db8b754cf73efa1"/></dir></target><target name="magelocale"><dir name="en_US"><file name="SWE_Optipricer.csv" hash="2c27e6a50f20ae1318274d6fa8b17bfd"/></dir><dir name="pt_PT"><file name="SWE_Optipricer.csv" hash="7ac9dd9cf8e434d982a003789a0cd826"/></dir></target><target name="mage"><dir name="js"><dir name="swe"><file name="optialert.min.js" hash="d819c38f0c3c8ef8a084154da96667eb"/><file name="optipricer.min.js" hash="5fad2fc014c5d54956a4ade5c05c7681"/><file name="optispin.min.js" hash="f2b0a61b3a739d03e88401e2a1163588"/></dir></dir></target><target name="mageskin"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="swe"><dir name="optipricer"><dir name="system"><dir name="config"><file name="button.phtml" hash=""/></dir></dir></dir></dir></dir></dir></dir></dir></target></contents>
|
18 |
+
<compatible/>
|
19 |
+
<dependencies><required><php><min>5.3.10</min><max>6.0.0</max></php></required></dependencies>
|
20 |
+
</package>
|