370 lines
15 KiB
PHP
370 lines
15 KiB
PHP
<?php
|
|
|
|
namespace FluentCrm\App\Hooks\Handlers;
|
|
|
|
use FluentCrm\App\Models\EventTracker;
|
|
use FluentCrm\App\Services\Helper;
|
|
use FluentCrm\Framework\Support\Arr;
|
|
|
|
class EventTrackingHandler
|
|
{
|
|
public function register()
|
|
{
|
|
add_filter('fluentcrm_ajax_options_event_tracking_keys', [$this, 'getEventTrackingKeyOptions'], 10, 1);
|
|
add_action('fluentcrm_contacts_filter_event_tracking', [$this, 'applyEventTrackingFilter'], 10, 2);
|
|
add_action('fluent_crm/track_event_activity', [$this, 'trackEventActivity'], 10, 2);
|
|
|
|
add_filter('fluent_crm/subscriber_info_widgets', [$this, 'addSubscriberInfoWidgets'], 10, 2);
|
|
add_filter('fluent_crm/subscriber_info_widget_event_tracking', [$this, 'addSubscriberInfoWidgets'], 10, 2);
|
|
|
|
add_filter('fluentcrm_advanced_filter_options', [$this, 'addEventTrackingFilterOptions'], 10, 1);
|
|
|
|
add_filter('fluent_crm/event_tracking_condition_groups', [$this, 'addEventTrackingConditionOptions'], 10, 1);
|
|
|
|
add_filter('fluentcrm_automation_condition_groups', function ($groups) {
|
|
if (!Helper::isExperimentalEnabled('event_tracking')) {
|
|
return $groups;
|
|
}
|
|
|
|
$groups['event_tracking'] = [
|
|
'label' => __('Event Tracking', 'fluent-crm'),
|
|
'value' => 'event_tracking',
|
|
'children' => $this->getConditionItems()
|
|
];
|
|
|
|
return $groups;
|
|
});
|
|
}
|
|
|
|
public function getEventTrackingKeyOptions($options = [])
|
|
{
|
|
$items = EventTracker::select(['event_key'])
|
|
->groupBy('event_key')
|
|
->orderBy('event_key', 'ASC')
|
|
->get();
|
|
|
|
$formattedItems = [];
|
|
|
|
foreach ($items as $item) {
|
|
$formattedItems[] = [
|
|
'id' => $item->event_key,
|
|
'title' => $item->event_key
|
|
];
|
|
}
|
|
|
|
return $formattedItems;
|
|
}
|
|
|
|
public function applyEventTrackingFilter($query, $filters)
|
|
{
|
|
if (!Helper::isExperimentalEnabled('event_tracking')) {
|
|
return $query;
|
|
}
|
|
|
|
foreach ($filters as $filter) {
|
|
if (!array_key_exists('value', $filter) || $filter['value'] === '') {
|
|
continue;
|
|
}
|
|
|
|
$relation = 'trackingEvents';
|
|
|
|
$filterProp = $filter['property'];
|
|
|
|
if ($filterProp == 'event_tracking_key') {
|
|
$operator = $filter['operator'];
|
|
$values = $filter['value'];
|
|
if ($operator == 'not_in') {
|
|
$query->whereDoesntHave($relation, function ($q) use ($values) {
|
|
$q->whereIn('event_key', $values);
|
|
});
|
|
} else {
|
|
$query->whereHas($relation, function ($q) use ($values) {
|
|
$q->whereIn('event_key', $values);
|
|
});
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if ($filterProp == 'event_tracking_title') {
|
|
$operator = $filter['operator'];
|
|
|
|
if ($operator == '=') {
|
|
$query->whereHas($relation, function ($q) use ($filter) {
|
|
$q->where('title', $filter['value']);
|
|
});
|
|
} else if ($operator == '!=') {
|
|
$query->whereDoesntHave($relation, function ($q) use ($filter) {
|
|
$q->where('title', $filter['value']);
|
|
});
|
|
} else if ($operator == 'contains') {
|
|
$query->whereHas($relation, function ($q) use ($filter) {
|
|
$q->where('title', 'LIKE', '%' . $filter['value'] . '%');
|
|
});
|
|
} else if ($operator == 'not_contains') {
|
|
$query->whereDoesntHave($relation, function ($q) use ($filter) {
|
|
$q->where('title', 'LIKE', '%' . $filter['value'] . '%');
|
|
});
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if ($filterProp == 'event_tracking_value') {
|
|
|
|
$eventKey = Arr::get($filter, 'extra_value');
|
|
if (!$eventKey) {
|
|
continue;
|
|
}
|
|
|
|
$operator = $filter['operator'];
|
|
|
|
if ($operator == '=') {
|
|
$query->whereHas($relation, function ($q) use ($filter, $eventKey) {
|
|
$q->where('value', $filter['value'])
|
|
->where('event_key', $eventKey);
|
|
});
|
|
} else if ($operator == '!=') {
|
|
$query->whereDoesntHave($relation, function ($q) use ($filter, $eventKey) {
|
|
$q->where('value', $filter['value'])
|
|
->where('event_key', $eventKey);
|
|
});
|
|
} else if (in_array($operator, ['<', '>'])) {
|
|
|
|
$query->whereHas($relation, function ($q) use ($filter, $eventKey, $operator) {
|
|
$q->where('value', $operator, (int)$filter['value'])
|
|
->where('event_key', $eventKey);
|
|
});
|
|
} else if ($operator == 'contains') {
|
|
$query->whereHas($relation, function ($q) use ($filter, $eventKey) {
|
|
$q->where('value', 'LIKE', '%' . $filter['value'] . '%')
|
|
->where('event_key', $eventKey);
|
|
});
|
|
} else if ($operator == 'not_contains') {
|
|
$query->whereDoesntHave($relation, function ($q) use ($filter, $eventKey) {
|
|
$q->where('value', 'LIKE', '%' . $filter['value'] . '%')
|
|
->where('event_key', $eventKey);
|
|
});
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if ($filterProp == 'event_tracking_key_count') {
|
|
|
|
$eventKey = Arr::get($filter, 'extra_value');
|
|
if (!$eventKey) {
|
|
continue;
|
|
}
|
|
|
|
$operator = $filter['operator'];
|
|
|
|
if ($operator == '=') {
|
|
$query->whereHas($relation, function ($q) use ($filter, $eventKey) {
|
|
$q->where('counter', $filter['value'])
|
|
->where('event_key', $eventKey);
|
|
});
|
|
} else if ($operator == '!=') {
|
|
$query->whereDoesntHave($relation, function ($q) use ($filter, $eventKey) {
|
|
$q->where('counter', $filter['value'])
|
|
->where('event_key', $eventKey);
|
|
});
|
|
} else if (in_array($operator, ['<', '>'])) {
|
|
|
|
$query->whereHas($relation, function ($q) use ($filter, $eventKey, $operator) {
|
|
$q->where('counter', $operator, (int)$filter['value'])
|
|
->where('event_key', $eventKey);
|
|
});
|
|
}
|
|
|
|
continue;
|
|
}
|
|
}
|
|
|
|
return $query;
|
|
}
|
|
|
|
public function trackEventActivity($data, $repeatable = true)
|
|
{
|
|
return FluentCrmApi('event_tracker')->track($data, $repeatable);
|
|
}
|
|
|
|
public function addSubscriberInfoWidgets($widgets, $subscriber)
|
|
{
|
|
if (!Helper::isExperimentalEnabled('event_tracking')) {
|
|
return $widgets;
|
|
}
|
|
|
|
$events = EventTracker::where('subscriber_id', $subscriber->id)
|
|
->orderBy('updated_at', 'DESC')
|
|
->paginate();
|
|
|
|
if ($events->isEmpty()) {
|
|
return $widgets;
|
|
}
|
|
|
|
$html = '<div class="fc_scrolled_lists"><ul class="fcrm_event_tracking_lists">';
|
|
foreach ($events as $event) {
|
|
$html .= '<li>';
|
|
$html .= '<p class="fcrm_event_tracking_title">' . esc_html($event->title) . '</p>';
|
|
if ($event->value) {
|
|
$html .= '<p class="fcrm_event_tracking_value">' . wp_kses_post($event->value) . '</p>';
|
|
}
|
|
$html .= '<div class="fcrm_event_tracking_footer">';
|
|
$html .= '<div class="fcrm_event_tracking_badge">' . esc_attr($event->event_key) . '<span class="fcrm_event_tracking_count">(' . esc_html($event->counter) . ')</span></div>';
|
|
$html .= '<span class="fcrm_event_tracking_date">' . $event->updated_at . '</span>';
|
|
$html .= '</div>';
|
|
$html .= '</li>';
|
|
}
|
|
$html .= '</ul></div>';
|
|
|
|
$widgets['event_tracking'] = [
|
|
'title' => __('Event Tracking', 'fluent-crm'),
|
|
'content' => $html,
|
|
'has_pagination' => $events->total() > $events->perPage(),
|
|
'total' => $events->total(),
|
|
'per_page' => $events->perPage(),
|
|
'current_page' => $events->currentPage()
|
|
];
|
|
|
|
return $widgets;
|
|
}
|
|
|
|
public function addEventTrackingFilterOptions($groups)
|
|
{
|
|
if (!Helper::isExperimentalEnabled('event_tracking')) {
|
|
return $groups;
|
|
}
|
|
|
|
$groups['event_tracking'] = [
|
|
'label' => __('Event Tracking', 'fluent-crm'),
|
|
'value' => 'event_tracking',
|
|
'children' => $this->getConditionItems()
|
|
];
|
|
|
|
return $groups;
|
|
}
|
|
|
|
public function addEventTrackingConditionOptions($items)
|
|
{
|
|
if (!Helper::isExperimentalEnabled('event_tracking')) {
|
|
return $items;
|
|
}
|
|
|
|
return [
|
|
[
|
|
'label' => __('Event Tracking', 'fluent-crm'),
|
|
'value' => 'event_tracking',
|
|
'children' => $this->getConditionItems()
|
|
],
|
|
[
|
|
'label' => __('Contact Segment', 'fluent-crm'),
|
|
'value' => 'segment',
|
|
'children' => [
|
|
[
|
|
'label' => __('Type', 'fluent-crm'),
|
|
'value' => 'contact_type',
|
|
'type' => 'selections',
|
|
'component' => 'options_selector',
|
|
'option_key' => 'contact_types',
|
|
'is_multiple' => false,
|
|
'is_singular_value' => true
|
|
],
|
|
[
|
|
'label' => __('Tags', 'fluent-crm'),
|
|
'value' => 'tags',
|
|
'type' => 'selections',
|
|
'component' => 'options_selector',
|
|
'option_key' => 'tags',
|
|
'is_multiple' => true,
|
|
],
|
|
[
|
|
'label' => __('Lists', 'fluent-crm'),
|
|
'value' => 'lists',
|
|
'type' => 'selections',
|
|
'component' => 'options_selector',
|
|
'option_key' => 'lists',
|
|
'is_multiple' => true,
|
|
]
|
|
],
|
|
]
|
|
];
|
|
}
|
|
|
|
private function getConditionItems()
|
|
{
|
|
return [
|
|
[
|
|
'label' => __('Event Key', 'fluent-crm'),
|
|
'value' => 'event_tracking_key',
|
|
'type' => 'selections',
|
|
'component' => 'ajax_selector',
|
|
'option_key' => 'event_tracking_keys',
|
|
'is_multiple' => true,
|
|
'custom_operators' => [
|
|
'in' => 'in',
|
|
'not_in' => 'not in'
|
|
],
|
|
'creatable' => true,
|
|
'experimental_cache' => true,
|
|
'help' => __('Match one or more tracking events for your contacts.', 'fluent-crm')
|
|
],
|
|
[
|
|
'label' => __('Event Occurrence Count', 'fluent-crm'),
|
|
'value' => 'event_tracking_key_count',
|
|
'type' => 'composite_optioned_compare',
|
|
'help' => __('The provided value for your selected event will be matched with the event occurrence count', 'fluent-crm'),
|
|
'ajax_selector' => [
|
|
'label' => __('For Event Key', 'fluent-crm'),
|
|
'option_key' => 'event_tracking_keys',
|
|
'experimental_cache' => true,
|
|
'is_multiple' => false,
|
|
'placeholder' => __('Select Event Key', 'fluent-crm')
|
|
],
|
|
'value_config' => [
|
|
'label' => __('Event Count', 'fluent-crm'),
|
|
'type' => 'input_text',
|
|
'data_type' => 'number',
|
|
'placeholder' => __('Event Value', 'fluent-crm')
|
|
],
|
|
'custom_operators' => [
|
|
'=' => 'equal',
|
|
'!=' => 'not equal',
|
|
'>' => 'greater than',
|
|
'<' => 'less than'
|
|
],
|
|
],
|
|
[
|
|
'label' => __('Event Value', 'fluent-crm'),
|
|
'value' => 'event_tracking_value',
|
|
'type' => 'composite_optioned_compare',
|
|
'help' => __('The compare value will be matched with selected event & last recorded value of the selected event key', 'fluent-crm'),
|
|
'ajax_selector' => [
|
|
'label' => __('For Event Key', 'fluent-crm'),
|
|
'option_key' => 'event_tracking_keys',
|
|
'experimental_cache' => true,
|
|
'is_multiple' => false,
|
|
'placeholder' => __('Select Event Key', 'fluent-crm')
|
|
],
|
|
'value_config' => [
|
|
'label' => __('Compare Value', 'fluent-crm'),
|
|
'type' => 'input_text',
|
|
'placeholder' => __('Event Value', 'fluent-crm'),
|
|
'data_type' => 'number',
|
|
],
|
|
'custom_operators' => [
|
|
'=' => 'equal',
|
|
'!=' => 'not equal',
|
|
'contains' => 'includes',
|
|
'not_contains' => 'does not include',
|
|
'>' => 'greater than',
|
|
'<' => 'less than'
|
|
],
|
|
],
|
|
[
|
|
'label' => __('Event Title', 'fluent-crm'),
|
|
'value' => 'event_tracking_title',
|
|
'type' => 'text',
|
|
'help' => __('Match by tracking event title', 'fluent-crm')
|
|
],
|
|
];
|
|
}
|
|
}
|