Skip to content

Commit db6fa50

Browse files
Merge branch 'raptor_integration_feature_branch' into IBX-11571
2 parents b1e8fb1 + 1f400e1 commit db6fa50

30 files changed

Lines changed: 1946 additions & 1 deletion
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php declare(strict_types=1);
2+
use Ibexa\Contracts\ConnectorRaptor\Tracking\Event\VisitEventData;
3+
4+
$eventData = new VisitEventData(
5+
productCode: $product->getCode(),
6+
productName: $product->getName(),
7+
categoryPath: '25#Electronics;26#Smartphones', // Build manually
8+
currency: 'USD',
9+
itemPrice: '999.99'
10+
);
11+
12+
$this->trackingDispatcher->dispatch($eventData);
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php declare(strict_types=1);
2+
use Ibexa\Contracts\ConnectorRaptor\Tracking\EventMapperInterface;
3+
use Ibexa\Contracts\ConnectorRaptor\Tracking\EventType;
4+
use Ibexa\Contracts\ConnectorRaptor\Tracking\ServerSideTrackingDispatcherInterface;
5+
use Ibexa\Contracts\ProductCatalog\Values\ProductInterface;
6+
7+
class EventMapper
8+
{
9+
public function __construct(
10+
private readonly EventMapperInterface $eventMapper,
11+
private ServerSideTrackingDispatcherInterface $trackingDispatcher,
12+
) {
13+
}
14+
15+
public function trackProductView(ProductInterface $product, string $url): void
16+
{
17+
// Map product to VisitEventData automatically
18+
$eventData = $this->eventMapper->map(EventType::VISIT, $product);
19+
20+
// Send tracking event
21+
$this->trackingDispatcher->dispatch($eventData);
22+
}
23+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php declare(strict_types=1);
2+
use Ibexa\Contracts\ConnectorRaptor\Tracking\EventMapperInterface;
3+
use Ibexa\Contracts\ConnectorRaptor\Tracking\EventType;
4+
use Ibexa\Contracts\ConnectorRaptor\Tracking\ServerSideTrackingDispatcherInterface;
5+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
6+
use Symfony\Component\HttpKernel\Event\ResponseEvent;
7+
use Symfony\Component\HttpKernel\KernelEvents;
8+
9+
class EventSubscriber implements EventSubscriberInterface
10+
{
11+
public function __construct(
12+
private readonly EventMapperInterface $eventMapper,
13+
private ServerSideTrackingDispatcherInterface $trackingDispatcher,
14+
) {
15+
}
16+
17+
public static function getSubscribedEvents(): array
18+
{
19+
return [KernelEvents::RESPONSE => ['onResponse', -10]];
20+
}
21+
22+
public function onResponse(ResponseEvent $event): void
23+
{
24+
if (!$event->isMainRequest()) {
25+
return;
26+
}
27+
28+
$request = $event->getRequest();
29+
30+
// Example: track only if request has specific attribute
31+
$product = $request->attributes->get('product');
32+
if (null === $product) {
33+
return;
34+
}
35+
36+
$eventData = $this->eventMapper->map(EventType::VISIT, $product);
37+
$this->trackingDispatcher->dispatch($eventData);
38+
}
39+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
ibexa:
2+
system:
3+
<scope>:
4+
connector_raptor:
5+
enabled: true
6+
customer_id: ~ # Required
7+
tracking_type: client # One of: "client" or "server"
8+
9+
# Raptor Recommendations API key
10+
recommendations_api_key: ~ # Required
11+
12+
# Raptor Recommendations API URL, optional, set by default
13+
recommendations_api_url: '%ibexa.connector.raptor.recommendations.api_url%'
14+
ibexa_connector_raptor:
15+
# When enabled, tracking exceptions are thrown instead of being silently handled
16+
strict_exceptions: true
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
``` html
2+
<!-- Cookie Consent by TermsFeed https://www.TermsFeed.com -->
3+
<script type="text/javascript" src="https://www.termsfeed.com/public/cookie-consent/4.2.0/cookie-consent.js" charset="UTF-8"></script>
4+
<script type="text/javascript" charset="UTF-8">
5+
document.addEventListener('DOMContentLoaded', function () {
6+
cookieconsent.run({
7+
"notice_banner_type": "simple",
8+
"consent_type": "implied",
9+
"palette": "dark",
10+
"language": "en",
11+
"page_load_consent_levels": ["strictly-necessary"],
12+
"notice_banner_reject_button_hide": false,
13+
"preferences_center_close_button_hide": false,
14+
"page_refresh_confirmation_buttons": false,
15+
"website_name": "Ibexa Storefront",
16+
"callbacks": {
17+
"scripts_specific_loaded": (level) => {
18+
switch(level) {
19+
case 'tracking':
20+
document.dispatchEvent(new CustomEvent('enableTracking'));
21+
break;
22+
}
23+
}
24+
},
25+
"callbacks_force": true
26+
});
27+
});
28+
</script>
29+
<noscript>Free cookie consent management tool by <a href="https://www.termsfeed.com/">TermsFeed</a></noscript>
30+
<!-- End Cookie Consent by TermsFeed https://www.TermsFeed.com -->
31+
```
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
{# templates/cart/add_confirmation.html.twig #}
2+
{% extends 'base.html.twig' %}
3+
4+
{% block content %}
5+
<div class="cart-notification">
6+
<p>Product "{{ product.name }}" has been added to your cart!</p>
7+
<p>Quantity: {{ addedQuantity }}</p>
8+
</div>
9+
10+
{# Build basket content string: "product-code:quantity;product-code:quantity" #}
11+
{% set basketContent = [] %}
12+
{% for entry in cart.entries %}
13+
{% set basketContent = basketContent|merge([entry.product.code ~ ':' ~ entry.quantity]) %}
14+
{% endfor %}
15+
{# Track basket addition #}
16+
{% set basketContext = {
17+
'basketContent': basketContent|join(';'),
18+
'basketId': cart.id,
19+
'quantity': addedQuantity
20+
} %}
21+
22+
{{ ibexa_tracking_track_event('basket', product, basketContext) }}
23+
24+
<a href="{{ path('cart_view') }}">View Cart</a>
25+
{% endblock %}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{# templates/bundles/IbexaCoreBundle/default/content/full.html.twig #}
2+
{% extends '@!IbexaCore/default/content/full.html.twig' %}
3+
4+
{% block content %}
5+
{{ parent() }}
6+
{{ ibexa_tracking_track_event('contentvisit', content) }}
7+
{% endblock %}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{{ ibexa_tracking_track_event('itemclick', product.code, {
2+
'moduleName': 'homepage-recommendations',
3+
'redirectUrl': path('ibexa.product.view', {'productCode': product.code})
4+
}) }}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# templates/product/view.html.twig #}
2+
{% extends 'base.html.twig' %}
3+
4+
{% block content %}
5+
<div class="product-details">
6+
<h1>{{ product.name }}</h1>
7+
<p>{{ product.description }}</p>
8+
<div class="price">{{ product.price }}</div>
9+
</div>
10+
11+
{# Track product visit #}
12+
{{ ibexa_tracking_track_event('visit', product) }}
13+
{% endblock %}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{% extends '@IbexaConnectorRaptor/themes/standard/ibexa/tracking/script.html.twig' %}
2+
{% block ibexa_tracking_script %}
3+
console.log('My custom tracking script, but relying on loadTracking function.');
4+
{% endblock %}

0 commit comments

Comments
 (0)