public function index() { /* Load the language file */ $this->language->load('module/retargeting'); /* Load the required modules */ $this->load->model('checkout/order'); $this->load->model('tool/image'); $this->load->model('setting/setting'); $this->load->model('design/layout'); $this->load->model('catalog/category'); $this->load->model('catalog/manufacturer'); $this->load->model('catalog/product'); /* * Get the base URL for our shop */ if (isset($this->request->server['HTTPS']) && ($this->request->server['HTTPS'] == 'on' || $this->request->server['HTTPS'] == '1')) { $this->data['shop_url'] = $this->config->get('config_ssl'); } else { $this->data['shop_url'] = $this->config->get('config_url'); } /* Get the saved value from the admin area */ $this->data['api_key_field'] = $this->config->get('api_key_field'); $this->data['api_secret_field'] = $this->config->get('api_secret_field'); $this->data['retargeting_setEmail'] = htmlspecialchars_decode($this->config->get('retargeting_setEmail')); $this->data['retargeting_addToCart'] = htmlspecialchars_decode($this->config->get('retargeting_addToCart')); $this->data['retargeting_clickImage'] = htmlspecialchars_decode($this->config->get('retargeting_clickImage')); $this->data['retargeting_commentOnProduct'] = htmlspecialchars_decode($this->config->get('retargeting_commentOnProduct')); $this->data['retargeting_mouseOverPrice'] = htmlspecialchars_decode($this->config->get('retargeting_mouseOverPrice')); $this->data['retargeting_setVariation'] = htmlspecialchars_decode($this->config->get('retargeting_setVariation')); /** * -------------------------------------- * Products feed * -------------------------------------- **/ /* XML Request intercepted, kill everything else and output */ if (isset($_GET['xml']) && $_GET['xml'] === 'retargeting') { /* Modify the header */ header('Content-Type: application/xml'); /* Pull ALL products from the database */ $products = $this->model_catalog_product->getProducts(); $output = '<products>'; foreach ($products as $product) { $product['quantity'] = isset($product['quantity']) && !empty($product['quantity']) ? 1 : 0; $product_url = htmlspecialchars($this->url->link('product/product', 'product_id=' . $product['product_id']), ENT_XML1); $product_image_url = $this->data['shop_url'] . 'image/' . $product['image']; $product_image_url = htmlspecialchars($product_image_url, ENT_XML1); $product_current_currency_price = $this->currency->format($this->tax->calculate($product['price'], $product['tax_class_id'], $this->config->get('config_tax')), '', '', false); $product_current_currency_special = isset($product['special']) ? $this->currency->format($this->tax->calculate($product['special'], $product['tax_class_id'], $this->config->get('config_tax')), '', '', false) : 0; $output .= "\n <product>\n <id>{$product['product_id']}</id>\n <price>{$product_current_currency_price}</price>\n <promo>{$product_current_currency_special}</promo>\n <inventory>\n <variations>0</variations>\n <stock>{$product['quantity']}</stock>\n </inventory>\n </product>\n "; } $output .= '</products>'; echo $output; die; } /* --- END PRODUCTS FEED --- */ /** * --------------------------------------------------------------------------------------------------------------------- * * API poach && Discount codes generator * * --------------------------------------------------------------------------------------------------------------------- * * * ******** * REQUEST: * ******** * POST : key=your_retargeting_key * GET : type=0&value=30&count=3 * * type => (Integer) 0: Fixed; 1: Percentage; 2: Free Delivery; * * value => (Float) actual value of discount * * count => (Integer) number of discounts codes to be generated * * * ********* * RESPONDS: * ********* * json with the discount codes * * ['code1', 'code2', ... 'codeN'] * * * STEP 1: check $_GET * STEP 2: add the discount codes to the local database * STEP 3: expose the codes to Retargeting * STEP 4: kill the script */ if (isset($_GET['key']) && $_GET['key'] === $this->data['api_key_field']) { /* ------------------------------------------------------------- * STEP 1: check $_GET and validate the API Key * ------------------------------------------------------------- */ /* Check and adjust the incoming values */ $discount_type = isset($_GET['type']) ? filter_var($_GET['type'], FILTER_SANITIZE_NUMBER_INT) : 'Received other than int'; $discount_value = isset($_GET['value']) ? filter_var($_GET['value'], FILTER_SANITIZE_NUMBER_FLOAT) : 'Received other than float'; $discount_codes = isset($_GET['count']) ? filter_var($_GET['count'], FILTER_SANITIZE_NUMBER_INT) : 'Received other than int'; /* ------------------------------------------------------------- * STEP 2: Generate and add to local database the discount codes * ------------------------------------------------------------- */ $generate_code = function () { return substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), 0, 1) . substr(str_shuffle('AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'), 0, 9); }; $datetime = new DateTime(); $start_date = $datetime->format('Y-m-d'); $datetime->modify('+6 months'); $expiration_date = $datetime->format('Y-m-d'); for ($i = $discount_codes; $i > 0; $i--) { $code = $generate_code(); $discount_codes_collection[] = $code; /* Discount type: Fixed value */ if ($discount_type == 0) { $this->db->query("\n INSERT INTO `" . DB_PREFIX . "coupon` \n SET name = 'Discount Code: RTG_FX', \n code = '{$code}', \n discount = '{$discount_value}', \n type = 'F', \n total = '0', \n logged = '0', \n shipping = '0', \n date_start = '{$start_date}', \n date_end = '{$expiration_date}', \n uses_total = '1', \n uses_customer = '1', \n status = '1', \n date_added = NOW()\n "); /* Discount type: Percentage */ } elseif ($discount_type == 1) { $this->db->query("\n INSERT INTO `" . DB_PREFIX . "coupon` \n SET name = 'Discount Code: RTG_PRCNT', \n code = '{$code}', \n discount = '{$discount_value}', \n type = 'P', \n total = '0', \n logged = '0', \n shipping = '0', \n date_start = '{$start_date}', \n date_end = '{$expiration_date}', \n uses_total = '1', \n uses_customer = '1', \n status = '1', \n date_added = NOW()\n "); /* Discount type: Free delivery */ } elseif ($discount_type == 2) { $this->db->query("\n INSERT INTO `" . DB_PREFIX . "coupon` \n SET name = 'Discount Code: RTG_SHIP', \n code = '{$code}', \n discount = '0', \n type = 'F', \n total = '0', \n logged = '0', \n shipping = '1', \n date_start = '{$start_date}', \n date_end = '{$expiration_date}', \n uses_total = '1', \n uses_customer = '1', \n status = '1', \n date_added = NOW()\n "); } } // End generating discount codes /* ------------------------------------------------------------- * STEP 3: Return the newly generated codes * ------------------------------------------------------------- */ if (isset($discount_codes_collection) && !empty($discount_codes_collection)) { /* Modify the header */ header('Content-Type: application/json'); /* Output the json */ echo json_encode($discount_codes_collection); } /* ------------------------------------------------------------- * STEP 4: Kill the script * ------------------------------------------------------------- */ die; } // End $_GET processing /* --- END API URL & DISCOUNT CODES GENERATOR --- */ /* Set the template path for our module */ if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/module/retargeting.tpl')) { $this->template = $this->config->get('config_template') . '/template/module/retargeting.tpl'; } else { $this->template = 'default/template/module/retargeting.tpl'; } /** * -------------------------------------- * Start gathering required data for View * -------------------------------------- **/ /* * Store the contents of the shopping cart * * returns Array ( [43::] => 1 [40::] => 3 ) * [ProductID::SerializedOptions] => Quantity */ $this->data['cart_products'] = isset($this->session->data['cart']) ? $this->session->data['cart'] : false; // We could use this too: $this->model_catalog_product->getProduct($product_id); /* * Get the current products from WishList * * return a numerical array containing the ID(s) * Array ( [0] => 40 [1] => 42 ) */ $this->data['wishlist'] = !empty($this->session->data['wishlist']) ? $this->session->data['wishlist'] : false; /* * Get the current Page * * returns 'layout/page' or '' * eg 'common/home', 'product/product', 'product/category' */ $this->data['current_page'] = isset($this->request->get['route']) ? $this->request->get['route'] : false; /* * Get the current Category * * returns a numerical array containing the ID(s) * Array ( [0] => 20 ) for single category * Array ( [0] => 20 [1] => 27 ) for nested categories */ $this->data['current_category'] = isset($this->request->get['path']) ? explode('_', $this->request->get['path']) : ''; /* * Count the categories * * returns int, 1 for single category, > 1 for nested */ $this->data['count_categories'] = count($this->data['current_category']) > 1 ? count($this->data['current_category']) : 0; /* * Check if the user is logged in */ if ($this->customer->isLogged()) { /* User is logged in */ $this->data['user_logged_in'] = true; $this->data['customer_id'] = $this->customer->getId(); $this->data['first_name'] = $this->customer->getFirstName(); $this->data['last_name'] = $this->customer->getLastName(); $this->data['email'] = $this->customer->getEmail(); } else { /* User is a visitor */ $this->data['user_logged_in'] = false; } /** * ------------------------------ * Start Retargeting JS functions * ------------------------------ **/ // Gather all the js code and output a single variable $this->data['js_output'] = "/* --- START Retargeting --- */\n\n"; /* DONE * 1. setEmail * */ /* User is logged in, pull data from DB */ if (isset($this->session->data['customer_id']) && !empty($this->session->data['customer_id'])) { $full_name = $this->customer->getFirstName() . ' ' . $this->customer->getLastName(); $email_address = $this->customer->getEmail(); $phone_number = $this->customer->getTelephone(); $this->data['js_output'] .= "\n var _ra = _ra || {};\n _ra.setEmailInfo = {\n 'email': '{$email_address}',\n 'name': '{$full_name}',\n 'phone': '{$phone_number}'\n };\n \n if (_ra.ready !== undefined) {\n _ra.setEmail(_ra.setEmailInfo)\n }\n "; } else { /* Listen on entire site for input data & validate it */ $this->data['js_output'] .= "\n /* -- setEmail -- */\n function checkEmail(email) {\n var regex = /^([a-zA-Z0-9_.+-])+\\@(([a-zA-Z0-9-])+\\.)+([a-zA-Z0-9]{2,9})+\$/;\n return regex.test(email);\n };\n\n jQuery(document).ready(function(\$){\n \$(\"{$this->data['retargeting_setEmail']}\").blur(function(){\n if ( checkEmail(\$(this).val()) ) {\n _ra.setEmail({ 'email': \$(this).val()});\n console.log('setEmail fired!');\n }\n });\n });\n "; } /* DONE * 2. sendCategory * * if in category, send category + nested * categ id + categ name + parent categ + breadcrumb */ if ($this->data['current_page'] === 'product/category') { $category_id_parent = $this->data['current_category'][0]; $category_info_parent = $this->model_catalog_category->getCategory($category_id_parent); $this->data['sendCategory'] = ' /* -- sendCategory -- */ '; $this->data['sendCategory'] = 'var _ra = _ra || {}; '; $this->data['sendCategory'] .= '_ra.sendCategoryInfo = {'; /* We have a nested category */ if (count($this->data['current_category']) > 1) { for ($i = count($this->data['current_category']) - 1; $i > 0; $i--) { $category_id = $this->data['current_category'][$i]; $category_info = $this->model_catalog_category->getCategory($category_id); $this->data['sendCategory'] .= "\n 'id': {$category_id},\n 'name': '{$category_info['name']}',\n 'parent': {$category_id_parent},\n 'breadcrumb': [\n "; break; } array_pop($this->data['current_category']); for ($i = count($this->data['current_category']) - 1; $i >= 0; $i--) { $category_id = $this->data['current_category'][$i]; $category_info = $this->model_catalog_category->getCategory($category_id); if ($i === 0) { $this->data['sendCategory'] .= "{\n 'id': {$category_id_parent},\n 'name': '{$category_info_parent['name']}',\n 'parent': false\n }\n "; break; } $this->data['sendCategory'] .= "{\n 'id': {$category_id},\n 'name': '{$category_info['name']}',\n 'parent': {$category_id_parent}\n },\n "; } $this->data['sendCategory'] .= "]"; /* We have a single category */ } else { $this->data['category_id'] = $this->data['current_category'][0]; $this->data['category_info'] = $this->model_catalog_category->getCategory($this->data['category_id']); $this->data['sendCategory'] .= "\n 'id': {$this->data['category_id']},\n 'name': '{$this->data['category_info']['name']}',\n 'parent': false,\n 'breadcrumb': []\n "; } //reset($this->data['current_category']); $this->data['sendCategory'] .= '};'; $this->data['sendCategory'] .= "\n if (_ra.ready !== undefined) {\n _ra.sendCategory(_ra.sendCategoryInfo);\n };\n "; /* Send to output */ $this->data['js_output'] .= $this->data['sendCategory']; } /* DONE * 3. sendBrand * * brand id + brand name */ if ($this->data['current_page'] === 'product/manufacturer/info') { /* Check if the current product is part of a brand */ if (isset($this->request->get['manufacturer_id']) && !empty($this->request->get['manufacturer_id'])) { $this->data['brand_id'] = $this->request->get['manufacturer_id']; $this->data['brand_name'] = $this->model_catalog_manufacturer->getManufacturer($this->request->get['manufacturer_id']); $this->data['sendBrand'] = "var _ra = _ra || {};\n _ra.sendBrandInfo = {\n 'id': {$this->data['brand_id']},\n 'name': '{$this->data['brand_name']['name']}'\n };\n \n if (_ra.ready !== undefined) {\n _ra.sendBrand(_ra.sendBrandInfo);\n };\n "; /* Send to output */ $this->data['js_output'] .= $this->data['sendBrand']; } } /* * 4. sendProduct * + likeFacebook * + setVariation */ if ($this->data['current_page'] === 'product/product') { $product_id = $this->request->get['product_id']; $product_url = $this->url->link('product/product', 'product_id=' . $product_id); $product_details = $this->model_catalog_product->getProduct($product_id); $product_categories = $this->db->query("SELECT * FROM `" . DB_PREFIX . "product_to_category` WHERE `product_id` = '{$product_id}'"); $product_categories = $product_categories->rows; // Get all the subcategories for this product. Reorder its numerical indexes to ease the breadcrumb logic $product_current_currency_price = $this->currency->format($this->tax->calculate($product_details['price'], $product_details['tax_class_id'], $this->config->get('config_tax')), '', '', false); $product_current_currency_special = isset($product_details['special']) ? $this->currency->format($this->tax->calculate($product_details['special'], $product_details['tax_class_id'], $this->config->get('config_tax')), '', '', false) : 0; /* Send the base info */ $this->data['sendProduct'] = "\n var _ra = _ra || {}; _ra.sendProductInfo = {\n "; $this->data['sendProduct'] .= "\n 'id': {$product_id},\n 'name': '{$product_details['name']}',\n 'url': '" . htmlspecialchars_decode($product_url) . "',\n 'img': '{$this->data['shop_url']}image/{$product_details['image']}',\n 'price': {$product_current_currency_price},\n 'promo': {$product_current_currency_special},\n 'inventory': {\n 'variations': false,\n 'stock': " . ($product_details['quantity'] > 0 ? 1 : 0) . "\n },\n "; /* Check if the product has a brand assigned */ if (isset($product_details['manufacturer_id'])) { $this->data['sendProduct'] .= "\n 'brand': {\n 'id': {$product_details['manufacturer_id']},\n 'name': '{$product_details['manufacturer']}'\n },"; } else { $this->data['sendProduct'] .= "\n 'brand': false,"; } /* Check if the product has a category assigned */ $raDefaultCategory = "'category': [{'id': 9999999999, 'name': 'Root', 'parent': false, 'breadcrumb': []}],"; if (isset($product_categories) && !empty($product_categories)) { $all_categories = $this->model_catalog_category->getCategories(); $categoryIds = array(); foreach ($all_categories as $cat) { $categoryIds[]['category_id'] = $cat['category_id']; } function in_array_r($needle, $haystack, $strict = false) { foreach ($haystack as $item) { if (($strict ? $item === $needle : $item == $needle) || is_array($item) && in_array_r($needle, $item, $strict)) { return true; } } return false; } foreach ($product_categories as $category) { if (in_array_r($category['category_id'], $categoryIds)) { $product_cat_details = $this->model_catalog_category->getCategory($category['category_id']); break; } } // Resides in a parent category if (isset($product_cat_details['parent_id']) && $product_cat_details['parent_id'] == 0) { $this->data['sendProduct'] .= "\n 'category': [{\n 'id': {$product_cat_details['category_id']},\n 'name': '{$product_cat_details['name']}',\n 'parent': false,\n 'breadcrumb': []\n }],"; // Resides in a nested category (child -> go up until parent) } else { $this->data['sendProduct'] .= $raDefaultCategory; } } else { $this->data['sendProduct'] .= $raDefaultCategory; } $this->data['sendProduct'] .= "};"; // Close _ra.sendProductInfo $this->data['sendProduct'] .= "\n if (_ra.ready !== undefined) {\n _ra.sendProduct(_ra.sendProductInfo);\n };\n "; $this->data['js_output'] .= $this->data['sendProduct']; /* --- END sendProduct --- */ /* * likeFacebook */ $this->data['likeFacebook'] = "\n if (typeof FB != 'undefined') {\n FB.Event.subscribe('edge.create', function () {\n _ra.likeFacebook({$product_id});\n });\n };\n "; $this->data['js_output'] .= $this->data['likeFacebook']; /* --- END likeFacebook --- */ /* * setVariation */ $this->data['setVariation'] = "\n var _ra = _ra || {};\n jQuery(document).ready(function(\$){\n \$(\"{$this->data['retargeting_setVariation']}\").click(function(){\n if ( \$(this).val() != undefined ) {\n _ra.setVariation({$product_id}, {\n 'code': '\$(this).val()',\n 'stock': " . ($product_details['quantity'] > 0 ? 1 : 0) . ",\n 'details': {}\n }, function() {\n console.log('setVariation fired.');\n });\n }\n });\n });\n "; $this->data['js_output'] .= $this->data['setVariation']; /* --- END setVariation --- */ } /* --- END --- */ /* DONE -> implemented along with 11. mouseOverAddToCart * 5. addToCart * * product id, variation */ $this->data['addToCart'] = ''; /* CANNOT BE DONE * 6. setVariation * * product id, variation */ $this->data['setVariation'] = ''; /* DONE * 7. addToWishlist * * product id */ if ($this->data['wishlist']) { /* Prevent notices */ $this->session->data['retargeting_wishlist_product_id'] = isset($this->session->data['retargeting_wishlist_product_id']) && !empty($this->session->data['retargeting_wishlist_product_id']) ? $this->session->data['retargeting_wishlist_product_id'] : ''; /* While pushing out an item from the WishList with a lower array index, OpenCart won't reset the numerical indexes, thus generating a notice. This fixes it */ $this->data['wishlist'] = array_values($this->data['wishlist']); if ($this->session->data['retargeting_wishlist_product_id'] != $this->data['wishlist'][count($this->data['wishlist']) - 1]) { /* Get the total number of products in WishList; push the last added product into Retargeting */ for ($i = count($this->data['wishlist']) - 1; $i >= 0; $i--) { $product_id_in_wishlist = $this->data['wishlist'][$i]; break; } $this->data['addToWishlist'] = "\n var _ra = _ra || {};\n _ra.addToWishlistInfo = {\n 'product_id': {$product_id_in_wishlist}\n };\n\n if (_ra.ready !== undefined) {\n _ra.addToWishlist(_ra.addToWishlistInfo.product_id);\n };\n "; /* We need to send the addToWishList event one time only. */ $this->session->data['retargeting_wishlist_product_id'] = $product_id_in_wishlist; $this->data['js_output'] .= $this->data['addToWishlist']; } } /* DONE * 8. clickImage * * product id * div.image & img#image */ if ($this->data['current_page'] === 'product/product') { $clickImage_product_info = $this->request->get['product_id']; $this->data['clickImage'] = "\n /* -- clickImage -- */\n jQuery(document).ready(function(\$) {\n if (\$(\"{$this->data['retargeting_clickImage']}\").length > 0) {\n \$(\"{$this->data['retargeting_clickImage']}\").mouseover(function(){\n\n _ra.clickImage({$clickImage_product_info}, function() {console.log('clickImage FIRED')});\n });\n }\n });\n "; $this->data['js_output'] .= $this->data['clickImage']; } /* DONE * 9. commentOnProduct * * product id * a#button-review */ if ($this->data['current_page'] === 'product/product') { $commentOnProduct_product_info = $this->request->get['product_id']; $this->data['commentOnProduct'] = "\n /* -- commentOnProduct -- */\n jQuery(document).ready(function(\$) {\n if (\$(\"{$this->data['retargeting_commentOnProduct']}\").length > 0) {\n \$(\"{$this->data['retargeting_commentOnProduct']}\").click(function() {\n _ra.commentOnProduct({$commentOnProduct_product_info}, function() {console.log('commentOnProduct FIRED')});\n });\n }\n });\n "; $this->data['js_output'] .= $this->data['commentOnProduct']; } /* DONE * 10. mouseOverPrice * * product id, product price * div.price */ if ($this->data['current_page'] === 'product/product') { $mouseOverPrice_product_id = $this->request->get['product_id']; $mouseOverPrice_product_info = $this->model_catalog_product->getProduct($mouseOverPrice_product_id); $mouseOverPrice_product_promo = isset($mouseOverPrice_product_info['special']) ? $mouseOverPrice_product_info['special'] : '0'; $product_current_currency_price = $this->currency->format($this->tax->calculate($mouseOverPrice_product_info['price'], $mouseOverPrice_product_info['tax_class_id'], $this->config->get('config_tax')), '', '', false); $product_current_currency_special = isset($mouseOverPrice_product_info['special']) ? $this->currency->format($this->tax->calculate($mouseOverPrice_product_info['special'], $mouseOverPrice_product_info['tax_class_id'], $this->config->get('config_tax')), '', '', false) : 0; // $this->data['mouseOverPrice'] = " // /* -- mouseOverPrice -- */ // jQuery(document).ready(function($) { // if ($(\"{$this->data['retargeting_mouseOverPrice']}\").length > 0) { // $(\"{$this->data['retargeting_mouseOverPrice']}\").mouseover(function(){ // if (typeof _ra.mouseOverAddToCart !== \"undefined\") // _ra.mouseOverPrice({$mouseOverPrice_product_id}, { // 'price': {$product_current_currency_price}, // 'promo': {$product_current_currency_special} // }, function() {console.log('mouseOverPrice FIRED')} // ); // }); // } // }); // "; $this->data['mouseOverPrice'] = ""; $this->data['js_output'] .= $this->data['mouseOverPrice']; } /* DONE * 11. mouseOverAddToCart * 12. addToCart[v1] * * product id * input[type=text].button, #button-cart */ if ($this->data['current_page'] === 'product/product') { $mouseOverAddToCart_product_id = $this->request->get['product_id']; $mouseOverAddToCart_product_info = $this->model_catalog_product->getProduct($mouseOverAddToCart_product_id); // $this->data['mouseOverAddToCart'] = " // /* -- mouseOverAddToCart & addToCart -- */ // jQuery(document).ready(function($){ // if ($(\"{$this->data['retargeting_addToCart']}\").length > 0) { // /* -- mouseOverAddToCart -- */ // $(\"{$this->data['retargeting_addToCart']}\").mouseover(function(){ // if (typeof _ra.mouseOverAddToCart !== \"undefined\") // _ra.mouseOverAddToCart({$mouseOverAddToCart_product_id}, function(){console.log('mouseOverAddToCart FIRED')}); // }); // /* -- addToCart -- */ // $(\"{$this->data['retargeting_addToCart']}\").click(function(){ // _ra.addToCart({$mouseOverAddToCart_product_id}, 1, false, function(){console.log('addToCart FIRED!')}); // }); // } // }); // "; $this->data['mouseOverAddToCart'] = "\n /* -- addToCart -- */\n jQuery(document).ready(function(\$){\n if (\$(\"{$this->data['retargeting_addToCart']}\").length > 0) {\n /* -- addToCart -- */\n \$(\"{$this->data['retargeting_addToCart']}\").click(function(){\n _ra.addToCart({$mouseOverAddToCart_product_id}, 1, false, function(){console.log('addToCart FIRED!')});\n });\n }\n });\n "; $this->data['js_output'] .= $this->data['mouseOverAddToCart']; } /* * saveOrder improvement */ $this->session->data['RTG_ID'] = isset($this->session->data['RTG_ID']) ? $this->session->data['RTG_ID'] : 1; /* DONE * 13. saveOrder * * order no, order total, products ID, products qty, products price, variation code * checkout/success * input#button-confirm */ if ($this->data['current_page'] === 'checkout/success') { $last_order_id = $this->db->query("SELECT * FROM `" . DB_PREFIX . "order` ORDER BY `order_id` DESC LIMIT 1"); $this->data['order_id'] = $last_order_id->row['order_id']; $this->data['order_data'] = $this->model_checkout_order->getOrder($this->data['order_id']); $order_no = $this->data['order_data']['order_id']; $lastname = $this->data['order_data']['lastname']; $firstname = $this->data['order_data']['firstname']; $email = $this->data['order_data']['email']; $phone = $this->data['order_data']['telephone']; $state = $this->data['order_data']['shipping_country']; $city = $this->data['order_data']['shipping_city']; $address = $this->data['order_data']['shipping_address_1']; $discount_code = isset($this->session->data['retargeting_discount_code']) ? $this->session->data['retargeting_discount_code'] : 0; $total_discount_value = 0; $shipping_value = 0; $total_order_value = $this->currency->format($this->tax->calculate($this->data['order_data']['total'], $this->data['order_data']['payment_tax_id'], $this->config->get('config_tax')), '', '', false); // to add currency exchange ... // Based on order id, grab the ordered products $order_product_query = $this->db->query("SELECT * FROM `" . DB_PREFIX . "order_product` WHERE `order_id` = '{$this->data['order_id']}'"); $this->data['order_product_query'] = $order_product_query; $this->data['saveOrder'] = "\n var _ra = _ra || {};\n _ra.saveOrderInfo = {\n 'order_no': {$order_no},\n 'lastname': '{$lastname}',\n 'firstname': '{$firstname}',\n 'email': '{$email}',\n 'phone': '{$phone}',\n 'state': '{$state}',\n 'city': '{$city}',\n 'address': '{$address}',\n 'discount_code': '{$discount_code}',\n 'discount': {$total_discount_value},\n 'shipping': {$shipping_value},\n 'rebates': 0,\n 'fees': 0,\n 'total': {$total_order_value}\n };\n "; /* -------------------------------------- */ $this->data['saveOrder'] .= "_ra.saveOrderProducts = ["; for ($i = count($order_product_query->rows) - 1; $i >= 0; $i--) { $product_details = $this->model_catalog_product->getProduct($order_product_query->rows[$i]['product_id']); $product_current_currency_price = $this->currency->format($this->tax->calculate($product_details['price'], $product_details['tax_class_id'], $this->config->get('config_tax')), '', '', false); if (isset($product_details['special'])) { $product_current_currency_price = $this->currency->format($this->tax->calculate($product_details['special'], $product_details['tax_class_id'], $this->config->get('config_tax')), '', '', false); } if ($i == 0) { $this->data['saveOrder'] .= "{\n 'id': {$order_product_query->rows[$i]['product_id']},\n 'quantity': {$order_product_query->rows[$i]['quantity']},\n 'price': {$product_current_currency_price},\n 'variation_code': ''\n }"; break; } $this->data['saveOrder'] .= "{\n 'id': {$order_product_query->rows[$i]['product_id']},\n 'quantity': {$order_product_query->rows[$i]['quantity']},\n 'price': {$product_current_currency_price},\n 'variation_code': ''\n },"; } $this->data['saveOrder'] .= "];"; /* -------------------------------------- */ $this->data['saveOrder'] .= "\n if( _ra.ready !== undefined ) {\n _ra.saveOrder(_ra.saveOrderInfo, _ra.saveOrderProducts);\n }"; /* * REST API Save Order */ if ($this->data['api_key_field'] && $this->data['api_key_field'] != '' && $this->data['api_secret_field'] && $this->data['api_secret_field'] != '') { $orderInfo = array('order_no' => $order_no, 'lastname' => $lastname, 'firstname' => $firstname, 'email' => $email, 'phone' => $phone, 'state' => $state, 'city' => $city, 'address' => $address, 'discount_code' => $discount_code, 'discount' => $total_discount_value, 'shipping' => $shipping_value, 'total' => $total_order_value); $orderProducts = array(); foreach ($order_product_query->rows as $orderedProduct) { $product_details = $this->model_catalog_product->getProduct($orderedProduct['product_id']); $product_current_currency_price = $this->currency->format($this->tax->calculate($product_details['price'], $product_details['tax_class_id'], $this->config->get('config_tax')), '', '', false); if (isset($product_details['special'])) { $product_current_currency_price = $this->currency->format($this->tax->calculate($product_details['special'], $product_details['tax_class_id'], $this->config->get('config_tax')), '', '', false); } $orderProducts[] = array('id' => $orderedProduct['product_id'], 'quantity' => $orderedProduct['quantity'], 'price' => $product_current_currency_price, 'variation_code' => ''); } $orderClient = new Retargeting_REST_API_Client($this->data['api_key_field'], $this->data['api_secret_field']); $orderClient->setResponseFormat("json"); $orderClient->setDecoding(false); $response = $orderClient->order->save($orderInfo, $orderProducts); } /* * Prevent * * sending saveOrder multiple times * * viewing saveOrder data in source */ if (isset($this->session->data['RTG_ID']) && $this->session->data['RTG_ID'] > 1) { $this->session->data['RTG_ID'] = 0; $this->data['js_output'] .= $this->data['saveOrder']; } } /* DONE * 14. visitHelpPage * * true/false */ if ($this->data['current_page'] === 'information/information') { $this->data['visitHelpPage'] = "\n /* -- visitHelpPage -- */\n var _ra = _ra || {};\n _ra.visitHelpPageInfo = {'visit' : true};\n if (_ra.ready !== undefined) {\n _ra.visitHelpPage();\n };\n "; $this->data['js_output'] .= $this->data['visitHelpPage']; } /* DONE * 15. checkoutIds * 16. setCartUrl * * product id */ $checkout_modules = array('checkout/checkout', 'checkout/simplecheckout', 'checkout/ajaxquickcheckout', 'checkout/ajaxcheckout', 'checkout/quickcheckout', 'checkout/onepagecheckout', 'supercheckout/supercheckout'); if (in_array($this->data['current_page'], $checkout_modules) && $this->data['cart_products'] || $this->data['current_page'] === 'checkout/cart' && $this->data['cart_products']) { $cart_products = $this->cart->getProducts(); // Use this instead of session $this->data['checkoutIds'] = "\n /* -- checkoutIds -- */\n var _ra = _ra || {};\n _ra.checkoutIdsInfo = [\n "; $i_products = count($cart_products); foreach ($cart_products as $item => $detail) { $i_products--; $this->data['checkoutIds'] .= $i_products > 0 ? $detail['product_id'] . "," : $detail['product_id']; } $this->data['checkoutIds'] .= "\n ];\n "; $this->data['checkoutIds'] .= "\n if (_ra.ready !== undefined) {\n _ra.checkoutIds(_ra.checkoutIdsInfo);\n };\n "; $this->data['setCartUrl'] = "\n /* -- setCartUrl -- */\n var _ra = _ra || {};\n _ra.setCartUrlInfo = {\n 'url': window.location.toString()\n };\n\n if (_ra.ready !== undefined) {\n _ra.setCartUrl(_ra.setCartUrlInfo.url);\n }"; $this->data['js_output'] .= $this->data['checkoutIds']; $this->data['js_output'] .= $this->data['setCartUrl']; /* saveOrder improvement: allow data exposure */ $this->session->data['RTG_ID']++; } /* With the gathered data, output in .tpl */ $this->data['js_output'] .= "\n/* --- END Retargeting Functions --- */\n"; /* * Render the output */ $this->render(); }
public function save_order($order_id) { if (is_numeric($order_id) && $order_id > 0) { $order = new WC_Order($order_id); $coupons_list = ''; if ($order->get_used_coupons()) { $coupons_count = count($order->get_used_coupons()); $i = 1; foreach ($order->get_used_coupons() as $coupon) { $coupons_list .= $coupon; if ($i < $coupons_count) { $coupons_list .= ', '; $i++; } } } $data = array('line_items' => array()); foreach ((array) $order->get_items() as $item_id => $item) { $_product = apply_filters('woocommerce_order_item_product', $order->get_product_from_item($item), $item); $item_meta = new WC_Order_Item_Meta($item['item_meta'], $_product); if (apply_filters('woocommerce_order_item_visible', true, $item)) { $line_item = array('id' => $item['product_id'], 'name' => $item['name'], 'price' => $item['line_subtotal'], 'quantity' => $item['qty'], 'variation_code' => $item['variation_id'] == 0 ? "" : $item['variation_id']); } $data['line_items'][] = $line_item; } echo '<script> var _ra = _ra || {}; _ra.saveOrderInfo = { "order_no": ' . $order->id . ', "lastname": "' . $order->billing_last_name . '", "firstname": "' . $order->billing_first_name . '", "email": "' . $order->billing_email . '", "phone": "' . $order->billing_phone . '", "state": "' . $order->billing_state . '", "city": "' . $order->billing_city . '", "address": "' . $order->billing_address_1 . " " . $order->billing_address_2 . '", "discount_code": "' . $coupons_list . '", "discount": ' . (empty($order->get_discount) ? 0 : $order->get_discount) . ', "shipping": ' . (empty($order->get_total_shipping) ? 0 : $order->get_total_shipping) . ', "rebates": 0, "fees": 0, "total": ' . $order->order_total . ' }; _ra.saveOrderProducts = ' . json_encode($data['line_items']) . ' ; if( _ra.ready !== undefined ){ _ra.saveOrder(_ra.saveOrderInfo, _ra.saveOrderProducts); } </script>'; } //REST API $orderInfo = array("order_no" => $order->id, "lastname" => $order->billing_last_name, "firstname" => $order->billing_first_name, "email" => $order->billing_email, "phone" => $order->billing_phone, "state" => $order->billing_state, "city" => $order->billing_city, "address" => $order->billing_address_1 . " " . $order->billing_address_2, "discount_code" => $coupons_list, "discount" => empty($order->get_discount) ? 0 : $order->get_discount, "shipping" => empty($order->get_total_shipping) ? 0 : $order->get_total_shipping, "total" => $order->order_total); if ($this->domain_api_key && $this->domain_api_key != "" && $this->token && $this->token != '') { $orderClient = new Retargeting_REST_API_Client($this->domain_api_key, $this->token); $orderClient->setResponseFormat("json"); $orderClient->setDecoding(false); $response = $orderClient->order->save($orderInfo, $data['line_items']); } }
public function save_order($purchase_log) { $apiKey = get_option('retargeting_domain_api'); $token = get_option('retargeting_token'); if ($purchase_log instanceof WPSC_Purchase_Log) { $order = array('line_items' => array()); $checkout_form = new WPSC_Checkout_Form_Data($purchase_log->get('id')); $products = $purchase_log->get_cart_contents(); if (is_array($products)) { foreach ($products as $product) { $parent = $this->get_parent_post($product->prodid); if ($parent) { $product_id = $parent->ID; $product_name = $parent->post_title; } else { $product_id = $product->prodid; $product_name = $product->name; } $line_item = array('id' => (int) $product_id, 'quantity' => (int) $product->quantity, 'price' => $this->format_price($product->price), 'variation_code' => ''); $order['line_items'][] = $line_item; } } if ($apiKey && $apiKey != "" && $token && $token != "") { require_once "/lib/Retargeting_REST_API_Client.php"; $orderInfo = array("order_no" => $purchase_log->get('id'), "lastname" => $checkout_form->get('billinglastname'), "firstname" => $checkout_form->get('billingfirstname'), "email" => $checkout_form->get('billingemail'), "phone" => $checkout_form->get('billingphone'), "state" => $checkout_form->get('shippingstate'), "city" => $checkout_form->get('shippingcity'), "address" => $checkout_form->get('billingaddress'), "discount_code" => $purchase_log->get('discount_data'), "discount" => $purchase_log->get('discount_value'), "shipping" => $purchase_log->get('total_shipping'), "total" => $purchase_log->get('totalprice')); $orderClient = new Retargeting_REST_API_Client($apiKey, $token); $orderClient->setResponseFormat('json'); $orderClient->setDecoding(false); $response = $orderClient->order->save($orderInfo, $order['line_items']); } echo '<script type="text/javascript"> var _ra = _ra || {}; _ra.saveOrderInfo = { "order_no": ' . $purchase_log->get('id') . ', "lastname": "' . $checkout_form->get('billinglastname') . '", "firstname": "' . $checkout_form->get('billingfirstname') . '", "email": "' . $checkout_form->get('billingemail') . '", "phone": "' . $checkout_form->get('billingphone') . '", "state": "' . $checkout_form->get('shippingstate') . '", "city": "' . $checkout_form->get('shippingcity') . '", "address": "' . $checkout_form->get('billingaddress') . '", "discount_code": "' . $purchase_log->get('discount_data') . '", "discount": "' . $purchase_log->get('discount_value') . '", "shipping": "' . $purchase_log->get('total_shipping') . '", "total": "' . $purchase_log->get('totalprice') . '" }; _ra.saveOrderProducts = ' . json_encode($order['line_items'], JSON_PRETTY_PRINT) . ' if( _ra.ready !== undefined ){ _ra.saveOrder(_ra.saveOrderInfo, _ra.saveOrderProducts); } </script>'; } }
public function index() { /* --------------------------------------------------------------------------------------------------------------------- * Setup the protocol * --------------------------------------------------------------------------------------------------------------------- */ if (isset($this->request->server['HTTPS']) && ($this->request->server['HTTPS'] == 'on' || $this->request->server['HTTPS'] == '1')) { $data['shop_url'] = $this->config->get('config_ssl'); } else { $data['shop_url'] = $this->config->get('config_url'); } /* --------------------------------------------------------------------------------------------------------------------- * Load the module's language file * --------------------------------------------------------------------------------------------------------------------- */ $this->language->load('module/retargeting'); /* --------------------------------------------------------------------------------------------------------------------- * Load models that we might need access to * --------------------------------------------------------------------------------------------------------------------- */ $this->load->model('checkout/order'); $this->load->model('setting/setting'); $this->load->model('design/layout'); $this->load->model('catalog/category'); $this->load->model('catalog/manufacturer'); $this->load->model('catalog/product'); $this->load->model('catalog/information'); // $this->load->model('marketing/coupon'); /* Available only in the admin/ area */ // $this->load->model('checkout/coupon'); /* --------------------------------------------------------------------------------------------------------------------- * Get the saved values from the admin area * --------------------------------------------------------------------------------------------------------------------- */ $data['api_key_field'] = $this->config->get('retargeting_apikey'); $data['api_secret_field'] = $this->config->get('retargeting_token'); $data['retargeting_setEmail'] = htmlspecialchars_decode($this->config->get('retargeting_setEmail')); $data['retargeting_addToCart'] = htmlspecialchars_decode($this->config->get('retargeting_addToCart')); $data['retargeting_clickImage'] = htmlspecialchars_decode($this->config->get('retargeting_clickImage')); $data['retargeting_commentOnProduct'] = htmlspecialchars_decode($this->config->get('retargeting_commentOnProduct')); $data['retargeting_mouseOverPrice'] = htmlspecialchars_decode($this->config->get('retargeting_mouseOverPrice')); $data['retargeting_setVariation'] = htmlspecialchars_decode($this->config->get('retargeting_setVariation')); /** * -------------------------------------- * Products feed * -------------------------------------- **/ /* XML Request intercepted, kill everything else and output */ if (isset($_GET['xml']) && $_GET['xml'] === 'retargeting') { /* Modify the header */ header('Content-Type: application/xml'); /* Pull ALL products from the database */ $products = $this->model_catalog_product->getProducts(); $output = '<products>'; foreach ($products as $product) { $product['quantity'] = isset($product['quantity']) && !empty($product['quantity']) ? 1 : 0; $product_promotional_price = isset($product['special']) ? $product['special'] : 0; $product_url = htmlspecialchars($this->url->link('product/product', 'product_id=' . $product['product_id']), ENT_XML1); $product_image_url = $data['shop_url'] . 'image/' . $product['image']; $product_image_url = htmlspecialchars($product_image_url, ENT_XML1); $output .= "\n <product>\n <id>{$product['product_id']}</id>\n <stock>{$product['quantity']}</stock>\n <price>{$product['price']}</price>\n <promo>{$product_promotional_price}</promo>\n <url>{$product_url}</url>\n <image>{$product_image_url}</image>\n </product>\n "; } $output .= '</products>'; echo $output; die; } /* --- END PRODUCTS FEED --- */ /** * --------------------------------------------------------------------------------------------------------------------- * * API poach && Discount codes generator * * --------------------------------------------------------------------------------------------------------------------- * * * ******** * REQUEST: * ******** * POST : key=your_retargeting_key * GET : type=0&value=30&count=3 * * type => (Integer) 0: Fixed; 1: Percentage; 2: Free Delivery; * * value => (Float) actual value of discount * * count => (Integer) number of discounts codes to be generated * * * ********* * RESPONDS: * ********* * json with the discount codes * * ['code1', 'code2', ... 'codeN'] * * * STEP 1: check $_POST * STEP 2: add the discount codes to the local database * STEP 3: expose the codes to Retargeting * STEP 4: kill the script */ if (isset($_POST) && isset($_POST['key']) && $_POST['key'] === $data['api_key_field']) { /* ------------------------------------------------------------- * STEP 1: check $_POST and validate the API Key * ------------------------------------------------------------- */ /* include_once 'Retargeting_REST_API_Client.php'; $client = new Retargeting_REST_API_Client($data['api_key_field'], $data['api_secret_field']); $client->setResponseFormat("json"); $client->setDecoding(false); $client->setApiVersion('1.0'); $client->setApiUri('https://retargeting.ro/api'); */ /* Check and adjust the incoming values */ $discount_type = isset($_GET['type']) ? filter_var($_GET['type'], FILTER_SANITIZE_NUMBER_INT) : 'Received other than int'; $discount_value = isset($_GET['value']) ? filter_var($_GET['value'], FILTER_SANITIZE_NUMBER_FLOAT) : 'Received other than float'; $discount_codes = isset($_GET['count']) ? filter_var($_GET['count'], FILTER_SANITIZE_NUMBER_INT) : 'Received other than int'; /* ------------------------------------------------------------- * STEP 2: Generate and add to local database the discount codes * ------------------------------------------------------------- */ $generate_code = function () { return substr(str_shuffle('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'), 0, 1) . substr(str_shuffle('AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz'), 0, 9); }; $datetime = new DateTime(); $start_date = $datetime->format('Y-m-d'); $datetime->modify('+6 months'); $expiration_date = $datetime->format('Y-m-d'); for ($i = $discount_codes; $i > 0; $i--) { $code = $generate_code(); $discount_codes_collection[] = $code; /* Discount type: Fixed value */ if ($discount_type == 0) { $this->db->query("\n INSERT INTO " . DB_PREFIX . "coupon\n SET name = 'Discount Code: RTG_FX',\n code = '{$code}',\n discount = '{$discount_value}',\n type = 'F',\n total = '0',\n logged = '0',\n shipping = '0',\n date_start = '{$start_date}',\n date_end = '{$expiration_date}',\n uses_total = '1',\n uses_customer = '1',\n status = '1',\n date_added = NOW()\n "); /* Discount type: Percentage */ } elseif ($discount_type == 1) { $this->db->query("\n INSERT INTO " . DB_PREFIX . "coupon\n SET name = 'Discount Code: RTG_PRCNT',\n code = '{$code}',\n discount = '{$discount_value}',\n type = 'P',\n total = '0',\n logged = '0',\n shipping = '0',\n date_start = '{$start_date}',\n date_end = '{$expiration_date}',\n uses_total = '1',\n uses_customer = '1',\n status = '1',\n date_added = NOW()\n "); /* Discount type: Free delivery */ } elseif ($discount_type == 2) { $this->db->query("\n INSERT INTO " . DB_PREFIX . "coupon\n SET name = 'Discount Code: RTG_SHIP',\n code = '{$code}',\n discount = '0',\n type = 'F',\n total = '0',\n logged = '0',\n shipping = '1',\n date_start = '{$start_date}',\n date_end = '{$expiration_date}',\n uses_total = '1',\n uses_customer = '1',\n status = '1',\n date_added = NOW()\n "); } } // End generating discount codes /* ------------------------------------------------------------- * STEP 3: Return the newly generated codes * ------------------------------------------------------------- */ if (isset($discount_codes_collection) && !empty($discount_codes_collection)) { /* Modify the header */ header('Content-Type: application/json'); /* Output the json */ echo json_encode($discount_codes_collection); } /* ------------------------------------------------------------- * STEP 4: Kill the script * ------------------------------------------------------------- */ die; } // End $_GET processing /* --- END API URL & DISCOUNT CODES GENERATOR --- */ /* --------------------------------------------------------------------------------------------------------------------- * * Start implementing Retargeting JS functions * * --------------------------------------------------------------------------------------------------------------------*/ /* Small helpers [pre-data processing] */ $data['cart_products'] = isset($this->session->data['cart']) ? $this->session->data['cart'] : false; $data['wishlist'] = !empty($this->session->data['wishlist']) ? $this->session->data['wishlist'] : false; $data['current_page'] = isset($this->request->get['route']) ? $this->request->get['route'] : false; $data['current_category'] = isset($this->request->get['path']) ? explode('_', $this->request->get['path']) : ''; $data['count_categories'] = count($data['current_category']) > 0 ? count($data['current_category']) : 0; $data['js_output'] = "/* --- START Retargeting --- */\n\n"; /* --- END pre-data processing --- */ /* * setEmail */ /* User is logged in, pull data from DB */ if (isset($this->session->data['customer_id']) && !empty($this->session->data['customer_id'])) { $full_name = $this->customer->getFirstName() . $this->customer->getLastName(); $email_address = $this->customer->getEmail(); $phone_number = $this->customer->getTelephone(); $data['js_output'] .= "\n var _ra = _ra || {};\n _ra.setEmailInfo = {\n 'email': '{$email_address}',\n 'name': '{$full_name}',\n 'phone': '{$phone_number}'\n };\n \n if (_ra.ready !== undefined) {\n _ra.setEmail(_ra.setEmailInfo)\n }\n "; } else { /* Listen on entire site for input data & validate it */ $data['setEmail'] = "\n /* -- setEmail -- */\n function checkEmail(email) {\n var regex = /^([a-zA-Z0-9_.+-])+\\@(([a-zA-Z0-9-])+\\.)+([a-zA-Z0-9]{2,9})+\$/;\n return regex.test(email);\n };\n\n jQuery(document).ready(function(\$){\n \$(\"{$data['retargeting_setEmail']}\").blur(function(){\n if ( checkEmail(\$(this).val()) ) {\n _ra.setEmail({ 'email': \$(this).val()});\n console.log('setEmail fired!');\n }\n });\n });\n "; $data['js_output'] .= $data['setEmail']; } /* --- END setEmail --- */ /* * sendCategory ✓ */ if ($data['current_page'] === 'product/category') { $category_id_parent = $data['current_category'][0]; $category_info_parent = $this->model_catalog_category->getCategory($category_id_parent); $data['sendCategory'] = ' /* -- sendCategory -- */ '; $data['sendCategory'] = 'var _ra = _ra || {}; '; $data['sendCategory'] .= '_ra.sendCategoryInfo = {'; /* We have a nested category */ if (count($data['current_category']) > 1) { for ($i = count($data['current_category']) - 1; $i > 0; $i--) { $category_id = $data['current_category'][$i]; $category_info = $this->model_catalog_category->getCategory($category_id); $data['sendCategory'] .= "\n 'id': {$category_id},\n 'name': '{$category_info['name']}',\n 'parent': {$category_id_parent},\n 'category_breadcrumb': [\n "; break; } array_pop($data['current_category']); for ($i = count($data['current_category']) - 1; $i >= 0; $i--) { $category_id = $data['current_category'][$i]; $category_info = $this->model_catalog_category->getCategory($category_id); if ($i === 0) { $data['sendCategory'] .= "{\n 'id': {$category_id_parent},\n 'name': '{$category_info_parent['name']}',\n 'parent': false\n }\n "; break; } $data['sendCategory'] .= "{\n 'id': {$category_id},\n 'name': '{$category_info['name']}',\n 'parent': {$category_id_parent}\n },\n "; } $data['sendCategory'] .= "]"; /* We have a single category */ } else { $data['category_id'] = $data['current_category'][0]; $data['category_info'] = $this->model_catalog_category->getCategory($data['category_id']); $data['sendCategory'] .= "\n 'id': {$data['category_id']},\n 'name': '{$data['category_info']['name']}',\n 'parent': false,\n 'category_breadcrumb': []\n "; } //reset($data['current_category']); $data['sendCategory'] .= '};'; $data['sendCategory'] .= "\n if (_ra.ready !== undefined) {\n _ra.sendCategory(_ra.sendCategoryInfo);\n };\n "; /* Send to output */ $data['js_output'] .= $data['sendCategory']; } /* --- END sendCategory --- */ /* * sendBrand ✓ */ if ($data['current_page'] === 'product/manufacturer/info') { /* Check if the current product is part of a brand */ if (isset($this->request->get['manufacturer_id']) && !empty($this->request->get['manufacturer_id'])) { $data['brand_id'] = $this->request->get['manufacturer_id']; $data['brand_name'] = $this->model_catalog_manufacturer->getManufacturer($this->request->get['manufacturer_id']); $data['sendBrand'] = "var _ra = _ra || {};\n _ra.sendBrandInfo = {\n 'id': {$data['brand_id']},\n 'name': '{$data['brand_name']['name']}'\n };\n\n if (_ra.ready !== undefined) {\n _ra.sendBrand(_ra.sendBrandInfo);\n };\n "; /* Send to output */ $data['js_output'] .= $data['sendBrand']; } } /* --- END sendBrand --- */ /* * sendProduct * likeFacebook */ if ($data['current_page'] === 'product/product') { $product_id = $this->request->get['product_id']; $product_url = $this->url->link('product/product', 'product_id=' . $product_id); $product_details = $this->model_catalog_product->getProduct($product_id); $product_categories = $this->db->query("SELECT * FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int) $product_id . "'"); $product_categories = $product_categories->rows; // Get all the subcategories for this product. Reorder its numerical indexes to ease the breadcrumb logic /* Send the base info */ $data['sendProduct'] = "\n var _ra = _ra || {}; _ra.sendProductInfo = {\n "; $data['sendProduct'] .= "\n 'id': {$product_id},\n 'name': '{$product_details['name']}',\n 'url': '{$product_url}',\n 'img': '{$data['shop_url']}image/{$product_details['image']}',\n 'price': '" . round($this->tax->calculate($product_details['price'], $product_details['tax_class_id'], $this->config->get('config_tax')), 2) . "',\n 'promo': '" . (isset($product_details['special']) ? round($this->tax->calculate($product_details['special'], $product_details['tax_class_id'], $this->config->get('config_tax')), 2) : 0) . "',\n 'stock': " . ($product_details['quantity'] > 0 ? 1 : 0) . ",\n "; /* Check if the product has a brand assigned */ if (isset($product_details['manufacturer_id'])) { $data['sendProduct'] .= "\n 'brand': {'id': {$product_details['manufacturer_id']}, 'name': '{$product_details['manufacturer']}'},\n "; } else { $data['sendProduct'] .= "\n 'brand': false,\n "; } /* Check if the product has a category assigned */ if (isset($product_categories) && !empty($product_categories)) { $product_cat = $this->model_catalog_product->getCategories($product_id); $product_cat_details = $this->model_catalog_category->getCategory($product_cat[0]['category_id']); // Resides in a parent category if (isset($product_cat_details['parent_id']) && $product_cat_details['parent_id'] == 0) { $data['sendProduct'] .= "\n 'category': {'id': {$product_cat_details['category_id']}, 'name': '{$product_cat_details['name']}', 'parent': false},\n 'category_breadcrumb': []\n "; // Resides in a nested category (child -> go up until parent) } else { $product_cat_details_parent = $this->model_catalog_category->getCategory($product_cat_details['parent_id']); // Get the top level category $data['sendProduct'] .= "\n 'category': {'id': {$product_cat_details['category_id']}, 'name': '{$product_cat_details['name']}', 'parent': {$product_cat_details['parent_id']}},\n 'category_breadcrumb': [{'id': {$product_cat_details_parent['category_id']}, 'name': '{$product_cat_details_parent['name']}', 'parent': false}]\n "; } // Close elseif } // Close check if product has categories assigned $data['sendProduct'] .= "};"; // Close _ra.sendProductInfo $data['sendProduct'] .= "\n if (_ra.ready !== undefined) {\n _ra.sendProduct(_ra.sendProductInfo);\n };\n "; $data['js_output'] .= $data['sendProduct']; $data['likeFacebook'] = "\n if (typeof FB != 'undefined') {\n FB.Event.subscribe('edge.create', function () {\n _ra.likeFacebook({$product_id});\n });\n };\n "; $data['js_output'] .= $data['likeFacebook']; } /* --- END sendProduct --- */ /* * addToWishList ✓ */ if ($data['wishlist']) { /* Prevent notices */ $this->session->data['retargeting_wishlist_product_id'] = isset($this->session->data['retargeting_wishlist_product_id']) && !empty($this->session->data['retargeting_wishlist_product_id']) ? $this->session->data['retargeting_wishlist_product_id'] : ''; /* While pushing out an item from the WishList with a lower array index, OpenCart won't reset the numerical indexes, thus generating a notice. This fixes it */ $data['wishlist'] = array_values($data['wishlist']); if ($this->session->data['retargeting_wishlist_product_id'] != $data['wishlist'][count($data['wishlist']) - 1]) { /* Get the total number of products in WishList; push the last added product into Retargeting */ for ($i = count($data['wishlist']) - 1; $i >= 0; $i--) { $product_id_in_wishlist = $data['wishlist'][$i]; break; } $data['addToWishlist'] = "\n var _ra = _ra || {};\n _ra.addToWishlistInfo = {\n 'product_id': {$product_id_in_wishlist}\n };\n\n if (_ra.ready !== undefined) {\n _ra.addToWishlist(_ra.addToWishlistInfo.product_id);\n };\n "; /* We need to send the addToWishList event one time only. */ $this->session->data['retargeting_wishlist_product_id'] = $product_id_in_wishlist; $data['js_output'] .= $data['addToWishlist']; } } /* --- END addToWishList --- */ /* * commentOnProduct ✓ */ if ($data['current_page'] === 'product/product') { $commentOnProduct_product_info = $this->request->get['product_id']; $data['commentOnProduct'] = "\n /* -- commentOnProduct -- */\n jQuery(document).ready(function(\$){\n if (\$(\"{$data['retargeting_commentOnProduct']}\").length > 0) {\n \$(\"{$data['retargeting_commentOnProduct']}\").click(function(){\n _ra.commentOnProduct({$commentOnProduct_product_info}, function() {console.log('commentOnProduct FIRED')});\n });\n }\n });\n "; $data['js_output'] .= $data['commentOnProduct']; } /* --- END commentOnProduct --- */ /* * mouseOverPrice ✓ * clickImage ✓ * likeFacebook ✓ * setVariation ✓ */ if ($data['current_page'] === 'product/product') { $mouseOverPrice_product_id = $this->request->get['product_id']; $mouseOverPrice_product_info = $this->model_catalog_product->getProduct($mouseOverPrice_product_id); $mouseOverPrice_product_promo = isset($mouseOverPrice_product_info['special']) ? $mouseOverPrice_product_info['special'] : '0'; $data['mouseOverPrice'] = "\n /* -- mouseOverPrice -- */\n jQuery(document).ready(function(\$) {\n if (\$(\"{$data['retargeting_mouseOverPrice']}\").length > 0) {\n \$(\"{$data['retargeting_mouseOverPrice']}\").mouseover(function(){\n _ra.mouseOverPrice({$mouseOverPrice_product_id}, {\n 'price': {$mouseOverPrice_product_info['price']},\n 'promo': {$mouseOverPrice_product_promo}\n }, function() {console.log('mouseOverPrice FIRED')}\n );\n });\n }\n });\n\n /* -- clickImage -- */\n jQuery(document).ready(function(\$) {\n if (\$(\"{$data['retargeting_clickImage']}\").length > 0) {\n \$(\"{$data['retargeting_clickImage']}\").mouseover(function(){\n\n _ra.clickImage({$mouseOverPrice_product_id}, function() {console.log('clickImage FIRED')});\n });\n }\n });\n\n /* -- likeFacebook -- */\n jQuery(document).ready(function(\$) {\n if (typeof FB != 'undefined') {\n FB.Event.subscribe('edge.create', function () {\n _ra.likeFacebook({$this->request->get['product_id']});\n });\n }\n });\n\n /* -- setVariation -- */\n jQuery(document).ready(function(\$){\n \$(\"{$this->data['retargeting_setVariation']}\").click(function(){\n if ( \$(this).val() != undefined ) {\n _ra.setVariation({$this->request->get['product_id']}, {\n 'code': '\$(this).val()',\n 'details': {}\n }, function() {\n console.log('setVariation fired.');\n });\n }\n });\n });\n "; $data['js_output'] .= $data['mouseOverPrice']; } /* --- END mouseOverPrice, clickImage, likeFacebook, setVariation --- */ /* * mouseOverAddToCart ✓ * addToCart [v1 - class/id listener] ✓ */ if ($data['current_page'] === 'product/product') { $mouseOverAddToCart_product_id = $this->request->get['product_id']; $mouseOverAddToCart_product_info = $this->model_catalog_product->getProduct($mouseOverAddToCart_product_id); $mouseOverAddToCart_product_promo = isset($mouseOverAddToCart_product_info['promo']) ?: 0; $data['mouseOverAddToCart'] = "\n /* -- mouseOverAddToCart & addToCart -- */\n jQuery(document).ready(function(\$){\n if (\$(\"{$data['retargeting_addToCart']}\").length > 0) {\n /* -- mouseOverAddToCart -- */\n \$(\"{$data['retargeting_addToCart']}\").mouseover(function(){\n _ra.mouseOverAddToCart({$mouseOverAddToCart_product_id}, function(){console.log('mouseOverAddToCart FIRED')});\n });\n\n /* -- addToCart -- */\n \$(\"{$data['retargeting_addToCart']}\").click(function(){\n _ra.addToCart({$mouseOverAddToCart_product_id}, false, function(){console.log('addToCart FIRED!')});\n });\n }\n });\n "; $data['js_output'] .= $data['mouseOverAddToCart']; } /* --- END mouseOverAddToCart & addToCart[v1] --- */ /* * visitHelpPage ✓ */ if ($data['current_page'] === 'information/information') { $data['visitHelpPage'] = "\n /* -- visitHelpPage -- */\n var _ra = _ra || {};\n _ra.visitHelpPageInfo = {'visit' : true};\n if (_ra.ready !== undefined) {\n _ra.visitHelpPage();\n };\n "; $data['js_output'] .= $data['visitHelpPage']; } /* --- END visitHelpPage --- */ /* * checkoutIds ✓ */ $checkout_modules = array('checkout/checkout', 'checkout/simplecheckout', 'checkout/ajaxquickcheckout', 'checkout/ajaxcheckout', 'checkout/quickcheckout', 'checkout/onepagecheckout'); if (in_array($data['current_page'], $checkout_modules) && $data['cart_products'] || $data['current_page'] === 'checkout/cart' && $data['cart_products']) { $cart_products = $this->cart->getProducts(); // Use this instead of session $data['checkoutIds'] = "\n /* -- checkoutIds -- */\n var _ra = _ra || {};\n _ra.checkoutIdsInfo = [\n "; $i_products = count($cart_products); foreach ($cart_products as $item => $detail) { $i_products--; $data['checkoutIds'] .= $i_products > 0 ? $detail['product_id'] . "," : $detail['product_id']; } $data['checkoutIds'] .= "\n ];\n "; $data['checkoutIds'] .= "\n if (_ra.ready !== undefined) {\n _ra.checkoutIds(_ra.checkoutIdsInfo);\n };\n "; $data['js_output'] .= $data['checkoutIds']; } /* --- END checkoutIds --- */ /* * saveOrder ✓ * * via pre.order.add event */ if (isset($this->session->data['retargeting_pre_order_add']) && !empty($this->session->data['retargeting_pre_order_add']) || isset($this->session->data['retargeting_post_order_add']) && !empty($this->session->data['retargeting_post_order_add'])) { $data['order_id'] = $this->session->data['retargeting_post_order_add']; $data['order_data'] = $this->model_checkout_order->getOrder($data['order_id']); $order_no = $data['order_data']['order_id']; $lastname = $data['order_data']['lastname']; $firstname = $data['order_data']['firstname']; $email = $data['order_data']['email']; $phone = $data['order_data']['telephone']; $state = $data['order_data']['shipping_country']; $city = $data['order_data']['shipping_city']; $address = $data['order_data']['shipping_address_1']; $discount_code = isset($this->session->data['retargeting_discount_code']) ? $this->session->data['retargeting_discount_code'] : 0; $total_discount_value = 0; $shipping_value = 0; $total_order_value = $data['order_data']['total']; // Based on order id, grab the ordered products $order_product_query = $this->db->query("SELECT * FROM " . DB_PREFIX . "order_product WHERE order_id = '" . (int) $data['order_id'] . "'"); $data['order_product_query'] = $order_product_query; $data['saveOrder'] = "\n var _ra = _ra || {};\n _ra.saveOrderInfo = {\n 'order_no': {$order_no},\n 'lastname': '{$lastname}',\n 'firstname': '{$firstname}',\n 'email': '{$email}',\n 'phone': '{$phone}',\n 'state': '{$state}',\n 'city': '{$city}',\n 'address': '{$address}',\n 'discount_code': '{$discount_code}',\n 'discount': {$total_discount_value},\n 'shipping': {$shipping_value},\n 'total': {$total_order_value}\n };\n "; /* -------------------------------------- */ $data['saveOrder'] .= "_ra.saveOrderProducts = ["; for ($i = count($order_product_query->rows) - 1; $i >= 0; $i--) { if ($i == 0) { $data['saveOrder'] .= "{\n 'id': {$order_product_query->rows[$i]['product_id']},\n 'quantity': {$order_product_query->rows[$i]['quantity']},\n 'price': {$order_product_query->rows[$i]['price']},\n 'variation_code': ''\n }"; break; } $data['saveOrder'] .= "{\n 'id': {$order_product_query->rows[$i]['product_id']},\n 'quantity': {$order_product_query->rows[$i]['quantity']},\n 'price': {$order_product_query->rows[$i]['price']},\n 'variation_code': ''\n },"; } $data['saveOrder'] .= "];"; /* -------------------------------------- */ $data['saveOrder'] .= "\n if( _ra.ready !== undefined ) {\n _ra.saveOrder(_ra.saveOrderInfo, _ra.saveOrderProducts);\n }"; $data['js_output'] .= $data['saveOrder']; /* * REST API Save Order */ $apiKey = $this->config->get('retargeting_apikey'); $token = $this->config->get('retargeting_token'); if ($apiKey && $token && $apiKey != '' && $token != '') { $orderInfo = array('order_no' => $order_no, 'lastname' => $lastname, 'firstname' => $firstname, 'email' => $email, 'phone' => $phone, 'state' => $state, 'city' => $city, 'address' => $address, 'discount_code' => $discount_code, 'discount' => $total_discount_value, 'shipping' => $shipping_value, 'total' => $total_order_value); $orderProducts = array(); foreach ($order_product_query->rows as $orderedProduct) { $orderProducts[] = array('id' => $orderedProduct['product_id'], 'quantity' => $orderedProduct['quantity'], 'price' => $orderedProduct['price'], 'variation_code' => ''); } $orderClient = new Retargeting_REST_API_Client($apiKey, $token); $orderClient->setResponseFormat("json"); $orderClient->setDecoding(false); $response = $orderClient->order->save($orderInfo, $orderProducts); } unset($this->session->data['retargeting_pre_order_add']); unset($this->session->data['retargeting_post_order_add']); } /* --------------------------------------------------------------------------------------------------------------------- * Set the template path for our module & load the View * --------------------------------------------------------------------------------------------------------------------- */ if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/module/retargeting.tpl')) { return $this->load->view($this->config->get('config_template') . '/template/module/retargeting.tpl', $data); } else { return $this->load->view('/module/retargeting.tpl', $data); } }
require __DIR__ . '/../../lib/retargeting-rest-api/Client.php'; function verify_webhook($data, $hmac_header) { $calculated_hmac = base64_encode(hash_hmac('sha256', $data, SHOPIFY_APP_SHARED_SECRET, true)); return $hmac_header == $calculated_hmac; } $hmac_header = $_SERVER['HTTP_X_SHOPIFY_HMAC_SHA256']; $data = file_get_contents('php://input'); $verified = verify_webhook($data, $hmac_header); if ($verified && !empty($_SERVER['HTTP_X_SHOPIFY_SHOP_DOMAIN']) && ($shop = verifyShopStatus($conn, $_SERVER['HTTP_X_SHOPIFY_SHOP_DOMAIN']))) { $shopify = shopify\client($shop['shop'], SHOPIFY_APP_API_KEY, $shop['token']); if (empty($shop['domain_api_key']) || empty($shop['api_token'])) { return false; } // get Order through Shopify API - unsolved issue // $order = $shopify('GET /admin/orders.json?ids='.$data['id']); $client = new Retargeting_REST_API_Client($shop['domain_api_key'], $shop['api_token']); $client->setResponseFormat("json"); $client->setDecoding(false); $orderObj = json_decode($data); $discountCodes = array(); foreach ($orderObj->discount_codes as $dc) { $discountCodes[] = $dc->code; } $discountCodes = implode(', ', $discountCodes); $lineItems = array(); foreach ($orderObj->line_items as $li) { $lineItems[] = array('id' => $li->id, 'quantity' => $li->quantity, 'price' => $li->price, 'variation_code' => $li->variant_id); } $response = $client->order->save(array('order_no' => 'sohpify-' . $orderObj->order_number, 'lastname' => '', 'firstname' => '', 'email' => $orderObj->email, 'phone' => '', 'state' => '', 'city' => '', 'address' => '', 'discount' => $orderObj->total_discounts, 'discount_code' => $discountCodes, 'shipping' => 0, 'total' => $orderObj->total_price), $lineItems); }