Commit 76ddf55d by dhn

Merge branch 'developer' of http://47.99.244.21:9999/root/joshine into Branch_developer

parents 8cccfe0b 4b1514eb
<?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,
'coupon_code' => $this->getCouponCode()
];
} 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.');
}
private function getCouponCode()
{
return $this->_objectManager->get(ScopeConfigInterface::class)
->getValue(
'joshine_coupon_pusher/general/newsletter_coupon_code',
ScopeInterface::SCOPE_STORE
);
}
}
<?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;
}
}
.coupon-wrapper {
transition: all 1s;
perspective: 1000px;
}
.coupon-back {
position: absolute;
}
.coupon-wrapper .coupon-front {
backface-visibility: hidden;
}
.coupon-wrapper .coupon-back {
position: absolute;
top: 0;
transform: rotateY(-180deg);
backface-visibility: hidden;
}
.coupon-wrapper.flipping .coupon-front {
transition: all 2s;
transform: rotateY(180deg);
}
.coupon-wrapper.flipping .coupon-back {
transition: all 2s;
display: block;
transform: rotateY(0deg);
}
.coupon-shopping-now-button {
position: relative;
padding: 1em;
height: 36px;
background: #fb7701;
border-radius: 4px;
color: #fff;
font-size: 16px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
line-height: 16px;
font-weight: 500;
}
</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">
<div class="coupon-wrapper">
<div class="coupon-front">
<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>
<div class="coupon-back">
<img src="<?= $block->getViewFileUrl('Joshine_CouponPusher::images/coupon_background.png'); ?>" alt="">
<div class="coupon-text">
<p class="coupon-discount-amount" id="flipping-coupon-code"></p>
</div>
</div>
</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-shopping-now" style="display: none;">
<div class="coupon-shopping-now-button"><a href="/"><?= __('Shopping Now') ?></a></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;
}
$("#flipping-coupon-code").html(response.coupon_code);
$(".coupon-wrapper").addClass("flipping");
$(".coupon-alt-input-title").html("Thank your Subscribe!")
$(".coupon-alt-input").hide();
$(".coupon-shopping-now").show();
},
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: 580px;
}
#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
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