Commit eca77d37 by liumengfei

Merge branch 'developer' into production

parents 98f5d87c 795d1019
<?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
......@@ -6,6 +6,7 @@
*/
namespace Joshine\CouponPusher\Controller\Ajax;
use Joshine\CouponPusher\Helper\CustomerChecker;
use Magento\Customer\Api\AccountManagementInterface as CustomerAccountManagement;
use Magento\Customer\Model\Session;
use Magento\Customer\Model\Url as CustomerUrl;
......@@ -50,6 +51,8 @@ class Subscribe extends SubscriberController implements HttpPostActionInterface
private $resultJsonFactory;
private $customerChecker;
/**
* Initialize dependencies.
*
......@@ -71,12 +74,14 @@ class Subscribe extends SubscriberController implements HttpPostActionInterface
CustomerAccountManagement $customerAccountManagement,
SubscriptionManagerInterface $subscriptionManager,
EmailValidator $emailValidator = null,
CustomerChecker $customerChecker,
JsonFactory $jsonFactory
) {
$this->customerAccountManagement = $customerAccountManagement;
$this->subscriptionManager = $subscriptionManager;
$this->emailValidator = $emailValidator ?: ObjectManager::getInstance()->get(EmailValidator::class);
$this->resultJsonFactory = $jsonFactory;
$this->customerChecker = $customerChecker;
parent::__construct(
$context,
$subscriberFactory,
......@@ -184,6 +189,7 @@ class Subscribe extends SubscriberController implements HttpPostActionInterface
'data' => $message,
'coupon_code' => $this->getCouponCode()
];
$this->setSubscribeCookie();
} catch (LocalizedException $e) {
$message = ['error' => $e->getMessage()];
} catch (\Exception $e) {
......@@ -240,4 +246,9 @@ class Subscribe extends SubscriberController implements HttpPostActionInterface
ScopeInterface::SCOPE_STORE
);
}
private function setSubscribeCookie()
{
$this->customerChecker->setSubscribeCookie();
}
}
......@@ -2,6 +2,17 @@
namespace Joshine\CouponPusher\Helper;
class Constant {
const FIRST_VISITOR = 'first_visitor';
const OTHER = 'other';
const FIRST_VISITOR = 'first_visitor';
const HAS_SUBSCRIBE = 'has_subscribe';
const STOP_COUPON_PUSH = 'coupon_push_stop';
const NOT_SUBSCRIBE = 'not_subscribe';
const HAS_SUBSCRIBE_COOKIE_DURATION = 86400 * 365;
const HAS_VISITED_COOKIE_KEY = 'has_visited';
const HAS_VISITED_COOKIE_DURATION = 86400 * 365;
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;
......@@ -29,28 +28,54 @@ class CustomerChecker implements \Magento\Framework\Data\CollectionDataSourceInt
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;
return is_null($this->_cookieManager->getCookie(Constant::HAS_VISITED_COOKIE_KEY));
}
public function setFirstVisitCookie()
{
$this->setCookie(Constant::HAS_VISITED_COOKIE_KEY, 'true', Constant::HAS_VISITED_COOKIE_DURATION);
}
public function checkSubscribed(): bool
{
return !is_null($this->_cookieManager->getCookie(Constant::HAS_SUBSCRIBE));
}
public function setSubscribeCookie()
{
$this->setCookie(Constant::HAS_SUBSCRIBE, 'true', Constant::HAS_SUBSCRIBE_COOKIE_DURATION);
}
public function setCookie($key, $data, $time)
{
$metadata = $this->_cookieMetadataFactory
->createPublicCookieMetadata()
->setPath('/')
->setDuration($time);
$this->_cookieManager->setPublicCookie(
$key,
$data,
$metadata
);
}
//访客细分
public function getCustomerSegments(): string
{
if ($this->checkFirstVisit()) {
$this->setFirstVisitCookie();
return Constant::FIRST_VISITOR;
}
if (!$this->checkSubscribed()) {
return Constant::NOT_SUBSCRIBE;
}
if ($this->checkSubscribed()) {
return Constant::HAS_SUBSCRIBE;
}
return Constant::OTHER;
}
}
......@@ -5,8 +5,8 @@ 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 Joshine\CouponPusher\Model\Strategy\SubscribePushStrategy;
use Joshine\CouponPusher\Model\Strategy\StopPushStrategy;
use Magento\Framework\ObjectManagerInterface;
class PushStrategyManager
......@@ -26,10 +26,18 @@ class PushStrategyManager
public function tagToStrategy($tag): string
{
$map = [
Constant::FIRST_VISITOR => FirstVisitorPushStrategy::class,
//第一次访问推送订阅券
Constant::FIRST_VISITOR => SubscribePushStrategy::class,
//未订阅,持续推送订阅券
Constant::NOT_SUBSCRIBE => SubscribePushStrategy::class,
//已订阅停止推送
Constant::HAS_SUBSCRIBE => StopPushStrategy::class,
];
if (!isset($map[$tag])) {
return NopePushStrategy::class;
return StopPushStrategy::class;
}
return $map[$tag];
}
......
......@@ -4,7 +4,7 @@ namespace Joshine\CouponPusher\Model\Strategy;
use Joshine\CouponPusher\Block\CouponNopeAlert;
class NopePushStrategy implements ContractPushStrategy
class StopPushStrategy implements ContractPushStrategy
{
/**
......
......@@ -3,23 +3,37 @@
namespace Joshine\CouponPusher\Model\Strategy;
use Joshine\CouponPusher\Block\CouponSubscribeAlert;
use Joshine\CouponPusher\Helper\Constant;
use Joshine\CouponPusher\Helper\CustomerChecker;
class FirstVisitorPushStrategy implements ContractPushStrategy
class SubscribePushStrategy implements ContractPushStrategy
{
/**
* @var \Magento\Framework\View\Element\BlockFactory
*/
private $blockFactory;
private $customerChecker;
public function __construct(
\Magento\Framework\View\Element\BlockFactory $blockFactory
\Magento\Framework\View\Element\BlockFactory $blockFactory,
CustomerChecker $customerChecker
)
{
$this->blockFactory = $blockFactory;
$this->customerChecker = $customerChecker;
}
public function push()
{
//停推10分钟
$this->stopPushTerm();
return $this->blockFactory->createBlock(CouponSubscribeAlert::class)->toHtml();
}
public function stopPushTerm()
{
$this->customerChecker->setCookie(Constant::STOP_COUPON_PUSH, 'true', 60 * 10);
}
}
\ No newline at end of file
......@@ -216,8 +216,8 @@ class ReviewInfo extends \Magento\Framework\App\Action\Action {
$res = [];
foreach ($collect->getItems() as $item) {
$res['full'][] = ['url'=>$block->getFullImagePath($item), 'image_id'=>$item->getId()] ;
$res['thumb'][] = ['url'=>$block->getResizedImagePathByLimit($item, 100), 'image_id'=>$item->getId()] ; ;
$res['full'][] = ['url'=>$block->getResizedImagePathByLimit($item, 400), 'image_id'=>$item->getId()] ;
$res['thumb'][] = ['url'=>$block->getResizedImagePathByLimit($item, 80), 'image_id'=>$item->getId()] ; ;
}
return $res;
}
......
......@@ -65,6 +65,12 @@ class ProductFirstImageAsBaseFixer extends Command
return;
}
$lastImage = $this->imageQueryResource->getLastImage($productId);
if ($mainImage != $lastImage) {
$output->writeln('base image not last, break');
return;
}
if ($mainImage != $firstImage) {
$output->writeln('fix product ' . $mainImage . ' product id: ' . $productId);
//change main image
......
......@@ -109,4 +109,23 @@ class ImageQueryResource
);
}
public function getLastImage($productId)
{
$select = $this->resourceConnection->getConnection()->select();
$select->from(['v' => $this->resourceConnection->getTableName('catalog_product_entity_media_gallery_value')]);
$select->join(
['g' => 'catalog_product_entity_media_gallery'],
'g.value_id=v.value_id',
[]
);
$select->where('entity_id=?', $productId);
$select->reset(\Magento\Framework\DB\Select::COLUMNS);
$select->columns(['g.value', 'v.position']);
$select->order('v.position DESC');
$select->limit(1);
return $this->resourceConnection->getConnection()->fetchOne($select);
}
}
\ No newline at end of file
......@@ -95,8 +95,9 @@ class Totals extends Bar
$totals = $collection->getFirstItem();
$this->addTotal(__('Revenue'), $totals->getRevenue());
$this->addTotal(__('Tax'), $totals->getTax());
$this->addTotal(__('Grand Total'), ($totals->getRevenue() + $totals->getShipping()));
$this->addTotal(__('Revenue'), $totals->getRevenue() );
//$this->addTotal(__('Tax'), $totals->getTax());
$this->addTotal(__('Shipping'), $totals->getShipping());
$this->addTotal(__('Quantity'), $totals->getQuantity() * 1, true);
......
......@@ -143,7 +143,7 @@ else
data-mage-init='{"shoppingCart":{"emptyCartButton": ".action.clear",
"updateCartActionContainer": "#update_cart_action_container"}}'>
<caption class="table-caption"><?= $block->escapeHtml(__('Shopping Cart Items')) ?></caption>
<thead><td><div class="item-summary"><?= $block->escapeHtml(__('Item Summary')) ?></div></td></thead>
<thead><td colspan="4"><div class="item-summary"><?= $block->escapeHtml(__('Item Summary')) ?></div></td></thead>
<tr>
<td class="col item first" scope="col"><span><?= $block->escapeHtml(__('Item')) ?></span></td>
<td class="col price" scope="col"><span><?= $block->escapeHtml(__('Price')) ?></span></td>
......@@ -221,7 +221,9 @@ require(['jquery'], function ($) {
var fixHeight = $('.area-blk-notitle').height();
$(window).scroll(function () {
$(window).scroll(function () {
if($('.area-blk-notitle').length < 1){
return false;
}
var scrollTop = $(document).scrollTop();
var fixTop = $('.area-blk-notitle').offset().top;
var tableTop = $('#shopping-cart-table').offset().top;
......
......@@ -54,7 +54,7 @@ $subtotalStr = $block->escapeHtml(
<div class="now-grand-total" style="font-size: 18px;width:100%;">
<div style="float: left;text-align: left;"><strong>Order Total:</strong></div>
<div style="float: right;text-align: right;"><?= $subtotalStr ?></div>
<div style="float: right;text-align: right;" id="now-grand-total"><?= $subtotalStr ?></div>
</div>
......
......@@ -33,6 +33,7 @@ define([
paymentMethod = ko.observable(null),
paymentMethodlist = ko.observable(null),
responseBillStatus = ko.observable(null),
billAddressMent = ko.observable(null),
quoteData = window.checkoutConfig.quoteData,
basePriceFormat = window.checkoutConfig.basePriceFormat,
priceFormat = window.checkoutConfig.priceFormat,
......@@ -47,6 +48,7 @@ define([
shippingMethod: shippingMethod,
shippingSaveMethod:shippingSaveMethod,
responseBillStatus:responseBillStatus,
billAddressMent:billAddressMent,
billingAddress: billingAddress,
paymentMethod: paymentMethod,
paymentMethodlist:paymentMethodlist,
......
......@@ -43,6 +43,7 @@ define([
var lastSelectedBillingAddress = null,
setCurrentBillingAddress = null,
getCurrentBillingAddress = null,
addressUpadated = false,
addressEdited = false,
countryData = customerData.get('directory-data'),
......@@ -81,7 +82,7 @@ define([
this._super()
.observe({
selectedAddress: null,
isAddressDetailsVisible: quote.billingAddress() != null,
isAddressDetailsVisible: getCurrentBillingAddress == null,
isAddressFormVisible: !customer.isLoggedIn() || !addressOptions.length,
isAddressSameAsShipping: true,
saveInAddressBook: 1
......@@ -94,8 +95,6 @@ define([
this.saveInAddressBook(1);
}
setCurrentBillingAddress = quote.billingAddress();
this.isAddressDetailsVisible(true);
}, this);
return this;
......@@ -113,8 +112,17 @@ define([
return address.getAddressInline();
},
currentBillingAddress:function(){
if(getCurrentBillingAddress)
{
return getCurrentBillingAddress;
}
return setCurrentBillingAddress;
},
billAddressMent: function(){
return quote.billAddressMent();
},
/**
* @return {Boolean}
*/
......@@ -164,6 +172,7 @@ define([
// New address must be selected as a billing address
selectBillingAddress(newBillingAddress);
setCurrentBillingAddress = newBillingAddress;
getCurrentBillingAddress = newBillingAddress;
checkoutData.setSelectedBillingAddress(newBillingAddress.getKey());
checkoutData.setNewCustomerBillingAddress(addressData);
}
......
......@@ -47,6 +47,7 @@ define([
email: true
}
},
quoteIsVirtual: quote.isVirtual(),
checkDelay: 2000,
checkRequest: null,
isEmailCheckComplete: null,
......
......@@ -7,6 +7,7 @@ define([
], 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')) {
input_city.attr('required',true);
input_city.attr('_required',true);
......@@ -19,9 +20,14 @@ define([
},
initStep: function () {
$(document).on('click', '#next-shipping>span', function () {
$('#next-shipping>span').addClass('pleaseWait');
setTimeout(function(){
$('#next-shipping>span').removeClass("pleaseWait");
}, 600);
var loginForm = $('.form.form-login');
var addressForm = $('#checkout-step-shipping>#co-shipping-form');
if (loginForm.length > 0 && !loginForm.validate().form()) {
if (loginForm.length > 0 && !loginForm.validates().form()) {
return false;
}
if (addressForm.length > 0) {
......@@ -38,12 +44,27 @@ define([
if (region_select.is(':visible') && region_select.closest('.field').hasClass('_required')) {
region_select.attr('required',true);
}
if (!addressForm.validate().form()) {
var selectInput = $('#shipping-new-address-form .select-input');
if(selectInput.length > 0){
for(var i=0;i<selectInput.length;i++){
var selectName = $(selectInput[i]).next('select').attr('name');
$(selectInput[i]).attr('name',selectName)
}
}
if (!addressForm.validates().form()) {
if(selectInput.length > 0){
for(var i=0;i<selectInput.length;i++){
$(selectInput[i]).removeAttr('name')
}
}
return false;
}
if(selectInput.length > 0){
for(var i=0;i<selectInput.length;i++){
$(selectInput[i]).removeAttr('name')
}
}
var paymentMethodObj = $('.checkout-index-index .payment-method');
if(paymentMethodObj.length < 1)
{
......@@ -65,6 +86,50 @@ define([
}
if(!registry.get('checkout.steps.shipping-step.shippingAddress.after-shipping-method-form.billing-address-form').isAddressSameAsShipping())
{
var billadressForm = $('.checkout-billing-address form');
if(billadressForm.length > 0)
{
if (!$('.checkout-billing-address input[name="region"]').closest('.field').hasClass('_required')) {
$('.checkout-billing-address input[name="region"]').removeAttr('required');
}
if (!$('.checkout-billing-address input[name="street[1]"]').closest('.field').hasClass('_required')) {
$('.checkout-billing-address input[name="street[1]"]').removeAttr('required');
}
if (!$('.checkout-billing-address input[name="company"]').closest('.field').hasClass('_required')) {
$('.checkout-billing-address input[name="company"]').removeAttr('required');
}
var region_select = $('.checkout-billing-address select[name="region_id"]');
if (region_select.is(':visible') && region_select.closest('.field').hasClass('_required')) {
region_select.attr('required',true);
}
var selectInput = $('.checkout-billing-address .select-input');
if(selectInput.length > 0){
for(var i=0;i<selectInput.length;i++){
var selectName = $(selectInput[i]).next('select').attr('name');
$(selectInput[i]).attr('name',selectName)
}
}
if (!billadressForm.validates().form()) {
if(selectInput.length > 0){
for(var i=0;i<selectInput.length;i++){
$(selectInput[i]).removeAttr('name')
}
}
return false;
}
if(selectInput.length > 0){
for(var i=0;i<selectInput.length;i++){
$(selectInput[i]).removeAttr('name')
}
}
}else {
return false;
}
$('#submitBill').trigger('click');
if(quote.responseBillStatus() == 400)
{
......@@ -87,6 +152,7 @@ define([
$('html,body').animate({scrollTop: scrollTop}, 'fast');
}
checkoutDataResolver.resolveEstimationAddress();
quote.billAddressMent(true);
});
$(document).on('click', '#shipping-text .address-edit', function () {
......@@ -129,7 +195,9 @@ define([
{
$('#action-edit-address').trigger('click');
}
quote.billAddressMent(false);
});
}
});
}
......
......@@ -72,7 +72,7 @@ define([
return priceUtils.formatPrice(price, quote.getPriceFormat());
},
getGrandTotal:function(){
return this.getFormattedPrice(this.totals['grand_total']);
return this.getFormattedPrice(this.totals['base_subtotal']);
},
/**
* Set items to observable field
......
......@@ -5,8 +5,9 @@
define([
'Magento_Checkout/js/view/summary/abstract-total',
'Magento_Checkout/js/model/quote'
], function (Component, quote) {
'Magento_Checkout/js/model/quote',
'jquery'
], function (Component, quote,$) {
'use strict';
return Component.extend({
......@@ -38,7 +39,9 @@ define([
* @return {*|String}
*/
getValue: function () {
return this.getFormattedPrice(this.getPureValue());
var price = this.getFormattedPrice(this.getPureValue());
$('#now-grand-total').html(price)
return price;
}
});
});
......@@ -4,7 +4,7 @@
* See COPYING.txt for license details.
*/
-->
<div if="isAddressDetailsVisible() && currentBillingAddress()" class="billing-address-details">
<div if="isAddressDetailsVisible() && currentBillingAddress() && billAddressMent()" class="billing-address-details">
<div class="billing-box">
<div class="billing-address-box">
<text args="currentBillingAddress().prefix"></text> <text args="currentBillingAddress().firstname"></text>
......
......@@ -11,17 +11,19 @@
role="tabpanel"
aria-hidden="false">
<!-- ko if: (quoteIsVirtual) -->
<!-- ko foreach: getRegion('customer-email') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<!-- ko foreach: getRegion('customer-email') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!--/ko-->
<!--/ko-->
<form id="co-payment-form" class="form payments" novalidate="novalidate">
<input data-bind='attr: {value: getFormKey()}' type="hidden" name="form_key"/>
<fieldset class="fieldset">
<p class="step-title no-border">
<!-- ko ifnot: (quoteIsVirtual) -->
<span class="number">
<span translate="'3'" />
</span>
<!--/ko-->
<span translate="'Payment Method'" />
</p>
......@@ -30,11 +32,22 @@
<!-- ko foreach: getRegion('beforeMethods') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
<!-- ko if: (quoteIsVirtual) -->
<div id="checkout-payment-method-load" class="opc-payment" data-bind="visible: isPaymentMethodsAvailable">
<!-- ko foreach: getRegion('payment-methods-list') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
</div>
<!--/ko-->
<!-- ko ifnot: (quoteIsVirtual) -->
<div id="checkout-payment-method-load" class="opc-payment dispay-solid" data-bind="visible: isPaymentMethodsAvailable">
<!-- ko foreach: getRegion('payment-methods-list') -->
<!-- ko template: getTemplate() --><!-- /ko -->
<!-- /ko -->
</div>
<!--/ko-->
<div class="no-quotes-block" data-bind="visible: isPaymentMethodsAvailable() == false">
<!-- ko i18n: 'No Payment method available.'--><!-- /ko -->
</div>
......
......@@ -30,6 +30,7 @@ var config = {
},
paths: {
'jquery/validate': 'jquery/jquery.validate',
'jquery/validates': 'jquery/jquery.validates',
'jquery/hover-intent': 'jquery/jquery.hoverIntent',
'jquery/file-uploader': 'jquery/fileUploader/jquery.fileuploader',
'prototype': 'legacy-build.min',
......
......@@ -8,8 +8,9 @@
*/
define([
'underscore',
'uiCollection'
], function (_, Collection) {
'uiCollection',
'jquery'
], function (_, Collection,$) {
'use strict';
return Collection.extend({
......@@ -104,6 +105,18 @@ define([
*/
getPreview: function () {
return this.elems.map('getPreview');
},
getStreetState: function () {
if(this.elems()[0].value._latestValue == '' && this.elems()[0].initialValue == ''){
return false;
}
return true;
},
/**
* Updates data from server.
*/
isCheckoutIndex: function () {
return $('body').hasClass('checkout-index-index');
}
});
});
......@@ -11,8 +11,9 @@ define([
'mageUtils',
'uiLayout',
'uiElement',
'Magento_Ui/js/lib/validation/validator'
], function (_, utils, layout, Element, validator) {
'Magento_Ui/js/lib/validation/validator',
'jquery'
], function (_, utils, layout, Element, validator,$) {
'use strict';
return Element.extend({
......@@ -482,6 +483,13 @@ define([
}
return id;
},
/**
* Updates data from server.
*/
isCheckoutIndex: function () {
return $('body').hasClass('checkout-index-index');
}
});
});
......@@ -11,8 +11,9 @@ define([
'mageUtils',
'uiRegistry',
'./abstract',
'uiLayout'
], function (_, utils, registry, Abstract, layout) {
'uiLayout',
'jquery'
], function (_, utils, registry, Abstract, layout,$) {
'use strict';
var inputNode = {
......@@ -310,6 +311,9 @@ define([
}
return this._super();
},
showNewSelect: function(){
return $('body').hasClass('checkout-index-index');
}
});
});
......@@ -356,6 +356,13 @@ define([
makeRequest(this.params, this.data, this.reloadUrl).then(function (data) {
app(data, true);
});
},
/**
* Updates data from server.
*/
isCheckoutIndex: function () {
return $('body').hasClass('checkout-index-index');
}
});
});
......@@ -13,6 +13,7 @@ define([
'moment',
'tinycolor',
'jquery/validate',
'jquery/validates',
'mage/translate'
], function ($, _, utils, moment, tinycolor) {
'use strict';
......
......@@ -4,6 +4,7 @@
* See COPYING.txt for license details.
*/
-->
<!-- ko ifnot: isCheckoutIndex() -->
<select class="select" data-bind="
attr: {
name: inputName,
......@@ -26,3 +27,31 @@
}
}"
></select>
<!-- /ko -->
<!-- ko if: isCheckoutIndex() -->
<input class="input-text select-input" type="text" data-bind="value: getPreview(),attr: {
'aria-required': required
}" required readonly="readonly"/>
<select class="select check-select" data-bind="
attr: {
name: inputName,
id: uid,
disabled: disabled,
'aria-describedby': getDescriptionId(),
'aria-required': required,
'aria-invalid': error() ? true : 'false',
placeholder: placeholder
},
hasFocus: focused,
optgroup: options,
value: value,
optionsCaption: caption,
optionsValue: 'value',
optionsText: 'label',
optionsAfterRender: function(option, item) {
if (item && item.disabled) {
ko.applyBindingsToNode(option, {attr: {disabled: true}}, item);
}
}"></select>
<!-- /ko -->
\ No newline at end of file
......@@ -4,9 +4,12 @@
* See COPYING.txt for license details.
*/
-->
<!-- ko ifnot: isCheckoutIndex() -->
<div class="field" data-bind="visible: visible, attr: {'name': element.dataScope}, css: additionalClasses">
<label class="label" data-bind="attr: { for: element.uid }"><!-- ko if: element.label --><span translate="element.label"></span><!-- /ko --></label>
<label class="label" data-bind="attr: { for: element.uid }">
<!-- ko if: element.label --><span translate="element.label"></span><!-- /ko -->
</label>
<div class="control" data-bind="css: {'_with-tooltip': element.tooltip}">
<!-- ko ifnot: element.hasAddons() -->
......@@ -50,3 +53,36 @@
<!-- /ko -->
</div>
</div>
<!-- /ko -->
<!-- ko if: isCheckoutIndex() -->
<div class="field" data-bind="visible: visible, attr: {'name': element.dataScope}, css: additionalClasses">
<label class="label" data-bind="attr: { for: element.uid },css: {'fouse-label': element.value}">
<!-- ko if: element.label --><span translate="element.label"></span><!-- /ko -->
</label>
<div class="control" data-bind="css: {'_with-tooltip': element.tooltip}">
<!-- ko ifnot: element.hasAddons() -->
<!-- ko template: element.elementTmpl --><!-- /ko -->
<!-- /ko -->
<!-- ko if: element.hasAddons() -->
<div class="control-addon">
<!-- ko template: element.elementTmpl --><!-- /ko -->
<!-- ko if: element.addbefore -->
<label class="addon-prefix" data-bind="attr: { for: element.uid }"><span data-bind="text: element.addbefore"></span></label>
<!-- /ko -->
<!-- ko if: element.addafter -->
<label class="addon-suffix" data-bind="attr: { for: element.uid }"><span data-bind="text: element.addafter"></span></label>
<!-- /ko -->
</div>
<!-- /ko -->
<!-- ko if: element.tooltip -->
<!-- ko template: element.tooltipTpl --><!-- /ko -->
<!-- /ko -->
</div>
</div>
<!-- /ko -->
\ No newline at end of file
......@@ -4,6 +4,7 @@
* See COPYING.txt for license details.
*/
-->
<!-- ko ifnot: isCheckoutIndex() -->
<fieldset class="field" data-bind="css: additionalClasses">
<legend class="label">
<span translate="element.label"></span>
......@@ -11,26 +12,51 @@
<div class="control">
<!-- ko foreach: { data: elems, as: 'element' } -->
<!-- ko if: element.visible() -->
<!-- ko if: element.visible() -->
<!-- ko ifnot: (element.input_type == 'checkbox' || element.input_type == 'radio') -->
<!-- ko template: $parent.fieldTemplate --><!-- /ko -->
<!-- /ko -->
<!-- ko ifnot: (element.input_type == 'checkbox' || element.input_type == 'radio') -->
<!-- ko template: $parent.fieldTemplate --><!-- /ko -->
<!-- /ko -->
<!-- ko if: (element.input_type == 'checkbox' || element.input_type == 'radio') -->
<!-- ko template: element.elementTmpl --><!-- /ko -->
<!-- /ko -->
<!-- ko if: (element.input_type == 'checkbox' || element.input_type == 'radio') -->
<!-- ko template: element.elementTmpl --><!-- /ko -->
<!-- /ko -->
<!-- /ko -->
<!-- /ko -->
<!-- /ko -->
<!-- ko if: validateWholeGroup -->
<!-- ko foreach: { data: elems, as: 'element' } -->
<!-- ko if: element.error() && element.visible() -->
<label class="error" data-bind="attr: { for: uid }, text: element.error"></label>
<!-- /ko -->
<!-- ko if: element.error() && element.visible() -->
<label class="error" data-bind="attr: { for: uid }, text: element.error"></label>
<!-- /ko -->
<!-- /ko -->
<!-- /ko -->
</div>
</fieldset>
<!-- /ko -->
<!-- ko if: isCheckoutIndex() -->
<fieldset class="field" data-bind="css: additionalClasses">
<legend class="label" data-bind="css: {'fouse-label': getStreetState()}">
<span translate="element.label"></span>
</legend>
<div class="control">
<!-- ko foreach: { data: elems, as: 'element' } -->
<!-- ko if: element.visible() -->
<!-- ko ifnot: (element.input_type == 'checkbox' || element.input_type == 'radio') -->
<!-- ko template: $parent.fieldTemplate --><!-- /ko -->
<!-- /ko -->
<!-- ko if: (element.input_type == 'checkbox' || element.input_type == 'radio') -->
<!-- ko template: element.elementTmpl --><!-- /ko -->
<!-- /ko -->
<!-- /ko -->
<!-- /ko -->
</div>
</fieldset>
<!-- /ko -->
\ No newline at end of file
......@@ -271,7 +271,7 @@ $full_free_ship = $_helper->currency($full_free, true, false);
}
/****************************************payment begin********************************************************/
#checkout-step-shipping_method,#checkout-payment-method-load{
#checkout-step-shipping_method,.dispay-solid{
display:none;
}
#shipping-text{
......@@ -871,10 +871,107 @@ $full_free_ship = $_helper->currency($full_free, true, false);
.checkout-index-index .page-header .header.content .logo{
left:35%;
}
.checkout-index-index .form-shipping-address{
margin-top:2rem;
}
}
.checkout-index-index #shipping .field.street {
min-height:7rem;
}
.checkout-index-index #shipping .field.street .field.additional .control input[type="text"] {
padding:0;
}
.checkout-index-index #shipping .field.street .control{
border:none;
}
.checkout-index-index #shipping .field.street .control .field .control{
border: 1px solid #ddd;
}
.checkout-index-index #shipping .field.field-select-billing .control{
border:none;
}
.checkout-index-index .opc .field-select-billing .label{
border-bottom: none;
}
.checkout-index-index .select-style{
height:3rem;
z-index:2;
transition: all .3s ease;
border:1px solid #ddd;
}
.checkout-index-index .error-border-style{
border:1px solid #fa320f!important;
}
.checkout-index-index .select-input{
cursor: pointer;
}
.fieldset.address .check-select{
z-index:2;
display:none;
}
.checkout-index-index #customer-password{
height: 50px;
outline: none;
text-indent: 10px;
padding: 18px 0 0;
border: none;
color: #515151;
background: 0 0;
}
/************************************* top logo style end******************************************************/
/********************************************address from end****************************************************/
#shipping .field{
position: relative;
}
#shipping .field .label{
position: absolute;
z-index: 1;
top:15px;
line-height: 18px;
transition: all .3s ease;
margin-left:0.5rem;
}
#shipping .field .control {
height:50px;
border:1px solid #ddd;
}
#shipping .field.required .label::before, #shipping .field._required .label::before {
content: '*';
color: rgba(var(--danger-color), var(--danger-alpha, 1));
}
#shipping .field.required .label::after, #shipping .field._required .label::after {
content: '';
}
#shipping .field ._with-tooltip .field-tooltip {
/*position: static;*/
vertical-align: middle;
}
#shipping .field .control input[type="text"],#maincontent input[type="email"] {
height: 50px;
outline: none;
text-indent: 10px;
padding: 18px 0 0;
border: none;
color: #515151;
background: 0 0;
}
#shipping .fouse-label{
top:5px!important;
}
.pleaseWait{
transition: all .3s ease;
box-shadow: 0 0 50px rgba(0,0,0,0.8);
}
#customer-email-fieldset .virtual-email{
border:1px solid #ddd!important;
padding: 0!important;
}
/********************************************address from end****************************************************/
</style>
<div id="checkout" data-bind="scope:'checkout'" class="checkout-container">
......@@ -953,5 +1050,113 @@ script;
});
}
$(document).on('focus', '#shipping input[type="email"],#shipping input[type="password"],#shipping input[type="text"]', function () {
if($(this).hasClass('select-input'))
{
return false;
}
if(!$(this).parent().prev('label').hasClass('fouse-label')){
$(this).parent().prev('label').addClass('fouse-label')
}
});
$(document).on('blur', '#shipping input[type="email"],#shipping input[type="password"],#shipping input[type="text"]', function () {
if($(this).hasClass('select-input'))
{
return false;
}
if($(this).parent().prev('label').hasClass('fouse-label')){
if($(this).val() == ''){
$(this).parent().prev('label').removeClass('fouse-label')
}
}
if($(this).attr('aria-required') == 'true')
{
var thisVal = $(this).val();
if(thisVal === '' || thisVal == null || thisVal.length === 0 || /^\s+$/.test(thisVal))
{
$(this).addClass('error-border-style')
}
else if($(this).hasClass('error-border-style'))
{
$(this).removeClass('error-border-style')
}
}
});
$(document).on('focus', '#shipping .field.street ._required input[type="text"]', function () {
if(!$(this).parent().parent().parent().prev('.label').hasClass('fouse-label')){
$(this).parent().parent().parent().prev('.label').addClass('fouse-label')
}
});
$(document).on('blur', '#shipping .field.street ._required input[type="text"]', function () {
if($(this).parent().parent().parent().prev('.label').hasClass('fouse-label')){
var thisVal = $(this).val();
if(thisVal === '' || thisVal == null || thisVal.length === 0 || /^\s+$/.test(thisVal))
{
$(this).addClass('error-border-style');
$(this).parent().parent().parent().prev('.label').removeClass('fouse-label')
}
else if($(this).hasClass('error-border-style'))
{
$(this).removeClass('error-border-style')
}
}
});
//select-input
$(document).on('click', '#shipping .select-input', function () {
if($(this).next('.select').is(':visible'))
{
$(this).next('.select').hide();
$(this).next('.select').removeClass('select-style')
if($(this).val() == '')
{
if($(this).parent().prev('.label').hasClass('fouse-label')){
$(this).parent().prev('.label').removeClass('fouse-label');
}
}
}
else
{
$(this).next('.select').show();
$(this).next('.select').addClass('select-style');
if($(this).val() == '')
{
$(this).parent().prev('.label').addClass('fouse-label');
}
}
});
//check-select
$(document).on('click', '#shipping .check-select', function () {
$(document).on('change', '#shipping .check-select', function () {
if($(this).val() != '')
{
if($(this).val() == '-')
{
$(this).prev('input').addClass('error-border-style');
}else {
$(this).hide();
$(this).removeClass('select-style');
if($(this).prev('input').hasClass('error-border-style')){
$(this).prev('input').removeClass('error-border-style');
}
}
}
else
{
$(this).prev('input').addClass('error-border-style');
}
});
});
});
</script>
\ No newline at end of file
......@@ -14,7 +14,10 @@
method="post">
<fieldset id="customer-email-fieldset" class="fieldset" data-bind="blockLoader: isLoading">
<div class="field required">
<label class="label" for="customer-email"><span data-bind="i18n: 'Email Address'"></span><!-- ko template: 'ui/form/element/helper/tooltip' --><!-- /ko --></label>
<label class="label" for="customer-email" data-bind="css:{'fouse-label': email}">
<span data-bind="i18n: 'Email Address'"></span>
<!-- ko template: 'ui/form/element/helper/tooltip' --><!-- /ko -->
</label>
<div class="control _with-tooltip">
<input class="input-text"
type="email"
......@@ -22,7 +25,8 @@
textInput: email,
hasFocus: emailFocused,
afterRender: emailHasChanged,
mageInit: {'mage/trim-input':{}}"
mageInit: {'mage/trim-input':{}},
css:{'virtual-email': quoteIsVirtual}"
name="username"
data-validate="{required:true, 'validate-email':true}"
id="customer-email" />
......@@ -37,10 +41,6 @@
<label class="label" for="customer-password"><span data-bind="i18n: 'Password'"></span></label>
<div class="control">
<input class="input-text"
data-bind="
attr: {
placeholder: $t('Password'),
}"
type="password"
name="password"
id="customer-password"
......@@ -67,4 +67,4 @@
<!--Hidden fields -->
</fieldset>
</form>
<!-- /ko -->
<!-- /ko -->
\ No newline at end of file
......@@ -2122,6 +2122,19 @@ footer{
width: 50%;
}
.products-grid {
.product-item .product-item-info, .product-list-item .product-item-info {
padding: .2rem !important;
}
.product-items {
gap: .2rem;
}
.product-items .product-item{
width: 49%;
}
}
.view-more-flashsale {
padding: 0px;
}
......@@ -2295,10 +2308,10 @@ button.action.submit.primary {
}
.swatch-option.color, .swatch-option.image{
width: 40px;
height: 40px;
width: 30px !important;
height: 30px !important;
background-clip: content-box!important;
padding: 5px;
padding: .25em;
border: 1px solid rgba(23,23,23,0.3);
}
......
......@@ -9,6 +9,7 @@ define([
'mageUtils',
'jquery-ui-modules/widget',
'jquery/validate',
'jquery/validates',
'mage/translate'
], function ($, moment, utils) {
'use strict';
......
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