Skip to content

Commit 60831ec

Browse files
committed
[Tracker] Add to cart events checker and fixer
1 parent 1fa494e commit 60831ec

3 files changed

Lines changed: 266 additions & 0 deletions

File tree

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
/**
3+
* DISCLAIMER
4+
*
5+
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer versions in the future.
6+
*
7+
* @category Smile
8+
* @package Smile\ElasticsuiteAnalytics
9+
* @author Richard BAYET <richard.bayet@smile.fr>
10+
* @copyright 2025 Smile
11+
* @license Open Software License ("OSL") v. 3.0
12+
*/
13+
14+
namespace Smile\ElasticsuiteTracker\Model\Data\Checker\Event;
15+
16+
use Magento\Framework\Search\SearchEngineInterface;
17+
use Smile\ElasticsuiteCore\Search\Request\Builder;
18+
use Smile\ElasticsuiteCore\Search\Request\Query\QueryFactory;
19+
use Smile\ElasticsuiteCore\Search\Request\QueryInterface;
20+
use Smile\ElasticsuiteCore\Search\RequestInterface;
21+
use Smile\ElasticsuiteTracker\Api\EventIndexInterface;
22+
use Smile\ElasticsuiteTracker\Model\Data\Checker\AbstractDataChecker;
23+
use Smile\ElasticsuiteTracker\Model\Data\Checker\DataCheckerInterface;
24+
use Smile\ElasticsuiteTracker\Model\Data\Checker\DataCheckResultFactory;
25+
use Smile\ElasticsuiteTracker\Model\Data\Fixer\DataFixerInterface;
26+
27+
/**
28+
* Behavioral data checker for mistyped checkout_cart_add events where the page type identifier
29+
* is located in page.identifier instead of page.type.identifier.
30+
*
31+
* @category Smile
32+
* @package Smile\ElasticsuiteTracker
33+
*/
34+
class MistypedAddToCartEvent extends AbstractDataChecker implements DataCheckerInterface
35+
{
36+
/**
37+
* @var QueryFactory
38+
*/
39+
private $queryFactory;
40+
41+
/**
42+
* Constructor.
43+
*
44+
* @param DataCheckResultFactory $checkResultFactory Data checker result factory.
45+
* @param Builder $searchRequestBuilder Search request builder.
46+
* @param QueryFactory $queryFactory Search query factory.
47+
* @param SearchEngineInterface $searchEngine Search engine.
48+
* @param DataFixerInterface|null $dataFixer Invalid data fixer.
49+
*/
50+
public function __construct(
51+
DataCheckResultFactory $checkResultFactory,
52+
Builder $searchRequestBuilder,
53+
QueryFactory $queryFactory,
54+
SearchEngineInterface $searchEngine,
55+
?DataFixerInterface $dataFixer = null
56+
) {
57+
$this->queryFactory = $queryFactory;
58+
parent::__construct($checkResultFactory, $searchRequestBuilder, $searchEngine, $dataFixer);
59+
}
60+
61+
/**
62+
* {@inheritDoc}
63+
*/
64+
protected function getInvalidDocsDescription(int $docCount): string
65+
{
66+
return sprintf("%d add to cart events not correctly typed.", $docCount);
67+
}
68+
69+
/**
70+
* {@inheritDoc}
71+
*/
72+
protected function getSearchRequest($storeId): RequestInterface
73+
{
74+
// The correct location for the page identifier is page.type.identifier.
75+
$queryFilters = [
76+
$this->queryFactory->create(
77+
QueryInterface::TYPE_BOOL,
78+
[
79+
'must' => [
80+
$this->queryFactory->create(
81+
QueryInterface::TYPE_MISSING,
82+
['field' => 'page.type.identifier']
83+
),
84+
$this->queryFactory->create(
85+
QueryInterface::TYPE_TERM,
86+
['field' => 'page.identifier', 'value' => 'checkout_cart_add']
87+
),
88+
],
89+
]
90+
),
91+
];
92+
93+
return $this->searchRequestBuilder->create($storeId, EventIndexInterface::INDEX_IDENTIFIER, 0, 0, null, [], [], $queryFilters);
94+
}
95+
}
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
<?php
2+
/**
3+
* DISCLAIMER
4+
*
5+
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer versions in the future.
6+
*
7+
* @category Smile
8+
* @package Smile\ElasticsuiteAnalytics
9+
* @author Richard BAYET <richard.bayet@smile.fr>
10+
* @copyright 2025 Smile
11+
* @license Open Software License ("OSL") v. 3.0
12+
*/
13+
14+
namespace Smile\ElasticsuiteTracker\Model\Data\Fixer\Event;
15+
16+
use Magento\Framework\View\Layout\PageType\Config as PageTypeConfig;
17+
use Smile\ElasticsuiteCore\Api\Client\ClientInterface;
18+
use Smile\ElasticsuiteCore\Api\Index\IndexSettingsInterface;
19+
use Smile\ElasticsuiteCore\Search\Adapter\Elasticsuite\Request\Query\Builder as QueryBuilder;
20+
use Smile\ElasticsuiteCore\Search\Request\Query\QueryFactory;
21+
use Smile\ElasticsuiteCore\Search\Request\QueryInterface;
22+
use Smile\ElasticsuiteTracker\Api\EventIndexInterface;
23+
use Smile\ElasticsuiteTracker\Model\Data\Fixer\DataFixerInterface;
24+
25+
/**
26+
* Behavioral data fixer for mistyped checkout_cart_add events where the page type identifier
27+
* is located in "page.identifier" instead of "page.type.identifier".
28+
*
29+
* @category Smile
30+
* @package Smile\ElasticsuiteTracker
31+
*/
32+
class MistypedAddToCartAddEvent implements DataFixerInterface
33+
{
34+
/**
35+
* @var QueryFactory
36+
*/
37+
private $queryFactory;
38+
39+
/**
40+
* @var QueryBuilder
41+
*/
42+
private $queryBuilder;
43+
44+
/**
45+
* @var IndexSettingsInterface
46+
*/
47+
private $indexSettings;
48+
49+
/**
50+
* @var PageTypeConfig
51+
*/
52+
private $pageTypeConfig;
53+
54+
/**
55+
* @var ClientInterface
56+
*/
57+
private $client;
58+
59+
/**
60+
* Constructor.
61+
*
62+
* @param QueryFactory $queryFactory Query factory.
63+
* @param QueryBuilder $queryBuilder Query Builder.
64+
* @param IndexSettingsInterface $indexSettings Index settings.
65+
* @param PageTypeConfig $pageTypeConfig Layout page types config.
66+
* @param ClientInterface $client Elasticsearch client.
67+
*/
68+
public function __construct(
69+
QueryFactory $queryFactory,
70+
QueryBuilder $queryBuilder,
71+
IndexSettingsInterface $indexSettings,
72+
PageTypeConfig $pageTypeConfig,
73+
ClientInterface $client
74+
) {
75+
$this->queryFactory = $queryFactory;
76+
$this->queryBuilder = $queryBuilder;
77+
$this->indexSettings = $indexSettings;
78+
$this->pageTypeConfig = $pageTypeConfig;
79+
$this->client = $client;
80+
}
81+
82+
/**
83+
* {@inheritDoc}
84+
*/
85+
public function fixInvalidData(int $storeId): int
86+
{
87+
$result = DataFixerInterface::FIX_COMPLETE;
88+
89+
try {
90+
$indexAlias = $this->indexSettings->getIndexAliasFromIdentifier(
91+
EventIndexInterface::INDEX_IDENTIFIER,
92+
$storeId
93+
);
94+
95+
$query = $this->queryBuilder->buildQuery(
96+
$this->queryFactory->create(
97+
QueryInterface::TYPE_BOOL,
98+
[
99+
'must' => [
100+
$this->queryFactory->create(
101+
QueryInterface::TYPE_MISSING,
102+
['field' => 'page.type.identifier']
103+
),
104+
$this->queryFactory->create(
105+
QueryInterface::TYPE_TERM,
106+
['field' => 'page.identifier', 'value' => 'checkout_cart_add']
107+
),
108+
],
109+
]
110+
)
111+
);
112+
113+
$updatePageIdentifier = <<<EOF
114+
if (!ctx._source.page.containsKey('type')) { ctx._source.page.type = params.typeInfo; }
115+
else { ctx._source.page.type.identifier=params.typeInfo.identifier; ctx._source.page.type.label=params.typeInfo.label; }
116+
ctx._source.page.remove('identifier');
117+
ctx._source.page.remove('label');
118+
EOF;
119+
$indicesNames = $this->client->getIndicesNameByAlias($indexAlias);
120+
foreach ($indicesNames as $indexName) {
121+
$params = [
122+
'index' => $indexName,
123+
'body' => [
124+
'query' => $query,
125+
'script' => [
126+
'source' => $updatePageIdentifier,
127+
'lang' => 'painless',
128+
'params' => [
129+
'typeInfo' => [
130+
'identifier' => 'checkout_cart_add',
131+
'label' => stripslashes($this->getPageTypeLabel('checkout_cart_add')),
132+
],
133+
],
134+
],
135+
'conflicts' => 'proceed',
136+
],
137+
];
138+
$this->client->updateByQuery($params);
139+
}
140+
} catch (\Exception $e) {
141+
$result = DataFixerInterface::FIX_FAILURE;
142+
}
143+
144+
return $result;
145+
}
146+
147+
/**
148+
* Human-readable version of the page type identifier.
149+
*
150+
* @param string $pageTypeIdentifier Page type identifier.
151+
*
152+
* @return string
153+
*/
154+
private function getPageTypeLabel($pageTypeIdentifier)
155+
{
156+
foreach ($this->pageTypeConfig->getPageTypes() as $identifier => $pageType) {
157+
if ($pageTypeIdentifier === $identifier) {
158+
return $pageType['label'];
159+
}
160+
}
161+
162+
return '';
163+
}
164+
}

src/module-elasticsuite-tracker/etc/di.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@
103103
<argument name="checkers" xsi:type="array">
104104
<item name="undefinedSessionIdInEvents" xsi:type="object">Smile\ElasticsuiteTracker\Model\Data\Checker\Event\UndefinedSessionId</item>
105105
<item name="undefinedSessionIdInSessions" xsi:type="object">Smile\ElasticsuiteTracker\Model\Data\Checker\Session\UndefinedSessionId</item>
106+
<item name="mistypedAddToCartEvents" xsi:type="object">Smile\ElasticsuiteTracker\Model\Data\Checker\Event\MistypedAddToCartEvent</item>
106107
</argument>
107108
</arguments>
108109
</type>
@@ -119,6 +120,12 @@
119120
</arguments>
120121
</type>
121122

123+
<type name="Smile\ElasticsuiteTracker\Model\Data\Checker\Event\MistypedAddToCartEvent">
124+
<arguments>
125+
<argument name="dataFixer" xsi:type="object">Smile\ElasticsuiteTracker\Model\Data\Fixer\Event\MistypedAddToCartAddEvent</argument>
126+
</arguments>
127+
</type>
128+
122129
<!-- Prevent session start for tracking urls -->
123130
<type name="Magento\Framework\Session\SessionStartChecker">
124131
<plugin name="elasticsuite_tracker_disable_session" type="Smile\ElasticsuiteTracker\Plugin\SessionStartCheckerPlugin"/>

0 commit comments

Comments
 (0)