Commit 36e34b21 by liumengfei

Merge branch 'developer' into production

parents 515794e8 1f97a2ec
<?php
namespace Cadence\Fbpixel\Block;
use Magento\Framework\View\Element\Template;
class AbstractBlock
extends \Magento\Framework\View\Element\Template
{
/** @var \Cadence\Fbpixel\Helper\Data $_helper */
protected $_helper;
public function __construct(
\Cadence\Fbpixel\Helper\Data $helper,
Template\Context $context,
array $data = []
) {
$this->_helper = $helper;
parent::__construct( $context, $data );
}
public function getHelper(){
return $this->_helper;
}
public function getSession(){
return $this->getHelper()->getSession();
}
public function getCurrencyCode(){
return $this->getHelper()->getCurrencyCode();
}
}
\ No newline at end of file
<?php
namespace Cadence\Fbpixel\CustomerData;
use Magento\Customer\CustomerData\SectionSourceInterface;
use Magento\Customer\Helper\Session\CurrentCustomer;
class Fpc implements SectionSourceInterface
{
/** @var \Cadence\Fbpixel\Helper\Data $_helper */
protected $_helper;
/** @var \Magento\Framework\Url\Helper\Data $_urlHelper */
protected $_urlBuilder;
protected $_customerSession;
protected $_currentCustomer;
public function __construct(
\Magento\Framework\UrlInterface $urlBuilder,
\Magento\Customer\Model\Session $customerSession,
\Cadence\Fbpixel\Helper\Data $helper,
CurrentCustomer $currentCustomer
) {
$this->_urlBuilder = $urlBuilder;
$this->_customerSession = $customerSession;
$this->_helper = $helper;
$this->_currentCustomer = $currentCustomer;
}
/**
* Get data
*
* @return array
*/
public function getSectionData() {
$data = [
'events' => []
];
if ($this->_helper->getSession()->hasAddToCart()) {
// Get the add-to-cart information since it's unique to the user
// but might be displayed on a cached page
$data['events'][] = [
'eventName' => 'AddToCart',
'eventAdditional' => $this->_helper->getSession()->getAddToCart()
];
}
return $data;
}
}
\ No newline at end of file
<?php
namespace Cadence\Fbpixel\Helper;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ProductRepository;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Helper\AbstractHelper;
use Magento\Store\Model\ScopeInterface;
class Data extends AbstractHelper{
/** @var \Magento\Checkout\Model\Session $_checkoutSession */
protected $_checkoutSession;
/** @var \Magento\Sales\Model\OrderFactory $_orderFactory */
protected $_orderFactory;
/** @var ScopeConfigInterface $_scopeConfig */
protected $_scopeConfig;
/** @var \Magento\Sales\Model\Order $_order */
protected $_order;
/** @var \Magento\Catalog\Model\ProductRepository $_productRepository */
protected $_productRepository;
/** @var \Magento\Store\Model\StoreManagerInterface $_storeManager */
protected $_storeManager;
/** @var \Cadence\Fbpixel\Model\Session $_fbPixelSession */
protected $_fbPixelSession;
public function __construct(
\Magento\Checkout\Model\Session $checkoutSession,
\Magento\Sales\Model\OrderFactory $orderFactory,
\Magento\Catalog\Model\ProductRepository $productRepository,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\App\Helper\Context $context,
\Cadence\Fbpixel\Model\Session $fbPixelSession
) {
$this->_checkoutSession = $checkoutSession;
$this->_orderFactory = $orderFactory;
$this->_scopeConfig = $context->getScopeConfig();
$this->_productRepository = $productRepository;
$this->_storeManager = $storeManager;
$this->_fbPixelSession = $fbPixelSession;
parent::__construct( $context );
}
public function isVisitorPixelEnabled()
{
return $this->_scopeConfig->getValue('cadence_fbpixel/visitor/enabled');
}
public function isConversionPixelEnabled()
{
return $this->_scopeConfig->getValue("cadence_fbpixel/conversion/enabled");
}
public function isAddToCartPixelEnabled()
{
return $this->_scopeConfig->getValue("cadence_fbpixel/add_to_cart/enabled");
}
public function isAddToWishlistPixelEnabled()
{
return $this->_scopeConfig->getValue('cadence_fbpixel/add_to_wishlist/enabled');
}
public function isInitiateCheckoutPixelEnabled()
{
return $this->_scopeConfig->getValue('cadence_fbpixel/inititiate_checkout/enabled');
}
public function isViewProductPixelEnabled()
{
return $this->_scopeConfig->getValue('cadence_fbpixel/view_product/enabled');
}
public function isSearchPixelEnabled()
{
return $this->_scopeConfig->getValue('cadence_fbpixel/search/enabled');
}
public function getVisitorPixelId()
{
return $this->_scopeConfig->getValue("cadence_fbpixel/visitor/pixel_id");
}
/**
* @param $event
* @param $data
* @return string
*/
public function getPixelHtml($event, $data = false)
{
$json = '';
if ($data) {
$json = ', ' . json_encode($data);
}
$html = <<<HTML
<!-- Begin Facebook {$event} Pixel -->
<script type="text/javascript">
fbq('track', '{$event}'{$json});
</script>
<!-- End Facebook {$event} Pixel -->
HTML;
return $html;
}
public function getOrderIDs()
{
$orderIDs = array();
/** @var \Magento\Sales\Model\Order\Item $item */
foreach($this->getOrder()->getAllVisibleItems() as $item){
$product = $this->_productRepository->getById($item->getProductId());
$orderIDs = array_merge($orderIDs, $this->_getProductTrackID($product));
}
return json_encode(array_unique($orderIDs));
}
public function getOrder(){
if(!$this->_order){
$this->_order = $this->_checkoutSession->getLastRealOrder();
}
return $this->_order;
}
protected function _getProductTrackID($product)
{
$productType = $product->getTypeID();
if($productType == "grouped") {
return $this->_getProductIDs($product);
} else {
return $this->_getProductID($product);
}
}
protected function _getProductIDs($product)
{
/** @var \Magento\Catalog\Model\Product $product */
$group = $product->getTypeInstance()->setProduct($product);
/** @var \Magento\GroupedProduct\Model\Product\Type\Grouped $group */
$group_collection = $group->getAssociatedProductCollection($product);
$ids = array();
foreach ($group_collection as $group_product) {
$ids[] = $this->_getProductID($group_product);
}
return $ids;
}
protected function _getProductID($product)
{
return array(
$product->getSku()
);
}
public function getOrderItemsCount()
{
$order = $this->getOrder();
$qty = 0;
/** @var \Magento\Sales\Model\Order\Item $item */
foreach($order->getAllVisibleItems() as $item) {
// Get a whole number
$qty += round($item->getQtyOrdered());
}
return $qty;
}
public function getCurrencyCode(){
return $this->_storeManager->getStore()->getCurrentCurrency()->getCode();
}
public function getSession(){
return $this->_fbPixelSession;
}
}
\ No newline at end of file
<?php
namespace Cadence\Fbpixel\Model;
class Session extends \Magento\Framework\Session\SessionManager
{
/**
* @var array
*/
protected $_ephemeralData = [];
/**
* @param $data
* @return $this
*/
public function setAddToCart($data)
{
$this->setData('add_to_cart', $data);
return $this;
}
/**
* @return mixed|null
*/
public function getAddToCart()
{
if ($this->hasAddToCart()) {
$data = $this->getData('add_to_cart');
$this->unsetData('add_to_cart');
return $data;
}
return null;
}
/**
* @return bool
*/
public function hasAddToCart()
{
return $this->hasData('add_to_cart');
}
/**
* @param $data
* @return $this
*/
public function setAddToWishlist($data)
{
$this->setData('add_to_wishlist', $data);
return $this;
}
/**
* @return mixed|null
*/
public function getAddToWishlist()
{
if ($this->hasAddToWishlist()) {
$data = $this->getData('add_to_wishlist');
$this->unsetData('add_to_wishlist');
return $data;
}
return null;
}
/**
* @return bool
*/
public function hasAddToWishlist()
{
return $this->hasData('add_to_wishlist');
}
/**
* @return bool
*/
public function hasInitiateCheckout()
{
$has = $this->hasData('initiate_checkout');
if ($has) {
$this->unsetData('initiate_checkout');
}
return $has;
}
/**
* @return $this
*/
public function setInitiateCheckout()
{
$this->setData('initiate_checkout', true);
return $this;
}
/**
* @return bool
*/
public function hasViewProduct()
{
return $this->_hasEphemeral('view_product');
}
/**
* @return mixed|null
*/
public function getViewProduct()
{
if ($this->hasViewProduct()) {
$data = $this->_getEphemeral('view_product');
$this->_unsetEphemeral('view_product');
return $data;
}
return null;
}
/**
* @param $data
* @return $this
*/
public function setViewProduct($data)
{
$this->_setEphemeral('view_product', $data);
return $this;
}
/**
* @return bool
*/
public function hasSearch()
{
return $this->_hasEphemeral('search');
}
/**
* @return mixed|null
*/
public function getSearch()
{
if ($this->hasSearch()) {
$data = $this->_getEphemeral('search');
$this->_unsetEphemeral('search');
return $data;
}
return null;
}
/**
* @param $value
* @return $this
*/
public function setSearch($value)
{
$this->_setEphemeral('search', $value);
return $this;
}
/**
* @param $key
* @param $value
* @return $this
*/
protected function _setEphemeral($key, $value)
{
$this->_ephemeralData[$key] = $value;
return $this;
}
/**
* @param $key
* @return mixed
*/
protected function _getEphemeral($key)
{
return isset($this->_ephemeralData[$key])
? $this->_ephemeralData[$key]
: null;
}
/**
* @param $key
* @return bool
*/
protected function _hasEphemeral($key)
{
return isset($this->_ephemeralData[$key]);
}
/**
* @param $key
* @return $this
*/
protected function _unsetEphemeral($key)
{
unset($this->_ephemeralData[$key]);
return $this;
}
}
\ No newline at end of file
<?php
namespace Cadence\Fbpixel\Observer;
use Magento\Framework\Event\ObserverInterface;
class CatalogControllerProductInitAfter implements ObserverInterface {
/** @var \Cadence\Fbpixel\Model\Session $_fbPixelSession */
protected $_fbPixelSession;
/** @var \Magento\Checkout\Model\Session $_checkoutSession */
protected $_checkoutSession;
/** @var \Cadence\Fbpixel\Helper\Data $_fbPixelHelper */
protected $_fbPixelHelper;
public function __construct(
\Cadence\Fbpixel\Model\Session $fbPixelSession,
\Magento\Checkout\Model\Session $checkoutSession,
\Cadence\Fbpixel\Helper\Data $helper
) {
$this->_fbPixelSession = $fbPixelSession;
$this->_checkoutSession = $checkoutSession;
$this->_fbPixelHelper = $helper;
}
/**
* @param \Magento\Framework\Event\Observer $observer
*
* @return void
*/
public function execute( \Magento\Framework\Event\Observer $observer ) {
/** @var Mage_Catalog_Model_Product $product */
$product = $observer->getProduct();
if (!$this->_fbPixelHelper->isViewProductPixelEnabled() || !$product) {
return $this;
}
$data = [
'content_type' => 'product',
'content_ids' => [$product->getSku()],
'value' => $product->getFinalPrice(),
'currency' => $this->_fbPixelHelper->getCurrencyCode(),
'content_name' => $product->getName()
];
$this->_fbPixelSession->setViewProduct($data);
return $this;
}
}
\ No newline at end of file
<?php
namespace Cadence\Fbpixel\Observer;
use Magento\Framework\Event\ObserverInterface;
class InitiateCheckout implements ObserverInterface {
/** @var \Cadence\Fbpixel\Model\Session $_fbPixelSession */
protected $_fbPixelSession;
/** @var \Magento\Checkout\Model\Session $_checkoutSession */
protected $_checkoutSession;
/** @var \Cadence\Fbpixel\Helper\Data $_fbPixelHelper */
protected $_fbPixelHelper;
public function __construct(
\Cadence\Fbpixel\Model\Session $fbPixelSession,
\Magento\Checkout\Model\Session $checkoutSession,
\Cadence\Fbpixel\Helper\Data $helper
) {
$this->_fbPixelSession = $fbPixelSession;
$this->_checkoutSession = $checkoutSession;
$this->_fbPixelHelper = $helper;
}
/**
* @param \Magento\Framework\Event\Observer $observer
*
* @return void
*/
public function execute( \Magento\Framework\Event\Observer $observer ) {
if (!$this->_fbPixelHelper->isInitiateCheckoutPixelEnabled()) {
return $this;
}
if (!count($this->_checkoutSession->getQuote()->getAllVisibleItems())) {
return $this;
}
$this->_fbPixelSession->setInitiateCheckout();
return $this;
}
}
\ No newline at end of file
<?php
namespace Cadence\Fbpixel\Observer;
use Magento\Framework\Event\ObserverInterface;
class SalesQuoteProductAddAfter implements ObserverInterface {
/** @var \Cadence\Fbpixel\Model\Session $_fbPixelSession */
protected $_fbPixelSession;
/** @var \Magento\Checkout\Model\Session $_checkoutSession */
protected $_checkoutSession;
/** @var \Cadence\Fbpixel\Helper\Data $_fbPixelHelper */
protected $_fbPixelHelper;
public function __construct(
\Cadence\Fbpixel\Model\Session $fbPixelSession,
\Magento\Checkout\Model\Session $checkoutSession,
\Cadence\Fbpixel\Helper\Data $helper
) {
$this->_fbPixelSession = $fbPixelSession;
$this->_checkoutSession = $checkoutSession;
$this->_fbPixelHelper = $helper;
}
/**
* @param \Magento\Framework\Event\Observer $observer
*
* @return void
*/
public function execute( \Magento\Framework\Event\Observer $observer ) {
if(!$this->_fbPixelHelper->isAddToCartPixelEnabled()){
return $this;
}
$items = $observer->getItems();
$candidates = array_replace([
'content_ids' => [],
'value' => 0.00
], $this->_fbPixelSession->getAddToCart() ?: array());
/** @var \Magento\Sales\Model\Order\Item $item */
foreach ($items as $item) {
if ($item->getParentItem()) {
continue;
}
$candidates['content_ids'][] = $item->getSku();
$candidates['value'] += $item->getProduct()->getFinalPrice() * $item->getProduct()->getQty();
}
$data = array(
'content_type' => 'product',
'content_ids' => $candidates['content_ids'],
'value' => $candidates['value'],
'currency' => $this->_fbPixelHelper->getCurrencyCode()
);
$this->_fbPixelSession->setAddToCart($data);
return $this;
}
}
\ No newline at end of file
<?php
namespace Cadence\Fbpixel\Observer;
use Magento\Framework\Event\ObserverInterface;
class Search implements ObserverInterface {
/** @var \Cadence\Fbpixel\Model\Session $_fbPixelSession */
protected $_fbPixelSession;
/** @var \Magento\Checkout\Model\Session $_checkoutSession */
protected $_checkoutSession;
/** @var \Cadence\Fbpixel\Helper\Data $_fbPixelHelper */
protected $_fbPixelHelper;
/** @var \Magento\Search\Helper\Data $_searchHelper */
protected $_searchHelper;
public function __construct(
\Cadence\Fbpixel\Model\Session $fbPixelSession,
\Magento\Checkout\Model\Session $checkoutSession,
\Cadence\Fbpixel\Helper\Data $helper,
\Magento\Search\Helper\Data $searchHelper
) {
$this->_fbPixelSession = $fbPixelSession;
$this->_checkoutSession = $checkoutSession;
$this->_fbPixelHelper = $helper;
$this->_searchHelper = $searchHelper;
}
/**
* @param \Magento\Framework\Event\Observer $observer
*
* @return void
*/
public function execute( \Magento\Framework\Event\Observer $observer ) {
$text = $this->_searchHelper->getEscapedQueryText();
if (!$this->_fbPixelHelper->isSearchPixelEnabled() || !$text || !strlen($text)) {
return $this;
}
$data = [
'search_string' => $text
];
$this->_fbPixelSession->setSearch($data);
return $this;
}
}
\ No newline at end of file
<?php
namespace Cadence\Fbpixel\Observer;
use Magento\Framework\Event\ObserverInterface;
class WishlistAddProduct implements ObserverInterface {
/** @var \Cadence\Fbpixel\Model\Session $_fbPixelSession */
protected $_fbPixelSession;
/** @var \Magento\Checkout\Model\Session $_checkoutSession */
protected $_checkoutSession;
/** @var \Cadence\Fbpixel\Helper\Data $_fbPixelHelper */
protected $_fbPixelHelper;
public function __construct(
\Cadence\Fbpixel\Model\Session $fbPixelSession,
\Magento\Checkout\Model\Session $checkoutSession,
\Cadence\Fbpixel\Helper\Data $helper
) {
$this->_fbPixelSession = $fbPixelSession;
$this->_checkoutSession = $checkoutSession;
$this->_fbPixelHelper = $helper;
}
/**
* @param \Magento\Framework\Event\Observer $observer
*
* @return void
*/
public function execute( \Magento\Framework\Event\Observer $observer ) {
/** @var \Magento\Catalog\Model\Product $product */
$product = $observer->getProduct();
if (!$this->_fbPixelHelper->isAddToWishlistPixelEnabled() || !$product) {
return $this;
}
$data = [
'content_type' => 'product',
'content_ids' => [$product->getSku()],
'value' => $product->getFinalPrice(),
'currency' => $this->_fbPixelHelper->getCurrencyCode()
];
$this->_fbPixelSession->setAddToWishlist($data);
return $this;
}
}
\ No newline at end of file
# cadence/m2-fbpixel
## Magento 2 Facebook Pixel Implementation
This extension adds support to Magento 2 for the Facebook Pixel and its associated events.
Current event support:
* Purchase (Checkout)
* ViewContent
* AddToCart
* AddToWishlist
* Initiate Checkout
* View Page
### License
GPL 3.0
### More Info
For user guide & full details see: https://www.cadence-labs.com/2017/09/free-magento-2-facebook-tracking-pixel-extension/
{
"name": "cadence/fbpixel-m2",
"description": "Facebook Pixel & Events Support For Magento 2.x",
"keywords": [
"Magento",
"Magento 2",
"Facebook Pixel",
"Facebook"
],
"type": "magento2-module",
"version": "1.0.0",
"license": [
"MIT"
],
"authors": [
{
"name": "Cadence Labs",
"homepage": "https://www.cadence-labs.com",
"email": "info@cadence-labs.com"
}
],
"autoload": {
"files": [
"registration.php"
],
"psr-4": {
"Cadence\\Fbpixel\\": ""
}
}
}
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Acl/etc/acl.xsd">
<acl>
<resources>
<resource id="Magento_Backend::admin">
<resource id="Magento_Backend::stores">
<resource id="Magento_Backend::stores_settings">
<resource id="Magento_Config::config">
<!-- this resource id we can use in system.xml for section -->
<resource id="Cadence_Fbpixel::config_cadence_fbpixel" title="Cadence Labs Facebook Pixel" sortOrder="90" />
</resource>
</resource>
</resource>
</resource>
</resources>
</acl>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<tab id="cadence" translate="label" sortOrder="500">
<label>Cadence</label>
</tab>
<section id="cadence_fbpixel" translate="label" type="text" sortOrder="3000" showInDefault="1" showInWebsite="1" showInStore="1" >
<class>separator-top</class>
<label>Facebook Pixel</label>
<tab>cadence</tab>
<resource>Cadence_Fbpixel::config_cadence_fbpixel</resource>
<group id="visitor" translate="label" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Visitor Pixel</label>
<field id="enabled" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="pixel_id" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Pixel ID</label>
<comment>This is the pixelId for the facebook pixel (see the install guide for instructions on where to find this).</comment>
</field>
</group>
<group id="conversion" translate="label" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Conversion Event (Optional)</label>
<field id="enabled" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>The base pixel must be enabled to track conversions. Includes parameters for grand total and currency.</comment>
</field>
</group>
<group id="add_to_cart" translate="label" type="text" sortOrder="30" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Add To Cart (Optional)</label>
<field id="enabled" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>The base pixel must be enabled to track addToCart. Includes parameters for all product SKU's added, the total value for added products, and currency.</comment>
</field>
</group>
<group id="add_to_wishlist" translate="label" type="text" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Add To Wishlist (Optional)</label>
<field id="enabled" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>The base pixel must be enabled to track addToWishlist. Includes parameters for the product sku added, price of product, and currency.</comment>
</field>
</group>
<group id="inititiate_checkout" translate="label" type="text" sortOrder="50" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Initiate Checkout (Optional)</label>
<field id="enabled" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>The base pixel must be enabled to track initiateCheckout. Includes no parameters</comment>
</field>
</group>
<group id="view_product" translate="label" type="text" sortOrder="60" showInDefault="1" showInWebsite="1" showInStore="1">
<label>View Product (Optional)</label>
<field id="enabled" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>The base pixel must be enabled to track viewProduct. Includes parameters for product price, product name, product sku, and currency</comment>
</field>
</group>
<group id="search" translate="label" type="text" sortOrder="70" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Search (Optional)</label>
<field id="enabled" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
<comment>The base pixel must be enabled to track search. Includes a parameter for the search string.</comment>
</field>
</group>
</section>
</system>
</config>
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<cadence_fbpixel>
<visitor>
<enable>0</enable>
</visitor>
<conversion>
<enable>0</enable>
</conversion>
</cadence_fbpixel>
</default>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<virtualType name="Cadence\Fbpixel\Model\Session\Storage" type="Magento\Framework\Session\Storage">
<arguments>
<argument name="namespace" xsi:type="string">cadence_fbpixel</argument>
</arguments>
</virtualType>
<type name="Cadence\Fbpixel\Model\Session">
<arguments>
<argument name="storage" xsi:type="object">Cadence\Fbpixel\Model\Session\Storage</argument>
</arguments>
</type>
</config>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Customer\CustomerData\SectionPoolInterface">
<arguments>
<argument name="sectionSourceMap" xsi:type="array">
<item name="cadence-fbpixel-fpc" xsi:type="string">Cadence\Fbpixel\CustomerData\Fpc</item>
</argument>
</arguments>
</type>
</config>
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="sales_quote_product_add_after">
<observer name="cadence_fbpixel_add_to_cart" instance="Cadence\Fbpixel\Observer\SalesQuoteProductAddAfter" />
</event>
<event name="wishlist_add_product">
<observer name="cadence_fbpixel_add_to_wishlist" instance="Cadence\Fbpixel\Observer\WishlistAddProduct" />
</event>
<event name="controller_action_predispatch_multishipping_checkout_index">
<observer name="cadence_fbpixel_initiate_checkout_multi" instance="Cadence\Fbpixel\Observer\InitiateCheckout" />
</event>
<event name="controller_action_predispatch_checkout_onepage_index">
<observer name="cadence_fbpixel_initiate_checkout_onepage" instance="Cadence\Fbpixel\Observer\InitiateCheckout" />
</event>
<event name="controller_action_predispatch_checkout_index_index">
<observer name="cadence_fbpixel_initiate_checkout_index_index" instance="Cadence\Fbpixel\Observer\InitiateCheckout" />
</event>
<event name="controller_action_predispatch_catalogsearch_result_index">
<observer name="cadence_fbpixel_search" instance="Cadence\Fbpixel\Observer\Search" />
</event>
<event name="catalog_controller_product_init_after">
<observer name="cadence_fbpixel_product_init_after" instance="Cadence\Fbpixel\Observer\CatalogControllerProductInitAfter" />
</event>
</config>
\ No newline at end of file
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Customer:etc/sections.xsd">
<action name="checkout/cart/add">
<section name="cadence-fbpixel-fpc"/>
</action>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Cadence_Fbpixel" setup_version="0.1.0">
<sequence>
<module name="Magento_Directory"/>
<module name="Magento_Checkout"/>
<module name="Magento_Sales"/>
<module name="Magento_Ui"/>
</sequence>
</module>
</config>
\ No newline at end of file
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Cadence_Fbpixel',
__DIR__
);
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* Copyright © 2017 Cadence Labs LLC. All rights reserved.
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="after.body.start">
<block class="Cadence\Fbpixel\Block\AbstractBlock" name="cadence_fbpixel_conversion" template="Cadence_Fbpixel::cadence/fbpixel/conversion.phtml"/>
</referenceContainer>
</body>
</page>
<?xml version="1.0"?>
<!--
/**
* Copyright © 2017 Cadence Labs LLC. All rights reserved.
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="head.additional">
<block class="Cadence\Fbpixel\Block\AbstractBlock" name="cadence_fbpixel_visitor" template="Cadence_Fbpixel::cadence/fbpixel/visitor.phtml"/>
<block class="Cadence\Fbpixel\Block\AbstractBlock" name="cadence_fbpixel_events" template="Cadence_Fbpixel::cadence/fbpixel/events.phtml" />
</referenceBlock>
<referenceBlock name="after.body.start">
<block class="Magento\Framework\View\Element\Template" name="cadence.fbpixel.fpc" before="-"
template="Cadence_Fbpixel::cadence/fbpixel/fpc.phtml">
<arguments>
<argument name="jsLayout" xsi:type="array">
<item name="components" xsi:type="array">
<item name="cadenceFbpixelFpc" xsi:type="array">
<item name="component" xsi:type="string">Cadence_Fbpixel/js/view/cadence-fbpixel-fpc</item>
</item>
</item>
</argument>
</arguments>
</block>
</referenceBlock>
</body>
</page>
\ No newline at end of file
<?xml version="1.0"?>
<!--
/**
* Copyright © 2017 Cadence Labs LLC. All rights reserved.
*/
-->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="after.body.start">
<block class="Cadence\Fbpixel\Block\AbstractBlock" name="cadence_fbpixel_conversion" template="Cadence_Fbpixel::cadence/fbpixel/conversion.phtml"/>
</referenceContainer>
</body>
</page>
\ No newline at end of file
<?php
/** @var Cadence\Fbpixel\Block\AbstractBlock $block */
$helper = $block->getHelper();
if (!$helper->isConversionPixelEnabled()) {
return;
}
$id = $helper->getVisitorPixelId();
?>
<?php
/** @var Magento\Sales\Model\Order $order */
$order = $helper->getOrder();
if (!$order) {
//Failsafe for bad order id
return;
}
$grand_total = round($order->getGrandTotal(), 2);
$currency_code = $block->getCurrencyCode();
$orderIds = $helper->getOrderIDs();
$numItems = $helper->getOrderItemsCount();
?>
<!-- Facebook Conversion Code for Conversions -->
<script>
fbq('track','Purchase', {
value: <?php echo $grand_total ?>,
currency: '<?php echo $currency_code ?>',
content_ids: <?php echo $orderIds ?>,
content_type: 'product',
num_items: <?php echo $numItems; ?>
});
</script>
<noscript><img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=<?php echo $id ?>&ev=Purchase&cd[value]=<?php echo $grand_total ?>&cd[currency]=<?php echo $currency_code ?>&cd[num_items]=<?php echo $numItems ?>&noscript=1"
/></noscript>
\ No newline at end of file
<?php
/** @var Cadence\Fbpixel\Block\AbstractBlock $block */
$helper = $block->getHelper();
$session = $block->getSession();
$id = $helper->getVisitorPixelId();
?>
<?php /*if ($helper->isAddToCartPixelEnabled() && $session->hasAddToCart()) : ?>
<?php echo $helper->getPixelHtml('AddToCart', $session->getAddToCart()); ?>
<?php endif;
AddToCart Handled by FPC
*/ ?>
<?php if ($helper->isAddToWishlistPixelEnabled() && $session->hasAddToWishlist()): ?>
<?php echo $helper->getPixelHtml('AddToWishlist', $session->getAddToWishlist()); ?>
<?php endif; ?>
<?php if ($helper->isInitiateCheckoutPixelEnabled() && $session->hasInitiateCheckout()): ?>
<?php echo $helper->getPixelHtml('InitiateCheckout'); ?>
<?php endif; ?>
<?php if ($helper->isViewProductPixelEnabled() && $session->hasViewProduct()): ?>
<?php echo $helper->getPixelHtml('ViewContent', $session->getViewProduct()); ?>
<?php endif; ?>
<?php if ($helper->isSearchPixelEnabled() && $session->hasSearch()): ?>
<?php echo $helper->getPixelHtml('Search', $session->getSearch()); ?>
<?php endif; ?>
<div data-role="cadence-fbpixel-fpc" style="display:none;">
</div>
<script type="text/x-magento-init">
{"[data-role='cadence-fbpixel-fpc']": {"Magento_Ui/js/core/app": <?php echo $block->getJsLayout();?>}}
</script>
\ No newline at end of file
<?php
/** @var Cadence\Fbpixel\Block\AbstractBlock $block */
$helper = $block->getHelper();
if (!$helper->isVisitorPixelEnabled()) {
return;
}
$id = $helper->getVisitorPixelId();
?>
<!-- Facebook Pixel Code -->
<script>
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','//connect.facebook.net/en_US/fbevents.js');
fbq('init', '<?php echo $id ?>');
fbq('track', "PageView");
</script>
<noscript><img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=<?php echo $id ?>&ev=PageView&noscript=1"
/></noscript>
<!-- End Facebook Pixel Code -->
/**
* Copyright © 2013-2017 Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
define([
'ko',
'uiComponent',
'Magento_Customer/js/customer-data'
], function (ko, Component, customerData) {
'use strict';
return Component.extend({
initialize: function () {
var self = this;
self._super();
//console.log(customerData.get('cadence-fbpixel-fpc')());
customerData.get('cadence-fbpixel-fpc').subscribe(function(loadedData){
//console.log(loadedData);
if (loadedData && "undefined" !== typeof loadedData.events) {
for (var eventCounter = 0; eventCounter < loadedData.events.length; eventCounter++) {
var eventData = loadedData.events[eventCounter];
//console.log(eventData);
if ("undefined" !== typeof eventData.eventAdditional && eventData.eventAdditional) {
//console.log("Tracking: " + eventData.eventName + " , with data: ");
//console.log(eventData.eventAdditional);
fbq('track', eventData.eventName, eventData.eventAdditional || {});
}
}
customerData.set('cadence-fbpixel-fpc', {});
}
});
}
});
});
\ No newline at end of file
<?php
namespace Joshine\CouponPusher\Block;
class CouponNopeAlert extends \Magento\Framework\View\Element\Template
{
protected $_template = 'Joshine_CouponPusher::coupon-nope-alert.phtml';
}
\ No newline at end of file
<?php
namespace Joshine\CouponPusher\Block;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\View\Element\Template;
use Magento\Newsletter\Model\Subscriber;
use Magento\Store\Model\ScopeInterface;
class CouponSubscribeAlert extends \Magento\Framework\View\Element\Template
{
protected $_template = 'Joshine_CouponPusher::coupon-subscribe-alert.phtml';
protected $coupon;
protected $_objectManager;
protected $saleRule;
protected $_rule;
public function __construct(
Template\Context $context,
array $data = [],
\Magento\SalesRule\Model\Coupon $coupon,
\Magento\SalesRule\Model\Rule $saleRule,
\Magento\Framework\ObjectManagerInterface $objectManager
)
{
parent::__construct($context, $data);
$this->coupon = $coupon;
$this->saleRule = $saleRule;
$this->_objectManager = $objectManager;
}
public function getCoupon()
{
if (empty($this->_rule)) {
$code = $this->_objectManager->get(ScopeConfigInterface::class)
->getValue(
'joshine_coupon_pusher/general/newsletter_coupon_code',
ScopeInterface::SCOPE_STORE
);
$ruleId = $this->coupon->loadByCode($code)->getRuleId();
$rule = $this->saleRule->load($ruleId);
$this->_rule = $rule;
}
return $this->_rule;
}
public function getCouponTitle()
{
return $this->_objectManager->get(ScopeConfigInterface::class)
->getValue(
'joshine_coupon_pusher/general/newsletter_coupon_title',
ScopeInterface::SCOPE_STORE
);
}
public function getInformationTitle()
{
return $this->_objectManager->get(ScopeConfigInterface::class)
->getValue(
'joshine_coupon_pusher/general/newsletter_information_title',
ScopeInterface::SCOPE_STORE
);
}
public function getInformationText()
{
return $this->_objectManager->get(ScopeConfigInterface::class)
->getValue(
'joshine_coupon_pusher/general/newsletter_information_text',
ScopeInterface::SCOPE_STORE
);
}
public function getCouponDescription()
{
return $this->getCoupon()->getData('description');
}
}
\ No newline at end of file
<?php
namespace Joshine\CouponPusher\Block;
class JsInit extends \Magento\Framework\View\Element\Template {
protected $_template = 'Joshine_CouponPusher::js-init.phtml';
}
\ No newline at end of file
<?php
namespace Joshine\CouponPusher\Controller\Ajax;
use Joshine\CouponPusher\Helper\CustomerChecker;
use Joshine\CouponPusher\Model\PushStrategyManager;
use Magento\Catalog\Model\ProductFactory;
use Magento\Framework\App\Action\Context;
use Magento\Framework\Controller\Result\JsonFactory;
use Magento\Framework\Exception\LocalizedException;
class CouponPusher extends \Magento\Framework\App\Action\Action {
protected $subscriptionManager;
protected $customerChecker;
protected $pushStrategyManager;
protected $formKeyValidator;
protected $remoteAddress;
protected $logger;
protected $jsonEncoder;
protected $resultJsonFactory;
public function __construct(
Context $context,
CustomerChecker $customerChecker,
PushStrategyManager $pushStrategyManager,
\Magento\Framework\Data\Form\FormKey\Validator $formKeyValidator,
\Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress,
\Psr\Log\LoggerInterface $logger,
\Magento\Framework\Json\EncoderInterface $jsonEncoder,
JsonFactory $resultJsonFactory
)
{
parent::__construct($context);
$this->customerChecker = $customerChecker;
$this->pushStrategyManager = $pushStrategyManager;
$this->formKeyValidator = $formKeyValidator;
$this->remoteAddress = $remoteAddress;
$this->logger = $logger;
$this->jsonEncoder = $jsonEncoder;
$this->resultJsonFactory = $resultJsonFactory;
}
public function execute()
{
$message = [
'error' => __('Sorry. There is a problem with your Request.')
];
if ($this->getRequest()->isAjax()) {
try {
if (!$this->formKeyValidator->validate($this->getRequest())) {
throw new LocalizedException(
__('Form key is not valid. Please try to reload the page.')
);
}
$message = [
'success' => __('Success.'),
'data' => $this->pushStrategyManager->getPushTemplate(),
];
} catch (LocalizedException $e) {
$message = ['error' => $e->getMessage()];
} catch (\Exception $e) {
$this->logger->error($e->getMessage());
}
}
$resultPage = $this->resultJsonFactory->create();
$resultPage->setHttpResponseCode(200);
$resultPage->setData($message);
return $resultPage;
}
}
\ No newline at end of file
<?php
/**
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Joshine\CouponPusher\Controller\Ajax;
use Magento\Customer\Api\AccountManagementInterface as CustomerAccountManagement;
use Magento\Customer\Model\Session;
use Magento\Customer\Model\Url as CustomerUrl;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\Action\HttpPostActionInterface;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Controller\Result\Redirect;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Phrase;
use Magento\Framework\Validator\EmailAddress as EmailValidator;
use Magento\Newsletter\Controller\Subscriber as SubscriberController;
use Magento\Newsletter\Model\Subscriber;
use Magento\Newsletter\Model\SubscriptionManagerInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Newsletter\Model\SubscriberFactory;
use Magento\Framework\Controller\Result\JsonFactory;
/**
* New newsletter subscription action
*
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class Subscribe extends SubscriberController implements HttpPostActionInterface
{
/**
* @var CustomerAccountManagement
*/
protected $customerAccountManagement;
/**
* @var EmailValidator
*/
private $emailValidator;
/**
* @var SubscriptionManagerInterface
*/
private $subscriptionManager;
private $resultJsonFactory;
/**
* Initialize dependencies.
*
* @param Context $context
* @param SubscriberFactory $subscriberFactory
* @param Session $customerSession
* @param StoreManagerInterface $storeManager
* @param CustomerUrl $customerUrl
* @param CustomerAccountManagement $customerAccountManagement
* @param SubscriptionManagerInterface $subscriptionManager
* @param EmailValidator $emailValidator
*/
public function __construct(
Context $context,
SubscriberFactory $subscriberFactory,
Session $customerSession,
StoreManagerInterface $storeManager,
CustomerUrl $customerUrl,
CustomerAccountManagement $customerAccountManagement,
SubscriptionManagerInterface $subscriptionManager,
EmailValidator $emailValidator = null,
JsonFactory $jsonFactory
) {
$this->customerAccountManagement = $customerAccountManagement;
$this->subscriptionManager = $subscriptionManager;
$this->emailValidator = $emailValidator ?: ObjectManager::getInstance()->get(EmailValidator::class);
$this->resultJsonFactory = $jsonFactory;
parent::__construct(
$context,
$subscriberFactory,
$customerSession,
$storeManager,
$customerUrl
);
}
/**
* Validates that the email address isn't being used by a different account.
*
* @param string $email
* @throws LocalizedException
* @return void
*/
protected function validateEmailAvailable($email)
{
$websiteId = $this->_storeManager->getStore()->getWebsiteId();
if ($this->_customerSession->isLoggedIn()
&& ($this->_customerSession->getCustomerDataObject()->getEmail() !== $email
&& !$this->customerAccountManagement->isEmailAvailable($email, $websiteId))
) {
throw new LocalizedException(
__('This email address is already assigned to another user.')
);
}
}
/**
* Validates that if the current user is a guest, that they can subscribe to a newsletter.
*
* @throws LocalizedException
* @return void
*/
protected function validateGuestSubscription()
{
if ($this->_objectManager->get(ScopeConfigInterface::class)
->getValue(
Subscriber::XML_PATH_ALLOW_GUEST_SUBSCRIBE_FLAG,
ScopeInterface::SCOPE_STORE
) != 1
&& !$this->_customerSession->isLoggedIn()
) {
throw new LocalizedException(
__(
'Sorry, but the administrator denied subscription for guests. Please <a href="%1">register</a>.',
$this->_customerUrl->getRegisterUrl()
)
);
}
}
/**
* Validates the format of the email address
*
* @param string $email
* @throws LocalizedException
* @return void
*/
protected function validateEmailFormat($email)
{
if (!$this->emailValidator->isValid($email)) {
throw new LocalizedException(__('Please enter a valid email address.'));
}
}
/**
* New subscription action
*
* @return Redirect
*/
public function execute()
{
$message = [
'error' => __('Sorry. There is a problem with your Request.')
];
if ($this->getRequest()->isPost() && $this->getRequest()->getPost('email')) {
$email = (string)$this->getRequest()->getPost('email');
try {
$this->validateEmailFormat($email);
$this->validateGuestSubscription();
$this->validateEmailAvailable($email);
$websiteId = (int)$this->_storeManager->getStore()->getWebsiteId();
/** @var Subscriber $subscriber */
$subscriber = $this->_subscriberFactory->create()->loadBySubscriberEmail($email, $websiteId);
if ($subscriber->getId()
&& (int)$subscriber->getSubscriberStatus() === Subscriber::STATUS_SUBSCRIBED) {
throw new LocalizedException(
__('This email address is already subscribed.')
);
}
$storeId = (int)$this->_storeManager->getStore()->getId();
$currentCustomerId = $this->getSessionCustomerId($email);
$subscriber = $currentCustomerId
? $this->subscriptionManager->subscribeCustomer($currentCustomerId, $storeId)
: $this->subscriptionManager->subscribe($email, $storeId);
$message = $this->getSuccessMessage((int)$subscriber->getSubscriberStatus());
$message = [
'success' => __('Success.'),
'data' => $message,
];
} catch (LocalizedException $e) {
$message = ['error' => $e->getMessage()];
} catch (\Exception $e) {
$message = ['error' => $e->getMessage()];
$this->logger->error($e->getMessage());
}
}
$resultPage = $this->resultJsonFactory->create();
$resultPage->setHttpResponseCode(200);
$resultPage->setData($message);
return $resultPage;
}
/**
* Get customer id from session if he is owner of the email
*
* @param string $email
* @return int|null
*/
private function getSessionCustomerId(string $email): ?int
{
if (!$this->_customerSession->isLoggedIn()) {
return null;
}
$customer = $this->_customerSession->getCustomerDataObject();
if ($customer->getEmail() !== $email) {
return null;
}
return (int)$this->_customerSession->getId();
}
/**
* Get success message
*
* @param int $status
* @return Phrase
*/
private function getSuccessMessage(int $status): Phrase
{
if ($status === Subscriber::STATUS_NOT_ACTIVE) {
return __('The confirmation request has been sent.');
}
return __('Thank you for your subscription.');
}
}
<?php
namespace Joshine\CouponPusher\Helper;
class Constant {
const FIRST_VISITOR = 'first_visitor';
const OTHER = 'other';
}
<?php
namespace Joshine\CouponPusher\Helper;
class CustomerChecker implements \Magento\Framework\Data\CollectionDataSourceInterface
{
const HAS_VISITED_COOKIE_KEY = 'has_visited';
const HAS_VISITED_COOKIE_DURATION = 86400 * 30;
protected $_cookieManager;
protected $_dateTime;
protected $_cookieMetadataFactory;
private $_request;
public function __construct(
\Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
\Magento\Framework\Stdlib\CookieManagerInterface $cookieManager,
\Magento\Framework\Stdlib\Cookie\CookieMetadataFactory $cookieMetadataFactory,
\Magento\Framework\App\RequestInterface $request
)
{
$this->_cookieManager = $cookieManager;
$this->_cookieMetadataFactory = $cookieMetadataFactory;
$this->_dateTime = $dateTime;
$this->_request = $request;
}
public function checkFirstVisit(): bool
{
$previousTimestamp = $this->_cookieManager->getCookie(self::HAS_VISITED_COOKIE_KEY);
if (!$previousTimestamp) {
$metadata = $this->_cookieMetadataFactory
->createPublicCookieMetadata()
->setPath('/')
->setDuration(self::HAS_VISITED_COOKIE_DURATION);
$this->_cookieManager->setPublicCookie(
self::HAS_VISITED_COOKIE_KEY,
'true',
$metadata
);
return true;
}
return false;
}
//访客细分
public function getCustomerSegments(): string
{
if ($this->checkFirstVisit()) {
return Constant::FIRST_VISITOR;
}
return Constant::OTHER;
}
}
<?php
namespace Joshine\CouponPusher\Model;
use Joshine\CouponPusher\Helper\Constant;
use Joshine\CouponPusher\Helper\CustomerChecker;
use Joshine\CouponPusher\Model\Strategy\ContractPushStrategy;
use Joshine\CouponPusher\Model\Strategy\FirstVisitorPushStrategy;
use Joshine\CouponPusher\Model\Strategy\NopePushStrategy;
use Magento\Framework\ObjectManagerInterface;
class PushStrategyManager
{
protected $_customerChecker;
protected $_objectManger;
public function __construct(
CustomerChecker $customerChecker,
ObjectManagerInterface $objectManager
)
{
$this->_customerChecker = $customerChecker;
$this->_objectManger = $objectManager;
}
public function tagToStrategy($tag): string
{
$map = [
Constant::FIRST_VISITOR => FirstVisitorPushStrategy::class,
];
if (!isset($map[$tag])) {
return NopePushStrategy::class;
}
return $map[$tag];
}
public function getPushTemplate() {
$tag = $this->_customerChecker->getCustomerSegments();
$strategyName = $this->tagToStrategy($tag);
/**
* @var $strategy ContractPushStrategy
*/
$strategy = $this->_objectManger->create($strategyName);
return $strategy->push();
}
}
\ No newline at end of file
<?php
namespace Joshine\CouponPusher\Model\Strategy;
interface ContractPushStrategy
{
public function push();
}
\ No newline at end of file
<?php
namespace Joshine\CouponPusher\Model\Strategy;
use Joshine\CouponPusher\Block\CouponSubscribeAlert;
class FirstVisitorPushStrategy implements ContractPushStrategy
{
/**
* @var \Magento\Framework\View\Element\BlockFactory
*/
private $blockFactory;
public function __construct(
\Magento\Framework\View\Element\BlockFactory $blockFactory
)
{
$this->blockFactory = $blockFactory;
}
public function push()
{
return $this->blockFactory->createBlock(CouponSubscribeAlert::class)->toHtml();
}
}
\ No newline at end of file
<?php
namespace Joshine\CouponPusher\Model\Strategy;
use Joshine\CouponPusher\Block\CouponNopeAlert;
class NopePushStrategy implements ContractPushStrategy
{
/**
* @var \Magento\Framework\View\Element\BlockFactory
*/
private $blockFactory;
public function __construct(
\Magento\Framework\View\Element\BlockFactory $blockFactory
)
{
$this->blockFactory = $blockFactory;
}
public function push()
{
return $this->blockFactory->createBlock(CouponNopeAlert::class)->toHtml();
}
}
\ No newline at end of file
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="joshine_coupon_pusher" frontName="joshine_coupon_pusher">
<module name="joshine_coupon_pusher"/>
</route>
</router>
</config>
\ No newline at end of file
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="joshine_coupon_pusher" translate="label" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<class>separator-top</class>
<label>CouponPusher</label>
<tab>joshine</tab>
<resource>Joshine_CouponPusher::opt_config</resource>
<group id="general" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
<label>General Configuration</label>
<field id="enabled" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Module Enable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="newsletter_coupon_code" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Newsletter Coupon Code</label>
<comment>Coupon will display on the frontend.</comment>
</field>
<field id="newsletter_coupon_title" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Newsletter Coupon Title</label>
<comment>Coupon will display on the frontend.</comment>
</field>
<field id="newsletter_information_title" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Newsletter Information Title</label>
<comment>Coupon will display on the frontend.</comment>
</field>
<field id="newsletter_information_text" translate="label" type="textarea" sortOrder="1" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Newsletter Information Text</label>
<comment>Coupon will display on the frontend.</comment>
</field>
</group>
</section>
</system>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<opt>
<general>
<enabled>0</enabled>
<newsletter_coupon_title>??% OF</newsletter_coupon_title>
<newsletter_information_title>Submit email address to get your exclusive offer.</newsletter_information_title>
<newsletter_information_text>*You agree to receive autodialed marketing messages on this
number. Consent not required to purchase goods. Message and data rates may apply. Message
frequency may vary. Text STOP to opt out and HELP for help.</newsletter_information_text>
</general>
</opt>
</default>
</config>
\ No newline at end of file
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route id="joshine_coupon_pusher" frontName="joshine_coupon_pusher">
<module name="Joshine_CouponPusher" />
</route>
</router>
</config>
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Joshine_CouponPusher" setup_version="0.0.1">>
</module>
</config>
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Joshine_CouponPusher',
__DIR__
);
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<head>
<css src="Joshine_CouponPusher::css/_coupon_alert.css"/>
</head>
<referenceContainer name="footer-container">
<block class="Joshine\CouponPusher\Block\JsInit" name="coupon.pusher.js" ifconfig="joshine_coupon_pusher/general/enabled"/>
</referenceContainer>
</page>
\ No newline at end of file
<script type="text/javascript">
require(['jquery', 'mage/cookies'], function($) {
if ($.mage.cookies.get('coupon_push_stop') == null) {
// $.mage.cookies.set('coupon_push_stop', 'true');
}
})
</script>
<?php
/**
* @var $block \Joshine\CouponPusher\Block\CouponSubscribeAlert
*/
?>
<style>
.coupon-input-errorMsg {
height: 12px;
font-size: 12px;
color: #fa320f;
line-height: 12px;
font-weight: 400;
text-align: left;
width: 446px;
margin-top: 10px;
display: none;
align-items: center;
position: relative;
}
@media (max-width: 991px) {
#coupon-subscribe-alert.joshine-model-warp .j-modal .j-modal-dialog {
width: 85vw;
}
.coupon-alt .coupon-alt-input {
width: 95%;
}
.coupon-alt .coupon-alt-input-title {
height: auto;
font-size: .8em;
line-height: 1em;
}
.coupon-input-errorMsg {
width: auto;
}
}
</style>
<div class="joshine-model-warp" id="coupon-subscribe-alert" style="display: none;">
<div class="joshine-mask"></div>
<div class="j-modal j-modal-vertical">
<div class="j-modal-dialog j-modal-fluid">
<div class="j-modal-content">
<div class="j-modal-header">
<button title="Close (Esc)" type="button" class="sparsh-mfp-close" id="coupon-alert-close"></button>
</div>
<div class="j-modal-body">
<div class="coupon-alt joshine-text-center">
<img src="<?= $block->getViewFileUrl('Joshine_CouponPusher::images/coupon_background.png'); ?>" alt="" class="">
<div class="coupon-text">
<!--todo:: show config coupon-->
<p class="coupon-discount-amount"><?= $block->getCouponTitle() ?></p>
<p class="coupon-discount-rule"><?= $block->getCouponDescription() ?></p>
</div>
<div class="coupon-alt-input-title">
<?= __('Subscribe to get your exclusive offer.') ?>
</div>
<div class="coupon-alt-input">
<div class="coupon-alt-input-left">
<input placeholder="Enter your email address" type="email" id="coupon-subscribe-email-input" value="">
</div>
<div class="coupon-alert-submit-button" id="coupon-subscribe-email"><?= __('Submit') ?></div>
</div>
<div class="coupon-input-errorMsg"></div>
<div class="split-line joshine-hidden-sm joshine-hidden-xs"><span class="split-text"><?= __('Additional Information') ?></span></div>
<div class="coupon-alt-bottom-title joshine-hidden-sm joshine-hidden-xs"><span><?= $block->getInformationTitle() ?></span>
</div>
<div class="coupon-alt-bottom-text joshine-hidden-sm joshine-hidden-xs">
<?= $block->getInformationText() ?>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript">
require(['jquery'], function($) {
setTimeout(function () {
$("#coupon-subscribe-alert").show();
}, 2000);
$(document).on('click', '#coupon-alert-close', function () {
$('#coupon-subscribe-alert').hide();
});
$(document).on('click', "#coupon-subscribe-email", function(e){
var email = $("#coupon-subscribe-email-input").val();
if (email.length < 5) {
$(".coupon-input-errorMsg").html('You enter an invalid email address').show();
return;
}
var data = {
email : email
};
$.ajax({
url: '/joshine_coupon_pusher/ajax/subscribe',
data: data,
type: 'POST',
dataType: 'json',
success: function (response) {
if (response.hasOwnProperty('error')) {
$(".coupon-input-errorMsg").html(response.error).show();
return;
}
//todo::show coupon code
},
error: function () {
$(".coupon-input-errorMsg").html('error').show();
},
});
})
$(document).on('keyup','#coupon-subscribe-email-input', function(e){
$(".coupon-input-errorMsg").hide();
})
})
</script>
<script type="text/javascript">
require(['jquery','mage/cookies'], function($) {
function getCouponAlert() {
var formKey = $.mage.cookies.get('form_key');
var data = 'form_key=' + formKey;
$.ajax({
url: '/joshine_coupon_pusher/ajax/couponpusher',
data: data,
type: 'GET',
dataType: 'json',
success: function (response) {
$('body').append(response.data);
}
});
}
function couponPusherStart()
{
var stopPush = $.mage.cookies.get('coupon_push_stop');
if (stopPush == 'true') {
return
}
setTimeout(function () {
getCouponAlert();
}, 1500)
}
couponPusherStart();
})
</script>
#coupon-subscribe-alert.joshine-model-warp .j-modal .j-modal-dialog {
width: 640px;
}
#coupon-subscribe-alert .j-modal .j-modal-content {
padding: 0;
}
.coupon-alt {
position: relative;
padding-bottom: 25px;
background: #fff;
border-radius: 4px;
display: flex;
flex-direction: column;
align-items: center;
}
.coupon-alt img {
height: 142px;
margin-top: 22px;
}
.coupon-alt .coupon-text {
position: absolute;
top: 58px;
left: 0;
width: 100%;
text-align: center;
}
.coupon-alt .coupon-text .coupon-discount-amount {
font-size: 44px;
color: #66331e;
line-height: 48px;
font-weight: 700;
}
.coupon-alt .coupon-text .coupon-discount-rule {
font-size: 12px;
color: #a59176;
line-height: 18px;
}
.coupon-alt .coupon-alt-input-title {
margin-top: 4px;
margin-bottom: 14px;
height: 22px;
font-size: 18px;
color: #222;
line-height: 22px;
font-weight: 500;
}
.coupon-alt .coupon-alt-input {
width: 446px;
height: 36px;
display: flex;
border-radius: 4px;
}
.coupon-alt .coupon-alt-input .coupon-alt-input-left {
border: 1px solid #dfdfdf;
border-right-width: 0;
flex: 1;
display: flex;
align-items: center;
border-radius: 4px 0 0 4px;
}
.coupon-alt-input-left .coupon-alt-input-left-prefix {
display: flex;
align-items: center;
justify-content: center;
line-height: 16px;
font-weight: 500;
padding: 0 11px;
font-size: 14px;
color: #000;
border-right: 1px solid #dfdfdf;
}
.coupon-alt-input-left input {
height: 16px;
font-size: 13px;
color: #000;
line-height: 16px;
font-weight: 500;
width: 240px;
border: 0;
}
.coupon-alert-submit-button {
position: relative;
left: -3px;
width: 116px;
height: 36px;
background: #fb7701;
border-radius: 0 4px 4px 0;
color: #fff;
font-size: 16px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
line-height: 16px;
font-weight: 500;
}
.coupon-alt-bottom-title {
height: 16px;
font-size: 14px;
color: #222;
font-weight: 500;
margin-top: 16px;
margin-bottom: 12px;
}
.coupon-alt-bottom-text {
opacity: .9;
font-size: 11px;
color: #afafaf;
line-height: 16px;
font-weight: 400;
text-align: center;
padding: 0 60px;
}
.coupon-alt-bottom-text >a {
color: #777;
}
\ No newline at end of file
......@@ -99,29 +99,15 @@ class Related extends AbstractProduct implements IdentityInterface
{
$product = $this->getProduct();
/* @var $product Product */
$this->_itemCollection = $product->getRelatedProductCollection()->addAttributeToSelect(
'required_options'
)->setPositionOrder()->addStoreFilter();
if ($this->moduleManager->isEnabled('Magento_Checkout')) {
$this->_addProductAttributesAndPrices($this->_itemCollection);
}
$this->_itemCollection = $this->_collectionFactory->create();
$this->_itemCollection->addAttributeToSelect('*');
//$this->_itemCollection->addCategoriesFilter(['in' => $product->getCategoryIds()]);
$this->_itemCollection->setVisibility($this->_catalogProductVisibility->getVisibleInCatalogIds());
$this->_itemCollection->load();
if (!count($this->_itemCollection->getItems())){
$collection = $this->_collectionFactory->create();
$collection->addAttributeToSelect('*');
$collection->addCategoriesFilter(['in' => $product->getCategoryIds()]);
$collection->setVisibility($this->_catalogProductVisibility->getVisibleInCatalogIds());
$collection->getSelect()->order('rand()');
$collection->setPageSize(10);
$collection->addStoreFilter($product->getStoreId());
$this->_itemCollection = $collection;
}
$this->_itemCollection->getSelect()->order('rand()');
$this->_itemCollection->setPageSize(10);
$this->_itemCollection->addStoreFilter($product->getStoreId());
$this->_itemCollection->getSelect()->limit(10);
foreach ($this->_itemCollection as $product) {
$product->setDoNotUseCategoryId(true);
}
......
......@@ -197,8 +197,27 @@ class LayoutProcessor implements LayoutProcessorInterface
$fields
);
}
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
if (isset($jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
['children']['shippingAddress']['children']['after-shipping-method-form'])){
$component['billing-address-form'] = $this->getBillingAddressComponent('shared', $elements);
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
['children']['shippingAddress']['children']['after-shipping-method-form']['children'] =
array_merge_recursive(
$component,
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']
['children']['shippingAddress']['children']['after-shipping-method-form']
);
}
$jsLayout['components']['checkout']['children']['steps']['children']['shipping-step']['children']
['shippingAddress']['children']['shipping-address-fieldset']['children']['company']['sortOrder'] = 140;
file_put_contents('./yyyy.txt',json_encode($jsLayout));
return $jsLayout;
}
......
......@@ -58,7 +58,7 @@
</item>
</item>
</item>
-->
<item name="estimation" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/estimation</item>
<item name="displayArea" xsi:type="string">estimation</item>
......@@ -69,6 +69,30 @@
</item>
</item>
</item>
-->
<item name="cart_items" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/summary/cart-items</item>
<item name="displayArea" xsi:type="string">estimation</item>
<item name="children" xsi:type="array">
<item name="details" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details</item>
<item name="children" xsi:type="array">
<item name="thumbnail" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details/thumbnail</item>
<item name="displayArea" xsi:type="string">before_details</item>
</item>
<item name="subtotal" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details/subtotal</item>
<item name="displayArea" xsi:type="string">after_details</item>
</item>
<item name="message" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details/message</item>
<item name="displayArea" xsi:type="string">item_message</item>
</item>
</item>
</item>
</item>
</item>
<item name="steps" xsi:type="array">
<item name="component" xsi:type="string">uiComponent</item>
<item name="displayArea" xsi:type="string">steps</item>
......@@ -229,6 +253,13 @@
</item>
</item>
</item>
<item name="after-shipping-method-form" xsi:type="array">
<item name="component" xsi:type="string">uiComponent</item>
<item name="displayArea" xsi:type="string">after-shipping-method-form</item>
<item name="children" xsi:type="array">
<!-- address-list-additional-addresses -->
</item>
</item>
</item>
</item>
</item>
......@@ -392,30 +423,8 @@
</item>
</item>
<!--<item name="cart_items" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/summary/cart-items</item>
<item name="sortOrder" xsi:type="string">2</item>
<item name="children" xsi:type="array">
<item name="details" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details</item>
<item name="children" xsi:type="array">
<item name="thumbnail" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details/thumbnail</item>
<item name="displayArea" xsi:type="string">before_details</item>
</item>
<item name="subtotal" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details/subtotal</item>
<item name="displayArea" xsi:type="string">after_details</item>
</item>
<item name="message" xsi:type="array">
<item name="component" xsi:type="string">Magento_Checkout/js/view/summary/item/details/message</item>
<item name="displayArea" xsi:type="string">item_message</item>
</item>
</item>
</item>
</item>
</item>
-->
<item name="itemsAfter" xsi:type="array">
<item name="component" xsi:type="string">uiComponent</item>
<item name="children" xsi:type="array">
......
......@@ -119,7 +119,7 @@ $subtotalStr = $block->escapeHtml(
}
</style>
<div id="we-accept">
<div class="title">We Accept</div>
<div class="title"><?= __('We Accept') ?> </div>
<img src="/media/wysiwyg/we_accept.png" alt="">
</div>
</div>
......
......@@ -11,6 +11,6 @@
}
</style>
<div id="we-accept">
<div class="title">We Accept</div>
<div class="title"><?= __('We Accept') ?></div>
<img src="/media/wysiwyg/we_accept.png" alt="">
</div>
\ No newline at end of file
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
/**
* @api
*/
define(
[
'jquery',
'Magento_Checkout/js/model/quote',
'Magento_Checkout/js/model/url-builder',
'mage/storage-new',
'Magento_Checkout/js/model/error-processor',
'Magento_Customer/js/model/customer',
'Magento_Checkout/js/model/full-screen-loader',
'Magento_Checkout/js/action/get-payment-information'
],
function ($,
quote,
urlBuilder,
storage,
errorProcessor,
customer,
fullScreenLoader,
getPaymentInformationAction
) {
'use strict';
return function (messageContainer) {
var serviceUrl,
payload;
/**
* Checkout for guest and registered customer.
*/
if (!customer.isLoggedIn()) {
serviceUrl = urlBuilder.createUrl('/guest-carts/:cartId/billing-address', {
cartId: quote.getQuoteId()
});
payload = {
cartId: quote.getQuoteId(),
address: quote.billingAddress()
};
} else {
serviceUrl = urlBuilder.createUrl('/carts/mine/billing-address', {});
payload = {
cartId: quote.getQuoteId(),
address: quote.billingAddress()
};
}
fullScreenLoader.startLoader();
quote.responseBillStatus(null);
return storage.post(
serviceUrl, JSON.stringify(payload)
).done(
function () {
var deferred = $.Deferred();
getPaymentInformationAction(deferred);
$.when(deferred).done(function () {
fullScreenLoader.stopLoader();
});
quote.responseBillStatus(200);
}
).fail(
function (response) {
errorProcessor.process(response, messageContainer);
fullScreenLoader.stopLoader();
quote.responseBillStatus(400);
}
);
};
}
);
......@@ -32,6 +32,7 @@ define([
shippingSaveMethod = ko.observable(null),
paymentMethod = ko.observable(null),
paymentMethodlist = ko.observable(null),
responseBillStatus = ko.observable(null),
quoteData = window.checkoutConfig.quoteData,
basePriceFormat = window.checkoutConfig.basePriceFormat,
priceFormat = window.checkoutConfig.priceFormat,
......@@ -45,6 +46,7 @@ define([
shippingAddress: shippingAddress,
shippingMethod: shippingMethod,
shippingSaveMethod:shippingSaveMethod,
responseBillStatus:responseBillStatus,
billingAddress: billingAddress,
paymentMethod: paymentMethod,
paymentMethodlist:paymentMethodlist,
......@@ -121,7 +123,6 @@ define([
getShippingSaveMethod: function () {
return shippingSaveMethod;
},
setPaymentMethodList: function (MethodList) {
paymentMethodlist(MethodList);
},
......
define([
'jquery',
'uiComponent',
'Magento_Checkout/js/model/checkout-data-resolver'
], function ($, Component,checkoutDataResolver) {
'uiRegistry',
'Magento_Checkout/js/model/checkout-data-resolver',
'Magento_Checkout/js/model/quote'
], function ($, Component,registry,checkoutDataResolver,quote) {
'use strict';
var input_city = $('#co-shipping-form input[name="city"]');
if (input_city.is(':visible') && !input_city.closest('.field').hasClass('_required')) {
......@@ -39,6 +41,9 @@ define([
if (!addressForm.validate().form()) {
return false;
}
var paymentMethodObj = $('.checkout-index-index .payment-method');
if(paymentMethodObj.length < 1)
{
......@@ -58,12 +63,22 @@ define([
} else {
regin = region_select.find(":selected").text();
}
if(!registry.get('checkout.steps.shipping-step.shippingAddress.after-shipping-method-form.billing-address-form').isAddressSameAsShipping())
{
$('#submitBill').trigger('click');
if(quote.responseBillStatus() == 400)
{
return false;
}
}
$('#checkout-step-shipping').hide();
$('#shipping-text').show();
$('#shipping-text .main-address.shipping-address').html(firstname + ' ' + lastname + '<br>' + street + '<br>' + city + ', ' + regin + ', ' + country + '<br>' + postcode + ', ' + telephone + '<br>' + email);
}
$(paymentMethodObj[0]).find('input[type="radio"]').trigger('click');
$('#next-shipping').hide();
$('#edit-shipping').show();
$('#checkout-step-shipping_method').show();
$('#checkout-payment-method-load').show();
$('#checkout-step-payment,#opc-shipping_method').find('.step-title').removeClass('no-border');
......@@ -80,10 +95,41 @@ define([
$('#shipping-text').hide();
$('#checkout-step-shipping').show();
$('#next-shipping').show();
$('#edit-shipping').hide();
$('#checkout-step-shipping_method').hide();
$('#checkout-payment-method-load').hide();
$('#checkout-step-payment,#opc-shipping_method').find('.step-title').addClass('no-border');
});
$(document).on('click', '#billing-address-same-as-shipping-shared', function () {
if(!registry.get('checkout.steps.shipping-step.shippingAddress.after-shipping-method-form.billing-address-form').isAddressSameAsShipping())
{
$('#shipping-text .main-address.shipping-address').html('');
$('#checkout_place_order').removeClass('button-fix');
$('#shipping-text').hide();
$('#checkout-step-shipping').show();
$('#next-shipping').show();
$('#edit-shipping').hide();
$('#checkout-step-shipping_method').hide();
$('#checkout-payment-method-load').hide();
$('#checkout-step-payment,#opc-shipping_method').find('.step-title').addClass('no-border');
}
});
$(document).on('click', '#editLink', function () {
$('#shipping-text .main-address.shipping-address').html('');
$('#checkout_place_order').removeClass('button-fix');
$('#shipping-text').hide();
$('#checkout-step-shipping').show();
$('#next-shipping').show();
$('#edit-shipping').hide();
$('#checkout-step-shipping_method').hide();
$('#checkout-payment-method-load').hide();
$('#checkout-step-payment,#opc-shipping_method').find('.step-title').addClass('no-border');
if(!registry.get('checkout.steps.shipping-step.shippingAddress.after-shipping-method-form.billing-address-form').isAddressSameAsShipping())
{
$('#action-edit-address').trigger('click');
}
});
}
});
}
......
......@@ -70,8 +70,10 @@ define([
* @returns {*}
*/
_isAddressSameAsShipping: function () {
if(registry.get('checkout.steps.shipping-step.shippingAddress.after-shipping-method-form.billing-address-form')){
return registry.get('checkout.steps.shipping-step.shippingAddress.after-shipping-method-form.billing-address-form').isAddressSameAsShipping();
}
return true;
//return registry.get('checkout.steps.billing-step.payment.payments-list.billing-address-form-shared').isAddressSameAsShipping();
}
});
});
......@@ -8,8 +8,9 @@ define([
'Magento_Checkout/js/model/totals',
'uiComponent',
'Magento_Checkout/js/model/step-navigator',
'Magento_Checkout/js/model/quote'
], function (ko, totals, Component, stepNavigator, quote) {
'Magento_Checkout/js/model/quote',
'Magento_Catalog/js/price-utils',
], function (ko, totals, Component, stepNavigator, quote,priceUtils) {
'use strict';
var useQty = window.checkoutConfig.useQty;
......@@ -67,7 +68,12 @@ define([
this.setItems(items);
}.bind(this));
},
getFormattedPrice: function (price) {
return priceUtils.formatPrice(price, quote.getPriceFormat());
},
getGrandTotal:function(){
return this.getFormattedPrice(this.totals['grand_total']);
},
/**
* Set items to observable field
*
......
......@@ -21,11 +21,11 @@
<br/>
</each>
</div>
<div class="billing-handle">
<div class="billing-handle" style="display: none;">
<button visible="!isAddressSameAsShipping()"
type="button"
class="action action-edit-address"
click="editAddress">
click="editAddress" id="action-edit-address">
<span translate="'Edit'"></span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M19.769 9.923l-12.642 12.639-7.127 1.438 1.438-7.128 12.641-12.64 5.69 5.691zm1.414-1.414l2.817-2.82-5.691-5.689-2.816 2.817 5.69 5.692z"></path>
......
......@@ -5,15 +5,17 @@
padding: 20px 22px;
border: 1px solid #d6d6d6;
font-size: 14px;
min-height: 200px;
/*min-height: 200px;*/
position: relative;
box-sizing: border-box;
}
/*
.billing-address-box{
padding-bottom: 1rem;
border-bottom: 1px dashed #ddd;
}
*/
.billing-handle .action-edit-address {
border: none;
background: 0 0;
......@@ -30,7 +32,7 @@
fill: #666;
}
.billing-address-details {
padding: 0.5rem 0px 0.5rem 1.5rem;
padding: 0.5rem 0px 0.5rem 0rem;
}
@media (max-width: 1023px){
.action-update-cancel{
......@@ -77,7 +79,7 @@
</style>
<div class="checkout-billing-address cclt">
<div class="billing-address-same-as-shipping-block field choice" data-bind="visible: canUseShippingAddress()">
<div class="billing-address-same-as-shipping-block field choice" data-bind="visible: canUseShippingAddress()" style="padding:0;">
<input type="checkbox" name="billing-address-same-as-shipping"
data-bind="checked: isAddressSameAsShipping, click: useShippingAddress, attr: {id: 'billing-address-same-as-shipping-' + getCode($parent)}"/>
<label data-bind="attr: {for: 'billing-address-same-as-shipping-' + getCode($parent)}"><span
......@@ -91,7 +93,7 @@
<!-- ko template: 'Magento_Checkout/billing-address/form' --><!-- /ko -->
<div class="actions-toolbar action-update-cancel" style="margin-left: 0%;">
<div class="primary">
<button class="action action-update" type="button" data-bind="click: updateAddress">
<button class="action action-update" id="submitBill" type="button" data-bind="click: updateAddress">
<span data-bind="i18n: 'Update'"></span>
</button>
<button class="action action-cancel" type="button" data-bind="click: cancelAddressEdit">
......
......@@ -8,11 +8,6 @@
class="items payment-methods">
<div repeat="foreach: paymentGroupsList, item: '$group'"
class="payment-group">
<!-- ko if: showFormShared($group) -->
<!-- ko foreach: getRegion(getBillingAddressRegionName()) -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<!--/ko-->
<each args="data: getRegion($group().displayArea), as: 'method'" render=""></each>
</div>
</div>
......
......@@ -283,7 +283,7 @@ $full_free_ship = $_helper->currency($full_free, true, false);
padding: 20px 22px;
border: 1px solid #d6d6d6;
font-size: 14px;
min-height: 200px;
/*min-height: 200px;*/
position: relative;
box-sizing: border-box;
}
......@@ -297,11 +297,13 @@ $full_free_ship = $_helper->currency($full_free, true, false);
background-size: contain;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAACECAYAAABVnZHfAAAA+0lEQVQ4je3UsUrDUBTG8X9s6yZOeYMOLejgS7iIUDCrS0uH0oI+QUGdHZSsjnZw6dB3ENK1U8eCQqBjoWvkaE/4SpHgYjv0bj9yc5J7v3tukN5GGT9jcICMreFDEQFLRwK0gCyIXtLvKfGkd5aDwr+uKkbAsaMGvAElf+cc6GuB6m7szo4hU9w5ysA9UNdpTWDsS7BMn3U9mZ3EtdIlxZOiC3T8O6yeTr1axU7JPp8iJIor7zvDJ9CwjLTNwj+02aEiVrSBGyS5R03OEr/e51OEd4UFNXPMgUtgkTdT7zQONzrrd1woXoETh92UQyD0AnaXPmi1o3/ZA+ALpYA1JaK/rAEAAAAASUVORK5CYII=) repeat-y;
}
/*
.main-address.shipping-address
{
border-bottom: 1px dashed #d6d6d6;
padding-bottom: 20px;
}
*/
.address-edit{
border: none;
background: 0 0;
......@@ -375,7 +377,7 @@ $full_free_ship = $_helper->currency($full_free, true, false);
gap: 0rem;
}
.checkout-index-index .block.items-in-cart{
border-bottom: 1px solid #ddd;
display: none;
}
.checkout-index-index table tr,.checkout-index-index table tr .mark .title{
border:none;
......@@ -494,13 +496,14 @@ $full_free_ship = $_helper->currency($full_free, true, false);
height: 100%;
}
.checkout-index-index .page-wrapper a.logo{
margin-left: 35%!important;
margin-left: 0px!important;
}
.checkout-index-index div#checkout {
margin-top: 1rem;
}
.checkout-index-index .authentication-wrapper{
padding: 5px 20px;
border-bottom: 1px solid #ddd;
}
.button-fix {
width:100%!important;
......@@ -516,8 +519,38 @@ $full_free_ship = $_helper->currency($full_free, true, false);
#checkout_place_order .fix-content.button-fix .now-order-total{
display:block;
}
.checkout-index-index .block.items-in-cart{
border-bottom: 1px solid #ddd;
background-color: #fff;
margin-bottom: 1rem;
padding: 0.35rem 0rem;
display: block;
}
.checkout-index-index .block.items-in-cart .title{
padding-left:1rem;
}
.checkout-index-index .block.items-in-cart .title strong{
width:100%;
}
.checkout-index-index .block.items-in-cart .title strong .estimated-label{
width: 50%;
display: inline-block;
}
.checkout-index-index .block.items-in-cart .title strong .estimated-price{
width: 45%;
display: inline-block;
text-align: right;
}
.checkout-index-index #opc-sidebar .table-totals .totals.discount .amount .price{
color:#ff373c;
}
/***************payment end******************/
}
.checkout-index-index .payment-method-title label.label .action.action-help span {
display: none;
}
#checkout_place_order .fix-content .now-order-total{
display:none;
}
......@@ -771,6 +804,78 @@ $full_free_ship = $_helper->currency($full_free, true, false);
border-bottom: 1px solid #dcdcdc !important;
}
}
/************************************* top logo style start******************************************************/
@media(max-width:768px){
.checkout-index-index .secure-span{
display:inline-block;
}
.checkout-index-index .show-logo{
width:100%;
margin:0 auto!important;
}
.checkout-index-index .show-logo img{
vertical-align: middle;
}
.checkout-index-index .show-logo .secure-span .cut-span{
font-size:30px;
vertical-align: middle;
margin-left:0.5rem;
font-weight: lighter;
color:#777;
}
.checkout-index-index .show-logo .site-logo{
width:100px;
}
.checkout-index-index .show-logo .secure-span .logo-secure{
width:25px;min-width: 0px;
}
.checkout-index-index .show-logo .secure-span .cut-font{
color:#6fab83;
font-size: 15px;
vertical-align: text-top;
margin-left:0.5rem;
}
.checkout-index-index .header.content{
text-align: center;
}
}
@media(min-width:768px){
.checkout-index-index .secure-span{
display:inline-block;
}
.checkout-index-index .show-logo{
width:35%;
}
.checkout-index-index .show-logo img{
vertical-align: middle;
}
.checkout-index-index .show-logo .secure-span .cut-span{
font-size:50px;
vertical-align: text-bottom;
margin-left:0.9rem;
font-weight: lighter;
color:#777;
}
.checkout-index-index .show-logo .site-logo{
width:198px;
}
.checkout-index-index .show-logo .secure-span .logo-secure{
width:45px;min-width: 0px;
}
.checkout-index-index .show-logo .secure-span .cut-font{
color:#6fab83;
font-size: 26px;
vertical-align: text-top;
margin-left:0.5rem;
}
.checkout-index-index .page-header .header.content .logo{
left:35%;
}
}
/************************************* top logo style end******************************************************/
</style>
<div id="checkout" data-bind="scope:'checkout'" class="checkout-container">
<div id="checkout-loader" data-role="checkout-loader" class="loading-mask" data-mage-init='{"checkoutLoader": {}}'>
......
......@@ -4,6 +4,15 @@
* See COPYING.txt for license details.
*/
-->
<style>
#edit-shipping{
border-bottom: 1px #dddddd dashed;
text-align: right;
}
#edit-shipping svg{
vertical-align: revert;
}
</style>
<li id="shipping" class="checkout-shipping-address" data-bind="fadeVisible: visible()">
<!--<div class="step-title" translate="'Shipping Address'" data-role="title" />-->
<p class="step-title">
......@@ -14,7 +23,7 @@
</p>
<div id="checkout-step-shipping"
class="step-content"
data-role="content">
data-role="content" style="margin-bottom: 1rem;">
<each if="!quoteIsVirtual" args="getRegion('customer-email')" render="" />
<each args="getRegion('address-list')" render="" />
......@@ -46,17 +55,22 @@
<div class="confirmed-address">
<div class="main-address shipping-address">
</div>
<button class="address-edit">
<span>edit</span>
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<path d="M19.769 9.923l-12.642 12.639-7.127 1.438 1.438-7.128 12.641-12.64 5.69 5.691zm1.414-1.414l2.817-2.82-5.691-5.689-2.816 2.817 5.69 5.692z"></path>
</svg>
</button>
</div>
</div>
<div class="billing-address-form">
<each args="getRegion('after-shipping-method-form')" render="" />
</div>
<div id="next-shipping">
<span><!-- ko i18n: 'Save & Continue'--><!-- /ko --></span>
</div>
<div id="edit-shipping" style="display:none;">
<a href="javascript:;" id="editLink" style="color:#000;">
<span><!-- ko i18n: 'Edit'--><!-- /ko --></span>
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24">
<path d="M19.769 9.923l-12.642 12.639-7.127 1.438 1.438-7.128 12.641-12.64 5.69 5.691zm1.414-1.414l2.817-2.82-5.691-5.689-2.816 2.817 5.69 5.692z"></path>
</svg>
</a>
</div>
</li>
......
......@@ -4,14 +4,11 @@
* See COPYING.txt for license details.
*/
-->
<div class="block items-in-cart" data-bind="mageInit: {'collapsible':{'closeOnOuter':false,'openedState': 'active', 'active': isItemsBlockExpanded()}}">
<div class="block items-in-cart" data-bind="mageInit: {'collapsible':{'closeOnOuter':false,'openedState': 'false', 'active': false}}">
<div class="title" data-role="title">
<strong role="heading" aria-level="1">
<translate args="maxCartItemsToDisplay" if="maxCartItemsToDisplay < getCartLineItemsCount()"></translate>
<translate args="'of'" if="maxCartItemsToDisplay < getCartLineItemsCount()"></translate>
<span data-bind="text: getCartSummaryItemsCount()"></span>
<translate args="'Item in Cart'" if="getCartSummaryItemsCount() === 1"></translate>
<translate args="'Items in Cart'" if="getCartSummaryItemsCount() > 1"></translate>
<span class="estimated-label" data-bind="i18n: 'Order Summary'"></span>
<span class="estimated-price" data-bind="text: getGrandTotal()"></span>
</strong>
</div>
<div class="content minicart-items" data-role="content">
......
......@@ -8,7 +8,7 @@
?>
<div class="block newsletter">
<div class="newsletter-list">
<span>JOIN OUR LIST FOR SPECIAL OFFERS!</span>
<span><?= __('JOIN OUR LIST FOR SPECIAL OFFERS!') ?></span>
</div>
<div class="content newsletter-list sub">
<form class="form subscribe"
......
......@@ -53,17 +53,28 @@ $logoHeight = $logoSizeResolver !== null && $logoSizeResolver->getHeight()
</script>
<style>
.secure-span{
display:none;
}
</style>
<span data-action="toggle-nav" class="action nav-toggle"><span><?= $block->escapeHtml(__('Toggle Nav')) ?></span></span>
<a
class="logo"
class="logo show-logo"
href="<?= $block->escapeUrl($block->getUrl('')) ?>"
title="<?= $block->escapeHtmlAttr($storeName) ?>"
aria-label="store logo">
<img src="<?= $block->escapeUrl($block->getLogoSrc()) ?>"
<img class="site-logo" src="<?= $block->escapeUrl($block->getLogoSrc()) ?>"
title="<?= $block->escapeHtmlAttr($block->getLogoAlt()) ?>"
alt="<?= $block->escapeHtmlAttr($block->getLogoAlt()) ?>"
<?= $logoWidth ? 'width="' . $block->escapeHtmlAttr($logoWidth) . '"' : '' ?>
<?= $logoHeight ? 'height="' . $block->escapeHtmlAttr($logoHeight) . '"' : '' ?>
/>
<span class="secure-span">
<span class="cut-span" >
/
</span>
<img class="logo-secure" src="/media/wysiwyg/logo-secure.png" />
<span class="cut-font">SECURE CHECKOUT</span>
</span>
</a>
......@@ -15617,6 +15617,8 @@ OR CHECKOUT WITH,O al pagar la cuenta
Checkout Now,Pagar de inmediato
Coupon Code,Código preferencial
WHY CHOOSE US,¿¿ por qué nos eligen?
We Accept,Aceptamos
"JOIN OUR LIST FOR SPECIAL OFFERS!","¡¡ Únete a nuestra lista de preferencias!"
......@@ -1045,7 +1045,10 @@ p.shopbycate-title {
max-width:60%;
}
.checkout-index-index .authentication-wrapper {
padding: 6px 20px!important;
padding: 0.23rem 20px!important;
}
.checkout-index-index .minicart-items-wrapper > .minicart-items{
padding: 0 0.45rem 0.375rem;
}
}
......
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
define(['jquery', 'mage/url'], function ($, urlBuilder) {
'use strict';
return {
/**
* Perform asynchronous GET request to server.
* @param {String} url
* @param {Boolean} global
* @param {String} contentType
* @param {Object} headers
* @returns {Deferred}
*/
get: function (url, global, contentType, headers) {
headers = headers || {};
global = global === undefined ? true : global;
contentType = contentType || 'application/json';
return $.ajax({
url: urlBuilder.build(url),
type: 'GET',
global: global,
contentType: contentType,
headers: headers
});
},
/**
* Perform asynchronous POST request to server.
* @param {String} url
* @param {String} data
* @param {Boolean} global
* @param {String} contentType
* @param {Object} headers
* @param {String} async
* @returns {Deferred}
*/
post: function (url, data, global, contentType, headers, async) {
headers = headers || {};
global = global === undefined ? true : global;
async = async === undefined ? false : async;
contentType = contentType || 'application/json';
return $.ajax({
url: urlBuilder.build(url),
type: 'POST',
data: data,
global: global,
contentType: contentType,
headers: headers,
async:async
});
},
/**
* Perform asynchronous PUT request to server.
* @param {String} url
* @param {String} data
* @param {Boolean} global
* @param {String} contentType
* @param {Object} headers
* @returns {Deferred}
*/
put: function (url, data, global, contentType, headers) {
var ajaxSettings = {};
headers = headers || {};
global = global === undefined ? true : global;
contentType = contentType || 'application/json';
ajaxSettings.url = urlBuilder.build(url);
ajaxSettings.type = 'PUT';
ajaxSettings.data = data;
ajaxSettings.global = global;
ajaxSettings.contentType = contentType;
ajaxSettings.headers = headers;
return $.ajax(ajaxSettings);
},
/**
* Perform asynchronous DELETE request to server.
* @param {String} url
* @param {Boolean} global
* @param {String} contentType
* @param {Object} headers
* @returns {Deferred}
*/
delete: function (url, global, contentType, headers) {
headers = headers || {};
global = global === undefined ? true : global;
contentType = contentType || 'application/json';
return $.ajax({
url: urlBuilder.build(url),
type: 'DELETE',
global: global,
contentType: contentType,
headers: headers
});
}
};
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment