Skip to content

Commit

Permalink
chores(insights): migration / order conversion tracking (algolia#895)
Browse files Browse the repository at this point in the history
  • Loading branch information
bsuravech authored Nov 7, 2019
1 parent e3a2945 commit 5552aae
Show file tree
Hide file tree
Showing 18 changed files with 461 additions and 74 deletions.
74 changes: 74 additions & 0 deletions Block/Checkout/Conversion.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace Algolia\AlgoliaSearch\Block\Checkout;

use Algolia\AlgoliaSearch\Helper\ConfigHelper;
use Magento\Checkout\Model\Session;
use Magento\Framework\View\Element\Template;
use Magento\Framework\View\Element\Template\Context;
use Magento\Sales\Model\Order\Item;

class Conversion extends Template
{
/**
* @var Session
*/
protected $checkoutSession;

/**
* @var ConfigHelper
*/
protected $configHelper;

/**
* @param Context $context
* @param Session $checkoutSession
* @param ConfigHelper $configHelper
* @param array $data
*/
public function __construct(
Context $context,
Session $checkoutSession,
ConfigHelper $configHelper,
array $data = []
) {
parent::__construct($context, $data);
$this->checkoutSession = $checkoutSession;
$this->configHelper = $configHelper;
}

protected function getOrderItems()
{
/** @var \Magento\Sales\Model\Order $order */
$order = $this->checkoutSession->getLastRealOrder();

return $order->getAllVisibleItems();
}

public function getOrderItemsConversionJson()
{
$orderItemsData = [];
$orderItems = $this->getOrderItems();

/** @var Item $item */
foreach ($orderItems as $item) {
if ($item->hasData('algoliasearch_query_param')) {
$orderItemsData[$item->getProductId()] = json_decode($item->getData('algoliasearch_query_param'));
}
}

return json_encode($orderItemsData);
}

public function toHtml()
{
$storeId = $this->checkoutSession->getLastRealOrder()->getStoreId();
if ($this->configHelper->isClickConversionAnalyticsEnabled($storeId)
&& $this->configHelper->getConversionAnalyticsMode($storeId) === 'place_order'
) {
return parent::toHtml();
}

return '';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

namespace Algolia\AlgoliaSearch\Model\Observer\ClickAnalytics;

use Algolia\AlgoliaSearch\Helper\ConfigHelper;
use Magento\Checkout\Model\Session as CheckoutSession;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class CatalogControllerProductInitBefore implements ObserverInterface
{
protected $analyticsParams = [
'queryID',
'indexName',
'objectID',
];

/** @var ConfigHelper */
private $configHelper;

/** @var CheckoutSession */
private $checkoutSession;

/**
* CatalogControllerProductInitBefore constructor.
*
* @param ConfigHelper $configHelper
* @param CheckoutSession $checkoutSession
*/
public function __construct(
ConfigHelper $configHelper,
CheckoutSession $checkoutSession
) {
$this->configHelper = $configHelper;
$this->checkoutSession = $checkoutSession;
}

/**
* @param array $params
*
* @return bool
*/
protected function hasRequiredParameters($params = [])
{
foreach ($this->analyticsParams as $requiredParam) {
if (!isset($params[$requiredParam])) {
return false;
}
}

return true;
}

public function execute(Observer $observer)
{
$controllerAction = $observer->getEvent()->getControllerAction();
$params = $controllerAction->getRequest()->getParams();

$storeID = $this->checkoutSession->getQuote()->getStoreId();
if ($this->hasRequiredParameters($params)
&& $this->configHelper->isClickConversionAnalyticsEnabled($storeID)
&& $this->configHelper->getConversionAnalyticsMode($storeID) === 'place_order'
) {
$conversionData = [
'queryID' => $params['queryID'],
'indexName' => $params['indexName'],
'objectID' => $params['objectID'],
];

$this->checkoutSession->setData('algoliasearch_query_param', json_encode($conversionData));
}
}
}
48 changes: 48 additions & 0 deletions Model/Observer/ClickAnalytics/CheckoutCartProductAddAfter.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Algolia\AlgoliaSearch\Model\Observer\ClickAnalytics;

use Algolia\AlgoliaSearch\Helper\ConfigHelper;
use Magento\Checkout\Model\Session as CheckoutSession;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;

class CheckoutCartProductAddAfter implements ObserverInterface
{
/** @var ConfigHelper */
private $configHelper;

/** @var CheckoutSession */
private $checkoutSession;

/**
* CatalogControllerProductInitBefore constructor.
*
* @param ConfigHelper $configHelper
* @param CheckoutSession $checkoutSession
*/
public function __construct(
ConfigHelper $configHelper,
CheckoutSession $checkoutSession
) {
$this->configHelper = $configHelper;
$this->checkoutSession = $checkoutSession;
}

/**
* @param Observer $observer
*/
public function execute(Observer $observer)
{
/** @var \Magento\Quote\Model\Quote\Item $quoteItem */
$quoteItem = $observer->getEvent()->getQuoteItem();
/** @var \Magento\Catalog\Model\Product $product */
$product = $observer->getEvent()->getProduct();

if ($this->configHelper->isClickConversionAnalyticsEnabled($product->getStoreId())
&& $this->configHelper->getConversionAnalyticsMode($product->getStoreId()) === 'place_order'
) {
$quoteItem->setData('algoliasearch_query_param', $this->checkoutSession->getData('algoliasearch_query_param'));
}
}
}
1 change: 0 additions & 1 deletion Model/ResourceModel/Query/Grid/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class Collection extends QueryCollection implements SearchResultInterface

/**
* @param \Magento\Framework\Data\Collection\EntityFactoryInterface $entityFactory
* @param \Psr\Log\LoggerInterface $logger
* @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
* @param \Magento\Framework\Event\ManagerInterface $eventManager
* @param mixed|null $mainTable
Expand Down
48 changes: 48 additions & 0 deletions Plugin/QuoteItem.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

namespace Algolia\AlgoliaSearch\Plugin;

use Algolia\AlgoliaSearch\Helper\ConfigHelper;
use Magento\Quote\Model\Quote\Item\AbstractItem;
use Magento\Quote\Model\Quote\Item\ToOrderItem;
use Magento\Sales\Api\Data\OrderItemInterface;

class QuoteItem
{
/** @var ConfigHelper */
private $configHelper;

/**
* QuoteItem constructor.
*
* @param ConfigHelper $configHelper
*/
public function __construct(ConfigHelper $configHelper)
{
$this->configHelper = $configHelper;
}

/**
* @param ToOrderItem $subject
* @param OrderItemInterface $orderItem
* @param AbstractItem $item
* @param array $additional
*
* @return OrderItemInterface
*/
public function afterConvert(
ToOrderItem $subject,
OrderItemInterface $orderItem,
AbstractItem $item,
$additional = []
) {
$product = $item->getProduct();
if ($this->configHelper->isClickConversionAnalyticsEnabled($product->getStoreId())
&& $this->configHelper->getConversionAnalyticsMode($product->getStoreId()) === 'place_order'
) {
$orderItem->setData('algoliasearch_query_param', $item->getData('algoliasearch_query_param'));
}

return $orderItem;
}
}
68 changes: 68 additions & 0 deletions Setup/UpgradeData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<?php

namespace Algolia\AlgoliaSearch\Setup;

use Magento\Framework\DB\Ddl\Table;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;
use Magento\Quote\Setup\QuoteSetupFactory;
use Magento\Sales\Setup\SalesSetupFactory;

class UpgradeData implements UpgradeDataInterface
{
/**
* @var QuoteSetupFactory
*/
private $quoteSetupFactory;

/**
* @var SalesSetupFactory
*/
private $salesSetupFactory;

public function __construct(
QuoteSetupFactory $quoteSetupFactory,
SalesSetupFactory $salesSetupFactory
) {
$this->quoteSetupFactory = $quoteSetupFactory;
$this->salesSetupFactory = $salesSetupFactory;
}
/**
* @param ModuleDataSetupInterface $setup
* @param ModuleContextInterface $context
*
* @throws \Magento\Framework\Exception\LocalizedException
*/
public function upgrade(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
{
// beware, this is the version we are upgrading from, not to!
$moduleVersion = $context->getVersion();

if (version_compare($moduleVersion, '2.0.0', '<')) {
/** @var \Magento\Quote\Setup\QuoteSetup $quoteSetup */
$quoteSetup = $this->quoteSetupFactory->create(['resourceName' => 'quote_setup', 'setup' => $setup]);
$quoteSetup->addAttribute(
'quote_item',
'algoliasearch_query_param',
[
'type' => TABLE::TYPE_TEXT,
'nullable' => true,
'comment' => 'Reference for Algolia analytics order conversion',
]
);

/** @var \Magento\Sales\Setup\SalesSetup $salesSetup */
$salesSetup = $this->salesSetupFactory->create(['resourceName' => 'sales_setup', 'setup' => $setup]);
$salesSetup->addAttribute(
'order_item',
'algoliasearch_query_param',
[
'type' => TABLE::TYPE_TEXT,
'nullable' => true,
'comment' => 'Reference for Algolia analytics order conversion',
]
);
}
}
}
2 changes: 1 addition & 1 deletion Setup/UpgradeSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class UpgradeSchema implements UpgradeSchemaInterface
'algoliasearch_queue/queue/number_of_retries' => '3',

'algoliasearch_cc_analytics/cc_analytics_group/enable' => '0',
'algoliasearch_cc_analytics/cc_analytics_group/is_selector' => '.ais-hits--item a.result, .ais-infinite-hits--item a.result',
'algoliasearch_cc_analytics/cc_analytics_group/is_selector' => '.ais-Hits-item a.result, .ais-InfiniteHits-item a.result',
'algoliasearch_cc_analytics/cc_analytics_group/enable_conversion_analytics' => 'disabled',
'algoliasearch_cc_analytics/cc_analytics_group/add_to_cart_selector' => '.action.primary.tocart',

Expand Down
2 changes: 1 addition & 1 deletion etc/adminhtml/system.xml
Original file line number Diff line number Diff line change
Expand Up @@ -655,7 +655,7 @@
<label>DOM selector of a result container on the instant search page</label>
<comment>
<![CDATA[
The element must contain attributes <code>data-objectid</code> and <code>data-position</code>.
The element must contain attributes <code>data-objectid</code>, <code>data-indexname</code>, <code>data-position</code>, and <code>data-queryid</code>.
]]>
</comment>
<depends>
Expand Down
5 changes: 5 additions & 0 deletions etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,9 @@
<argument name="imageUploader" xsi:type="object">Algolia\AlgoliaSearch\QueryImageUpload</argument>
</arguments>
</type>

<!-- Click and Conversion Analytics -->
<type name="Magento\Quote\Model\Quote\Item\ToOrderItem">
<plugin name="algoliasearch_query_quote_item_conversion" type="Algolia\AlgoliaSearch\Plugin\QuoteItem"/>
</type>
</config>
8 changes: 8 additions & 0 deletions etc/frontend/events.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,12 @@
<event name="algolia_get_attributes_to_filter">
<observer name="algoliasearch_apply_product_permissions" instance="Algolia\AlgoliaSearch\Model\Observer\CatalogPermissions\ApplyProductPermissionsFilter" />
</event>

<!-- Click and Conversion Analytics -->
<event name="catalog_controller_product_init_before">
<observer name="algoliasearch_set_parameters_to_session" instance="Algolia\AlgoliaSearch\Model\Observer\ClickAnalytics\CatalogControllerProductInitBefore" />
</event>
<event name="checkout_cart_product_add_after">
<observer name="algoliasearch_add_request_to_quote_item" instance="Algolia\AlgoliaSearch\Model\Observer\ClickAnalytics\CheckoutCartProductAddAfter" />
</event>
</config>
13 changes: 13 additions & 0 deletions view/frontend/layout/checkout_onepage_success.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?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">
<body>
<referenceContainer name="order.success.additional.info">
<block ifconfig="algoliasearch_cc_analytics/cc_analytics_group/enable"
class="Algolia\AlgoliaSearch\Block\Checkout\Conversion"
name="algoliasearch.analytics.order.conversion"
template="Algolia_AlgoliaSearch::checkout/conversion.phtml"
after="-">
</block>
</referenceContainer>
</body>
</page>
7 changes: 5 additions & 2 deletions view/frontend/templates/autocomplete/product.phtml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ $tierFormatedVar = 'price' . $priceKey . '_tier_formated'

<!-- Product hit template -->
<script type="text/template" id="autocomplete_products_template">
<a class="algoliasearch-autocomplete-hit" href="{{url}}">
<a class="algoliasearch-autocomplete-hit"
{{^__queryID}} href="{{url}}" {{/__queryID}}
{{#__queryID}} href="{{urlForInsights}}" {{/__queryID}}
>
{{#thumbnail_url}}
<div class="thumb"><img src="{{thumbnail_url}}" alt="{{{name}}}" /></div>
{{/thumbnail_url}}
Expand Down Expand Up @@ -55,4 +58,4 @@ $tierFormatedVar = 'price' . $priceKey . '_tier_formated'
</div>
</div>
</a>
</script>
</script>
Loading

0 comments on commit 5552aae

Please sign in to comment.