Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteAnalytics
* @author Richard BAYET <richard.bayet@smile.fr>
* @copyright 2025 Smile
* @license Open Software License ("OSL") v. 3.0
*/

namespace Smile\ElasticsuiteTracker\Model\Data\Checker\Event;

use Magento\Framework\Search\SearchEngineInterface;
use Smile\ElasticsuiteCore\Search\Request\Builder;
use Smile\ElasticsuiteCore\Search\Request\Query\QueryFactory;
use Smile\ElasticsuiteCore\Search\Request\QueryInterface;
use Smile\ElasticsuiteCore\Search\RequestInterface;
use Smile\ElasticsuiteTracker\Api\EventIndexInterface;
use Smile\ElasticsuiteTracker\Model\Data\Checker\AbstractDataChecker;
use Smile\ElasticsuiteTracker\Model\Data\Checker\DataCheckerInterface;
use Smile\ElasticsuiteTracker\Model\Data\Checker\DataCheckResultFactory;
use Smile\ElasticsuiteTracker\Model\Data\Fixer\DataFixerInterface;

/**
* Behavioral data checker for mistyped checkout_cart_add events where the page type identifier
* is located in page.identifier instead of page.type.identifier.
*
* @category Smile
* @package Smile\ElasticsuiteTracker
*/
class MistypedAddToCartEvent extends AbstractDataChecker implements DataCheckerInterface
{
/**
* @var QueryFactory
*/
private $queryFactory;

/**
* Constructor.
*
* @param DataCheckResultFactory $checkResultFactory Data checker result factory.
* @param Builder $searchRequestBuilder Search request builder.
* @param QueryFactory $queryFactory Search query factory.
* @param SearchEngineInterface $searchEngine Search engine.
* @param DataFixerInterface|null $dataFixer Invalid data fixer.
*/
public function __construct(
DataCheckResultFactory $checkResultFactory,
Builder $searchRequestBuilder,
QueryFactory $queryFactory,
SearchEngineInterface $searchEngine,
?DataFixerInterface $dataFixer = null
) {
$this->queryFactory = $queryFactory;
parent::__construct($checkResultFactory, $searchRequestBuilder, $searchEngine, $dataFixer);
}

/**
* {@inheritDoc}
*/
protected function getInvalidDocsDescription(int $docCount): string
{
return sprintf("%d add to cart events not correctly typed.", $docCount);
}

/**
* {@inheritDoc}
*/
protected function getSearchRequest($storeId): RequestInterface
{
// The correct location for the page identifier is page.type.identifier.
$queryFilters = [
$this->queryFactory->create(
QueryInterface::TYPE_BOOL,
[
'must' => [
$this->queryFactory->create(
QueryInterface::TYPE_MISSING,
['field' => 'page.type.identifier']
),
$this->queryFactory->create(
QueryInterface::TYPE_TERM,
['field' => 'page.identifier', 'value' => 'checkout_cart_add']
),
],
]
),
];

return $this->searchRequestBuilder->create($storeId, EventIndexInterface::INDEX_IDENTIFIER, 0, 0, null, [], [], $queryFilters);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteAnalytics
* @author Richard BAYET <richard.bayet@smile.fr>
* @copyright 2025 Smile
* @license Open Software License ("OSL") v. 3.0
*/

namespace Smile\ElasticsuiteTracker\Model\Data\Fixer\Event;

use Magento\Framework\View\Layout\PageType\Config as PageTypeConfig;
use Smile\ElasticsuiteCore\Api\Client\ClientInterface;
use Smile\ElasticsuiteCore\Api\Index\IndexSettingsInterface;
use Smile\ElasticsuiteCore\Search\Adapter\Elasticsuite\Request\Query\Builder as QueryBuilder;
use Smile\ElasticsuiteCore\Search\Request\Query\QueryFactory;
use Smile\ElasticsuiteCore\Search\Request\QueryInterface;
use Smile\ElasticsuiteTracker\Api\EventIndexInterface;
use Smile\ElasticsuiteTracker\Model\Data\Fixer\DataFixerInterface;

/**
* Behavioral data fixer for mistyped checkout_cart_add events where the page type identifier
* is located in "page.identifier" instead of "page.type.identifier".
*
* @category Smile
* @package Smile\ElasticsuiteTracker
*/
class MistypedAddToCartAddEvent implements DataFixerInterface
{
/**
* @var QueryFactory
*/
private $queryFactory;

/**
* @var QueryBuilder
*/
private $queryBuilder;

/**
* @var IndexSettingsInterface
*/
private $indexSettings;

/**
* @var PageTypeConfig
*/
private $pageTypeConfig;

/**
* @var ClientInterface
*/
private $client;

/**
* Constructor.
*
* @param QueryFactory $queryFactory Query factory.
* @param QueryBuilder $queryBuilder Query Builder.
* @param IndexSettingsInterface $indexSettings Index settings.
* @param PageTypeConfig $pageTypeConfig Layout page types config.
* @param ClientInterface $client Elasticsearch client.
*/
public function __construct(
QueryFactory $queryFactory,
QueryBuilder $queryBuilder,
IndexSettingsInterface $indexSettings,
PageTypeConfig $pageTypeConfig,
ClientInterface $client
) {
$this->queryFactory = $queryFactory;
$this->queryBuilder = $queryBuilder;
$this->indexSettings = $indexSettings;
$this->pageTypeConfig = $pageTypeConfig;
$this->client = $client;
}

/**
* {@inheritDoc}
*/
public function fixInvalidData(int $storeId): int
{
$result = DataFixerInterface::FIX_COMPLETE;

try {
$indexAlias = $this->indexSettings->getIndexAliasFromIdentifier(
EventIndexInterface::INDEX_IDENTIFIER,
$storeId
);

$query = $this->queryBuilder->buildQuery(
$this->queryFactory->create(
QueryInterface::TYPE_BOOL,
[
'must' => [
$this->queryFactory->create(
QueryInterface::TYPE_MISSING,
['field' => 'page.type.identifier']
),
$this->queryFactory->create(
QueryInterface::TYPE_TERM,
['field' => 'page.identifier', 'value' => 'checkout_cart_add']
),
],
]
)
);

$updatePageIdentifier = <<<EOF
if (!ctx._source.page.containsKey('type')) { ctx._source.page.type = params.typeInfo; }
else { ctx._source.page.type.identifier=params.typeInfo.identifier; ctx._source.page.type.label=params.typeInfo.label; }
ctx._source.page.remove('identifier');
ctx._source.page.remove('label');
EOF;
$indicesNames = $this->client->getIndicesNameByAlias($indexAlias);
foreach ($indicesNames as $indexName) {
$params = [
'index' => $indexName,
'body' => [
'query' => $query,
'script' => [
'source' => $updatePageIdentifier,
'lang' => 'painless',
'params' => [
'typeInfo' => [
'identifier' => 'checkout_cart_add',
'label' => stripslashes($this->getPageTypeLabel('checkout_cart_add')),
],
],
],
'conflicts' => 'proceed',
],
];
$this->client->updateByQuery($params);
}
} catch (\Exception $e) {
$result = DataFixerInterface::FIX_FAILURE;
}

return $result;
}

/**
* Human-readable version of the page type identifier.
*
* @param string $pageTypeIdentifier Page type identifier.
*
* @return string
*/
private function getPageTypeLabel($pageTypeIdentifier)
{
foreach ($this->pageTypeConfig->getPageTypes() as $identifier => $pageType) {
if ($pageTypeIdentifier === $identifier) {
return $pageType['label'];
}
}

return '';
}
}
6 changes: 4 additions & 2 deletions src/module-elasticsuite-tracker/Plugin/QuotePlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,10 @@ public function afterAddProduct(
private function logEvent(int $productId, int $storeId, ?int $customerGroupId, ?int $companyId): void
{
$pageData = [
'identifier' => 'checkout_cart_add',
'label' => stripslashes($this->getPageTypeLabel('checkout_cart_add')),
'type' => [
'identifier' => 'checkout_cart_add',
'label' => stripslashes($this->getPageTypeLabel('checkout_cart_add')),
],
];
$pageData['store_id'] = $storeId;
$pageData['cart']['product_id'] = $productId;
Expand Down
7 changes: 7 additions & 0 deletions src/module-elasticsuite-tracker/etc/di.xml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
<argument name="checkers" xsi:type="array">
<item name="undefinedSessionIdInEvents" xsi:type="object">Smile\ElasticsuiteTracker\Model\Data\Checker\Event\UndefinedSessionId</item>
<item name="undefinedSessionIdInSessions" xsi:type="object">Smile\ElasticsuiteTracker\Model\Data\Checker\Session\UndefinedSessionId</item>
<item name="mistypedAddToCartEvents" xsi:type="object">Smile\ElasticsuiteTracker\Model\Data\Checker\Event\MistypedAddToCartEvent</item>
</argument>
</arguments>
</type>
Expand All @@ -119,6 +120,12 @@
</arguments>
</type>

<type name="Smile\ElasticsuiteTracker\Model\Data\Checker\Event\MistypedAddToCartEvent">
<arguments>
<argument name="dataFixer" xsi:type="object">Smile\ElasticsuiteTracker\Model\Data\Fixer\Event\MistypedAddToCartAddEvent</argument>
</arguments>
</type>

<!-- Prevent session start for tracking urls -->
<type name="Magento\Framework\Session\SessionStartChecker">
<plugin name="elasticsuite_tracker_disable_session" type="Smile\ElasticsuiteTracker\Plugin\SessionStartCheckerPlugin"/>
Expand Down