diff --git a/src/Resources/config/grids/setono_sylius_facebook_admin_pixel.yaml b/src/Resources/config/grids/setono_sylius_facebook_admin_pixel.yaml
index 8559d29..0287196 100644
--- a/src/Resources/config/grids/setono_sylius_facebook_admin_pixel.yaml
+++ b/src/Resources/config/grids/setono_sylius_facebook_admin_pixel.yaml
@@ -1,4 +1,7 @@
sylius_grid:
+ templates:
+ action:
+ setono_facebook_reset_failed_events: "@SetonoSyliusFacebookPlugin/Admin/Grid/Action/setono_facebook_reset_failed_events.html.twig"
grids:
setono_sylius_facebook_admin_pixel:
driver:
@@ -7,8 +10,17 @@ sylius_grid:
class: "%setono_sylius_facebook.model.pixel.class%"
fields:
pixelId:
- type: string
+ type: twig
label: setono_sylius_facebook.ui.pixel_id
+ path: .
+ options:
+ template: "@SetonoSyliusFacebookPlugin/Admin/Grid/Field/pixel.html.twig"
+ events_statistics:
+ type: twig
+ label: setono_sylius_facebook.ui.events_statistics
+ path: .
+ options:
+ template: "@SetonoSyliusFacebookPlugin/Admin/Grid/Field/statistics.html.twig"
channels:
type: twig
label: sylius.ui.channels
@@ -35,5 +47,7 @@ sylius_grid:
item:
update:
type: update
+ setono_facebook_reset_failed_events:
+ type: setono_facebook_reset_failed_events
delete:
type: delete
diff --git a/src/Resources/config/routes/admin.yaml b/src/Resources/config/routes/admin.yaml
index 10109eb..a18759d 100644
--- a/src/Resources/config/routes/admin.yaml
+++ b/src/Resources/config/routes/admin.yaml
@@ -8,6 +8,19 @@ setono_sylius_facebook_admin_pixel:
vars:
all:
subheader: setono_sylius_facebook.ui.manage_pixels
+ templates:
+ form: "@SetonoSyliusFacebookPlugin/Admin/Pixel/_form.html.twig"
index:
icon: 'facebook'
type: sylius.resource
+
+setono_sylius_facebook_admin_pixel_reset_failed_events:
+ path: /{id}/events/failed/reset
+ methods: [PATCH]
+ defaults:
+ _controller: setono_sylius_facebook.controller.action.pixel.reset_failed_events
+ _sylius:
+ section: admin
+ permission: true
+ redirect:
+ route: setono_sylius_facebook_admin_pixel_index
diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml
index b73e286..92e292a 100644
--- a/src/Resources/config/services.xml
+++ b/src/Resources/config/services.xml
@@ -5,6 +5,7 @@
+
@@ -13,5 +14,6 @@
+
diff --git a/src/Resources/config/services/controller.xml b/src/Resources/config/services/controller.xml
new file mode 100644
index 0000000..db457d9
--- /dev/null
+++ b/src/Resources/config/services/controller.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Resources/config/services/twig.xml b/src/Resources/config/services/twig.xml
new file mode 100644
index 0000000..e07266a
--- /dev/null
+++ b/src/Resources/config/services/twig.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Resources/translations/flashes.en.yml b/src/Resources/translations/flashes.en.yml
new file mode 100644
index 0000000..eb647e3
--- /dev/null
+++ b/src/Resources/translations/flashes.en.yml
@@ -0,0 +1,3 @@
+setono_sylius_facebook:
+ pixel:
+ failed_events_reset: 'Failed events reset'
diff --git a/src/Resources/translations/messages.en.yaml b/src/Resources/translations/messages.en.yaml
index b00c243..e6f0771 100644
--- a/src/Resources/translations/messages.en.yaml
+++ b/src/Resources/translations/messages.en.yaml
@@ -1,13 +1,25 @@
setono_sylius_facebook:
form:
pixel:
+ custom_access_token: Pixel's access token
+ custom_access_token_help: Leave it empty to use default one from plugin configuration
+ custom_access_token_placeholder: Insert Facebook access token for this pixel
pixel_id: Pixel id
+ pixel_id_help: Get it from https://www.facebook.com/events_manager2
pixel_id_placeholder: Insert your pixel id...
ui:
+ custom_access_token_specified: Custom token
edit_pixel: Edit facebook pixel
+ events_in_state:
+ pending: Pending
+ sent: Sent
+ failed: Failed
+ events_statistics: Statistics
facebook: Facebook
manage_pixels: Manage facebook pixels
new_pixel: New facebook pixel
+ no_channels: No channels
+ no_events: No events
pixel_id: Pixel id
pixels: Facebook pixels
- no_channels: No channels
+ reset_failed_events: Reset failed events
diff --git a/src/Resources/views/Admin/Grid/Action/setono_facebook_reset_failed_events.html.twig b/src/Resources/views/Admin/Grid/Action/setono_facebook_reset_failed_events.html.twig
new file mode 100644
index 0000000..b69478e
--- /dev/null
+++ b/src/Resources/views/Admin/Grid/Action/setono_facebook_reset_failed_events.html.twig
@@ -0,0 +1,18 @@
+{# @var \Setono\SyliusFacebookPlugin\Model\PixelInterface data #}
+
+{% import '@SetonoSyliusFacebookPlugin/Admin/Macro/buttons.html.twig' as buttons %}
+
+{% set path = options.link.url|default(path(
+ options.link.route|default('setono_sylius_facebook_admin_pixel_reset_failed_events'),
+ options.link.parameters|default({'id': data.id})
+)) %}
+
+{% set failedCount = setono_facebook_events_count_by_state(data, constant('Setono\\SyliusFacebookPlugin\\Model\\PixelEventInterface::STATE_FAILED')) %}
+{% if options.visible|default(failedCount > 0) %}
+ {{ buttons.resetFailedEvents(
+ path,
+ action.label|default('setono_sylius_facebook.ui.reset_failed_events'),
+ true,
+ data.id
+ ) }}
+{% endif %}
diff --git a/src/Resources/views/Admin/Grid/Field/pixel.html.twig b/src/Resources/views/Admin/Grid/Field/pixel.html.twig
new file mode 100644
index 0000000..32f13ef
--- /dev/null
+++ b/src/Resources/views/Admin/Grid/Field/pixel.html.twig
@@ -0,0 +1,10 @@
+{# @var \Setono\SyliusFacebookPlugin\Model\PixelInterface data #}
+
+{{ data.pixelId }}
+
+{% if data.customAccessToken is not null %}
+
+
+ {{ 'setono_sylius_facebook.ui.custom_access_token_specified'|trans }}
+
+{% endif %}
diff --git a/src/Resources/views/Admin/Grid/Field/statistics.html.twig b/src/Resources/views/Admin/Grid/Field/statistics.html.twig
new file mode 100644
index 0000000..c37c45f
--- /dev/null
+++ b/src/Resources/views/Admin/Grid/Field/statistics.html.twig
@@ -0,0 +1,10 @@
+{# @var \Setono\SyliusFacebookPlugin\Model\PixelInterface data #}
+
+{% for state, count in setono_facebook_events_pushing_statistics(data) %}
+
+ {{ ('setono_sylius_facebook.ui.events_in_state.' ~ state)|trans }}:
+ {{ count }}
+
+{% else %}
+ {{ 'setono_sylius_facebook.ui.no_events'|trans }}
+{% endfor %}
diff --git a/src/Resources/views/Admin/Macro/buttons.html.twig b/src/Resources/views/Admin/Macro/buttons.html.twig
new file mode 100644
index 0000000..7ef4d8e
--- /dev/null
+++ b/src/Resources/views/Admin/Macro/buttons.html.twig
@@ -0,0 +1,11 @@
+{% extends '@SyliusUi/Macro/buttons.html.twig' %}
+
+{% macro resetFailedEvents(url, message, labeled = true, resourceId = null) %}
+
+{% endmacro %}
diff --git a/src/Resources/views/Admin/Pixel/_form.html.twig b/src/Resources/views/Admin/Pixel/_form.html.twig
new file mode 100644
index 0000000..b1288e0
--- /dev/null
+++ b/src/Resources/views/Admin/Pixel/_form.html.twig
@@ -0,0 +1,11 @@
+
+ {{ form_errors(form) }}
+
+ {{ form_row(form.pixelId) }}
+ {{ form_row(form.channels) }}
+
+ {{ form_row(form.enabled) }}
+
+
+ {{ form_row(form.customAccessToken) }}
+
diff --git a/src/Twig/EventsPushingStatisticsExtension.php b/src/Twig/EventsPushingStatisticsExtension.php
new file mode 100644
index 0000000..bdf773b
--- /dev/null
+++ b/src/Twig/EventsPushingStatisticsExtension.php
@@ -0,0 +1,52 @@
+pixelEventRepository = $pixelEventRepository;
+ }
+
+ public function getFunctions(): array
+ {
+ return [
+ new TwigFunction('setono_facebook_events_pushing_statistics', [$this, 'getEventsPushingStatistics']),
+ new TwigFunction('setono_facebook_events_count_by_state', [$this, 'getEventsCountByState']),
+ ];
+ }
+
+ /**
+ * @return array
+ */
+ public function getEventsPushingStatistics(PixelInterface $pixel): array
+ {
+ $result = [];
+ foreach (SendPixelEventWorkflow::getStates() as $state) {
+ $count = $this->pixelEventRepository->getCountByPixelAndState($pixel, $state);
+ if (0 === $count) {
+ continue;
+ }
+
+ $result[$state] = $count;
+ }
+
+ return $result;
+ }
+
+ public function getEventsCountByState(PixelInterface $pixel, string $state): int
+ {
+ return $this->pixelEventRepository->getCountByPixelAndState($pixel, $state);
+ }
+}
diff --git a/tests/Application/templates/bundles/SyliusUiBundle/Form/theme.html.twig b/tests/Application/templates/bundles/SyliusUiBundle/Form/theme.html.twig
new file mode 100644
index 0000000..2843248
--- /dev/null
+++ b/tests/Application/templates/bundles/SyliusUiBundle/Form/theme.html.twig
@@ -0,0 +1,10 @@
+{% extends '@!SyliusUi/Form/theme.html.twig' %}
+
+{% block form_row -%}
+
+ {{- form_label(form) -}}
+ {{- form_widget(form) -}}
+ {{- form_help(form) -}}
+ {{- form_errors(form) -}}
+
+{%- endblock form_row %}
diff --git a/tests/Client/ClientTest.php b/tests/Client/ClientTest.php
index ddb0881..ea1d762 100644
--- a/tests/Client/ClientTest.php
+++ b/tests/Client/ClientTest.php
@@ -58,6 +58,8 @@ public function send_pixel_event_test(): void
$pixel = new Pixel();
$pixel->setPixelId($this->pixelId);
+ $eventTime = time();
+
$pixelEvent = new PixelEvent();
$pixelEvent->setPixel($pixel);
$pixelEvent->setData([
@@ -66,7 +68,7 @@ public function send_pixel_event_test(): void
'client_user_agent' => 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36',
],
'event_name' => 'ViewContent',
- 'event_time' => 1635769396,
+ 'event_time' => $eventTime,
'custom_data' => [
'contents' => [
[
@@ -106,7 +108,7 @@ public function send_pixel_event_test(): void
Assert::string($requestOptions['body']);
$requestBody = urldecode($requestOptions['body']);
- $expected = sprintf('access_token=%s&data=[{"user_data":{"client_ip_address":"::1","client_user_agent":"Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/94.0.4606.61 Safari\/537.36"},"event_name":"ViewContent","event_time":1635769396,"custom_data":{"contents":[{"id":"Beige_strappy_summer_dress","quantity":1}],"content_ids":["Beige_strappy_summer_dress"],"content_name":"Beige strappy summer dress","content_type":"product"},"action_source":"website","event_source_url":"https:\/\/localhost:8000\/en_US\/products\/beige-strappy-summer-dress"}]', $this->accessToken);
+ $expected = sprintf('access_token=%s&data=[{"user_data":{"client_ip_address":"::1","client_user_agent":"Mozilla\/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit\/537.36 (KHTML, like Gecko) Chrome\/94.0.4606.61 Safari\/537.36"},"event_name":"ViewContent","event_time":%s,"custom_data":{"contents":[{"id":"Beige_strappy_summer_dress","quantity":1}],"content_ids":["Beige_strappy_summer_dress"],"content_name":"Beige strappy summer dress","content_type":"product"},"action_source":"website","event_source_url":"https:\/\/localhost:8000\/en_US\/products\/beige-strappy-summer-dress"}]', $this->accessToken, $eventTime);
if (null !== $this->testEventCode) {
$expected .= sprintf('&test_event_code=%s', $this->testEventCode);
}