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,279 @@
<?php
namespace FluentCrm\App\Services\Funnel\Actions;
use FluentCrm\App\Models\CampaignEmail;
use FluentCrm\App\Models\CampaignUrlMetric;
use FluentCrm\App\Models\FunnelCampaign;
use FluentCrm\App\Services\Funnel\BaseAction;
use FluentCrm\App\Services\Funnel\FunnelHelper;
use FluentCrm\Framework\Support\Arr;
class SendEmailAction extends BaseAction
{
public function __construct()
{
$this->actionName = 'send_custom_email';
$this->priority = 10;
parent::__construct();
add_filter('fluentcrm_funnel_sequence_saving_' . $this->actionName, array($this, 'savingAction'), 10, 2);
add_filter('fluentcrm_funnel_sequence_deleting_' . $this->actionName, array($this, 'deleteAction'), 10, 2);
add_filter('fluentcrm_funnel_sequence_filtered_' . $this->actionName, array($this, 'gettingAction'), 10, 2);
}
public function getBlock()
{
return [
'category' => __('Email', 'fluent-crm'),
'title' => __('Send Custom Email', 'fluent-crm'),
'description' => __('Send a custom Email to your subscriber or custom email address', 'fluent-crm'),
'icon' => 'fc-icon-send_campaign',//fluentCrmMix('images/funnel_icons/custom_email.svg'),
'settings' => [
'reference_campaign' => '',
'send_email_to_type' => 'contact',
'send_email_custom' => '',
'campaign' => FunnelCampaign::getMock(),
'is_scheduled' => 'no',
'scheduled_at' => '',
'skip_if_overdue' => 'no',
'mailer_settings' => [
'from_name' => '',
'from_email' => '',
'reply_to_name' => '',
'reply_to_email' => '',
'is_custom' => 'no'
]
]
];
}
public function getBlockFields()
{
return [
'title' => __('Send Custom Email', 'fluent-crm'),
'sub_title' => __('Please provide email details that you want to send', 'fluent-crm'),
'fields' => [
'send_email_to_type' => [
'type' => 'radio',
'wrapper_class' => 'fc_half_field',
'label' => __('Send Email to', 'fluent-crm'),
'options' => [
[
'id' => 'contact',
'title' => __('Send To the contact', 'fluent-crm')
],
[
'id' => 'custom',
'title' => __('Send to Custom Email Address', 'fluent-crm')
]
]
],
'send_email_custom' => [
'wrapper_class' => 'fcrm_send_custom_email_form_wrap',
'type' => 'input-text',
'label' => __('Send To Email Addresses (If Custom)', 'fluent-crm'),
'placeholder' => __('Custom Email Addresses', 'fluent-crm'),
'inline_help' => __('Use comma separated values for multiple', 'fluent-crm'),
'dependency' => [
'depends_on' => 'send_email_to_type',
'operator' => '=',
'value' => 'custom'
]
],
'campaign' => [
'label' => '',
'wrapper_class' => 'fc_email_writer',
'type' => 'email_campaign_composer'
],
'is_scheduled' => [
'type' => 'yes_no_check',
'check_label' => __('Schedule this email to a specific date', 'fluent-crm'),
'wrapper_class' => 'fc_no_pad_l',
],
'skip_if_overdue' => [
'type' => 'yes_no_check',
'wrapper_class' => 'fcrm_child_field',
'check_label' => __('Skip sending email if date is overdued', 'fluent-crm'),
'dependency' => [
'depends_on' => 'is_scheduled',
'operator' => '=',
'value' => 'yes'
]
],
'scheduled_at' => [
'label' => __('Schedule Date and Time', 'fluent-crm'),
'type' => 'date_time',
'wrapper_class' => 'fcrm_child_field fcrm_schedule_date_time fc_no_marg_b',
'placeholder' => __('Select Date and Time', 'fluent-crm'),
'inline_help' => __('If schedule date is past in the runtime then email will be sent immediately', 'fluent-crm'),
'dependency' => [
'depends_on' => 'is_scheduled',
'operator' => '=',
'value' => 'yes'
]
],
'mailer_settings' => [
'type' => 'custom_sender_config',
'check_label' => __('Set Custom From Name and Email', 'fluent-crm')
]
]
];
}
public function savingAction($sequence, $funnel)
{
$funnelCampaign = Arr::get($sequence, 'settings.campaign', []);
$funnelCampaignId = Arr::get($funnelCampaign, 'id');
$isStripped = Arr::get($sequence, 'is_stripped');
if ($isStripped && $funnelCampaignId) {
$refCampaign = FunnelCampaign::find($funnelCampaignId);
if (!$refCampaign) {
return $sequence;
}
$data = Arr::only($refCampaign->toArray(), array_keys(FunnelCampaign::getMock()));
} else {
$data = Arr::only($funnelCampaign, array_keys(FunnelCampaign::getMock()));
}
$sequenceId = Arr::get($sequence, 'id');
$data['settings']['mailer_settings'] = Arr::get($sequence, 'settings.mailer_settings', []);
if ($funnelCampaignId && $funnel->id == Arr::get($data, 'parent_id')) {
// We have this campaign
$data['settings'] = \maybe_serialize($data['settings']);
$data['type'] = 'funnel_email_campaign';
$data['title'] = $funnel->title . ' (' . $funnel->id . ' - ' . $sequenceId . ')';
FunnelCampaign::where('id', $funnelCampaignId)->update($data);
} else {
$data['parent_id'] = $funnel->id;
$data['type'] = 'funnel_email_campaign';
$data['title'] = $funnel->title . ' (' . $funnel->id . ' - ' . $sequenceId . ')';
$campaign = FunnelCampaign::create($data);
$funnelCampaignId = $campaign->id;
if ($data['design_template'] == 'visual_builder' && !empty($funnelCampaign['_visual_builder_design'])) {
fluentcrm_update_campaign_meta($funnelCampaignId, '_visual_builder_design', $funnelCampaign['_visual_builder_design']);
}
}
$sequence['settings']['reference_campaign'] = $funnelCampaignId;
$sequence['settings']['campaign'] = [];
return $sequence;
}
public function gettingAction($sequence, $funnel)
{
$refCampaignData = FunnelCampaign::getMock();
if ($refCampaignId = Arr::get($sequence, 'settings.reference_campaign')) {
$refCampaign = FunnelCampaign::find($refCampaignId);
if ($refCampaign) {
$refCampaignData = Arr::only($refCampaign->toArray(), array_keys(FunnelCampaign::getMock()));
if ($refCampaignData['design_template'] == 'visual_builder') {
$refCampaignData['_visual_builder_design'] = fluentcrm_get_campaign_meta($refCampaignData['id'], '_visual_builder_design', true);
} else {
$refCampaignData['__fcrm_block_type'] = 'email_body_in_funnel';
}
$sequence['settings']['campaign'] = $refCampaignData;
}
}
if (empty($sequence['settings']['mailer_settings'])) {
$sequence['settings']['mailer_settings'] = [
'from_name' => '',
'from_email' => '',
'reply_to_name' => '',
'reply_to_email' => '',
'is_custom' => 'no'
];
}
return $sequence;
}
public function deleteAction($sequence, $funnel)
{
$refCampaign = Arr::get($sequence->settings, 'reference_campaign');
if ($refCampaign) {
FunnelCampaign::where('id', $refCampaign)->delete();
CampaignEmail::where('campaign_id', $refCampaign)->delete();
CampaignUrlMetric::where('campaign_id', $refCampaign)->delete();
fluentcrm_delete_campaign_meta($refCampaign, '');
}
}
public function handle($subscriber, $sequence, $funnelSubscriberId, $funnelMetric)
{
$settings = $sequence->settings;
$refCampaign = Arr::get($settings, 'reference_campaign');
if (!$refCampaign) {
FunnelHelper::changeFunnelSubSequenceStatus($funnelSubscriberId, $sequence->id, 'skipped');
return;
}
if ($funnelMetric) {
// We are making sure, this action will run only once per funnel subscriber
if (did_action('fluent_crm/did_run_funnel_email_action_' . $funnelMetric->id)) {
FunnelHelper::changeFunnelSubSequenceStatus($funnelSubscriberId, $sequence->id, 'skipped');
return;
}
do_action('fluent_crm/did_run_funnel_email_action_' . $funnelMetric->id);
}
$campaign = FunnelCampaign::find($refCampaign);
if (!$campaign) {
FunnelHelper::changeFunnelSubSequenceStatus($funnelSubscriberId, $sequence->id, 'skipped');
return;
}
$scheduledAt = current_time('mysql');
if (Arr::get($settings, 'is_scheduled') == 'yes') {
$providedDate = Arr::get($settings, 'scheduled_at');
if ($providedDate && Arr::get($settings, 'skip_if_overdue') == 'yes') {
if (strtotime($scheduledAt) > strtotime($providedDate)) {
FunnelHelper::changeFunnelSubSequenceStatus($funnelSubscriberId, $sequence->id, 'skipped');
return;
}
}
if ($providedDate && strtotime($providedDate) > strtotime($scheduledAt)) {
$scheduledAt = $providedDate;
}
}
$args = [
'status' => 'scheduled',
'scheduled_at' => $scheduledAt,
'email_type' => 'funnel_email_campaign',
'note' => __('Email Sent From Funnel: ', 'fluent-crm') . $campaign->title
];
if (Arr::get($settings, 'send_email_to_type') == 'contact') {
$campaign->processAndSubscribe($subscriber, [
'funnel_subscriber_id' => $funnelSubscriberId
], $args);
do_action('fluentcrm_process_contact_jobs', $subscriber);
} else if ($customAddresses = Arr::get($settings, 'send_email_custom')) {
/**
* Filters and parses custom email addresses for a campaign email text.
*
* This code applies the 'fluent_crm/parse_campaign_email_text' filter to process
* the custom email addresses for a given subscriber.
*
* @param string $customAddresses The custom email addresses string to be parsed.
* @param object $subscriber The subscriber object containing subscriber details.
*
* @return string The filtered and parsed custom email addresses string.
*/
$customAddresses = apply_filters('fluent_crm/parse_campaign_email_text', $customAddresses, $subscriber);
$customAddresses = array_filter(array_map('sanitize_email', explode(',', $customAddresses)));
$campaign->sendToCustomAddresses($customAddresses, $args, $subscriber);
}
}
}