Initial commit

This commit is contained in:
gustavooth
2026-07-23 22:56:30 -03:00
commit 22a1006598
1816 changed files with 410742 additions and 0 deletions
@@ -0,0 +1,369 @@
<?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')
],
];
}
}