shell bypass 403

UnknownSec Shell


name : EloquentCampaignRepository.php
<?php


namespace App\Repositories\Eloquent;

use App\Jobs\ImportCampaign;
use App\Jobs\ScheduleBatchJob;
use App\Jobs\StoreCampaignJob;
use App\Library\SMSCounter;
use App\Library\Tool;
use App\Models\Blacklists;
use App\Models\Campaigns;
use App\Models\CampaignsList;
use App\Models\CampaignsRecipients;
use App\Models\CampaignsSenderid;
use App\Models\CampaignsSendingServer;
use App\Models\ContactGroups;
use App\Models\Country;
use App\Models\CsvData;
use App\Models\ImportJobHistory;
use App\Models\PhoneNumbers;
use App\Models\PlansCoverageCountries;
use App\Models\Senderid;
use App\Models\SendingServer;
use App\Models\SpamWord;
use App\Models\Templates;
use App\Models\User;
use App\Notifications\SendCampaignCopy;
use App\Repositories\Contracts\CampaignRepository;
use Carbon\Carbon;
use Illuminate\Bus\Batch;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Bus;
use Illuminate\Support\Facades\DB;
use Throwable;

class EloquentCampaignRepository extends EloquentBaseRepository implements CampaignRepository
{

    public static array $serverPools = [];

    /**
     * EloquentCampaignRepository constructor.
     *
     * @param  Campaigns  $campaigns
     */
    public function __construct(Campaigns $campaigns)
    {
        parent::__construct($campaigns);
    }


    /**
     * send quick message
     *
     * @param  Campaigns  $campaign
     * @param  array  $input
     *
     * @return JsonResponse
     * @throws Throwable
     */
    public function quickSend(Campaigns $campaign, array $input): JsonResponse
    {
        if (isset($input['user_id'])) {
            $user = User::find($input['user_id']);
        } else {
            $user = Auth::user();
        }
        $sms_type = $input['sms_type'];

        $blacklist = Blacklists::where('user_id', $user->id)->where('number', $input['recipient'])->first();
        if ($blacklist) {
            return response()->json([
                    'status'  => 'error',
                    'message' => 'Number contain in blacklist',
            ]);
        }

        if ($user->customer->getOption('send_spam_message') == 'no') {
            $spamWords = SpamWord::all()->filter(function ($spamWord) use ($input) {
                if ( true === str_contains(strtolower($input['message']), strtolower($spamWord->word))) {
                    return true;
                }

                return false;
            });

            if ($spamWords->count()) {
                return response()->json([
                        'status'  => 'error',
                        'message' => 'Your message contains spam words.',
                ]);
            }
        }

        if ($user->sms_unit == 0) {
            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.campaigns.sending_limit_exceed'),
            ]);
        }

        if ($user->customer->activeSubscription()) {

            if ($sms_type == 'unicode') {
                $db_sms_type = 'plain';
            } else {
                $db_sms_type = $sms_type;
            }

            if ($sms_type == 'plain' || $sms_type == 'unicode') {
                $capabilities_type = 'sms';
            } else {
                $capabilities_type = $sms_type;
            }

            // Check the customer has permissions using sending servers and has his own sending servers
            $sending_server = SendingServer::find($input['sending_server']);

            if ( ! $sending_server) {
                return response()->json([
                        'status'  => 'error',
                        'message' => __('locale.campaigns.sending_server_not_available'),
                ]);
            }

            if ($sending_server->{$db_sms_type} != 1) {
                return response()->json([
                        'status'  => 'error',
                        'message' => __('locale.campaigns.sending_server_not_available'),
                ]);
            }

            $sender_id = null;
            if ($user->customer->getOption('sender_id_verification') == 'yes') {
                if (isset($input['originator'])) {
                    if ($input['originator'] == 'sender_id' && isset($input['sender_id'])) {
                        $sender_id = $input['sender_id'];
                    } elseif ($input['originator'] == 'phone_number' && isset($input['phone_number'])) {
                        $sender_id = $input['phone_number'];
                    }
                } elseif (isset($input['sender_id'])) {
                    $sender_id = $input['sender_id'];
                }

                $check_sender_id = Senderid::where('user_id', $user->id)->where('sender_id', $sender_id)->where('status', 'active')->first();
                if ( ! $check_sender_id) {
                    $number = PhoneNumbers::where('user_id', $user->id)->where('number', $sender_id)->where('status', 'assigned')->first();

                    if ( ! $number) {
                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_invalid', ['sender_id' => $sender_id]),
                        ]);
                    }

                    $capabilities = str_contains($number->capabilities, $capabilities_type);

                    if ( ! $capabilities) {
                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_sms_capabilities', ['sender_id' => $sender_id, 'type' => $db_sms_type]),
                        ]);
                    }

                }
            } elseif ($user->can('view_numbers') && $input['originator'] == 'phone_number' && isset($input['phone_number'])) {

                $sender_id = $input['phone_number'];

                $number = PhoneNumbers::where('user_id', $user->id)->where('number', $sender_id)->where('status', 'assigned')->first();

                if ( ! $number) {
                    return response()->json([
                            'status'  => 'error',
                            'message' => __('locale.sender_id.sender_id_invalid', ['sender_id' => $sender_id]),
                    ]);
                }

                $capabilities = str_contains($number->capabilities, $capabilities_type);

                if ( ! $capabilities) {
                    return response()->json([
                            'status'  => 'error',
                            'message' => __('locale.sender_id.sender_id_sms_capabilities', ['sender_id' => $sender_id, 'type' => $db_sms_type]),
                    ]);
                }

            } elseif (isset($input['sender_id'])) {
                $sender_id = $input['sender_id'];
            }

            $message = null;
            if (isset($input['message'])) {
                $message = $input['message'];
            }

            $coverage = PlansCoverageCountries::where('plan_id', $user->customer->activeSubscription()->plan_id)->first();

            if ( ! $coverage) {
                return response()->json([
                        'status'  => 'error',
                        'message' => "Permission to send an SMS has not been enabled for the region indicated by the 'To' number: ".$input['recipient'],
                ]);
            }

            if (isset($input['api_key']) || isset($input['exist_c_code'])) {

                $country_list = Country::where('country_code', $input['country_code'])->where('status', 1)->get();
                if ($country_list->count() > 1) {

                    $coverage_list = PlansCoverageCountries::where('plan_id', $user->customer->activeSubscription()->plan_id)->select('country_id')->get()->pluck('country_id')->toArray();

                    $filtered = $country_list->pluck('id')->filter(function ($value, $key) use ($coverage_list) {
                        return in_array($value, $coverage_list);
                    });

                    $country = Country::find($filtered->first());

                } else {
                    $country = $country_list->first();
                }

                if ($country->country_code != $input['country_code']) {
                    return response()->json([
                            'status'  => 'error',
                            'message' => "Permission to send an SMS has not been enabled for the region indicated by the 'To' number: ".$input['recipient'],
                    ]);
                }

            } else {
                $country = Country::find($input['country_code']);
            }
            if ( ! $country) {
                return response()->json([
                        'status'  => 'error',
                        'message' => "Permission to send an SMS has not been enabled for the region indicated by the 'To' number: ".$input['recipient'],
                ]);
            }

            $country_code = $country->country_code;

            $coverage = PlansCoverageCountries::where('country_id', $country->id)->where('plan_id', $user->customer->activeSubscription()->plan_id)->first();

            if ( ! $coverage) {
                return response()->json([
                        'status'  => 'error',
                        'message' => "Permission to send an SMS has not been enabled for the region indicated by the 'To' number: ".$input['recipient'],
                ]);
            }

            $priceOption = json_decode($coverage->options, true);

            $price = 0;

            $sms_counter  = new SMSCounter();
            $message_data = $sms_counter->count($message);
            $sms_count    = $message_data->messages;

            if ($sms_type == 'plain' || $sms_type == 'unicode') {
                $unit_price = $priceOption['plain_sms'];
                $price      = $sms_count * $unit_price;
            }

            if ($sms_type == 'voice') {
                $unit_price = $priceOption['voice_sms'];
                $price      = $sms_count * $unit_price;
            }

            if ($sms_type == 'mms') {

                if ($message_data->messages == 0) {
                    $sms_count = 1;
                }

                $unit_price = $priceOption['mms_sms'];
                $price      = $sms_count * $unit_price;
            }

            if ($sms_type == 'whatsapp') {
                $unit_price = $priceOption['whatsapp_sms'];
                $price      = $sms_count * $unit_price;
            }

            $price = (int) $price;

            if ($user->sms_unit != '-1') {

                if ($price > $user->sms_unit) {
                    return response()->json([
                            'status'  => 'error',
                            'message' => __('locale.campaigns.not_enough_balance', [
                                    'current_balance' => $user->sms_unit,
                                    'campaign_price'  => $price,
                            ]),
                    ]);
                }
            }

            //prepared message data

//            $phone = Tool::strReplaceFirst($country_code, '', ltrim($input['recipient'], '0'));
//
            $preparedData = [
                    'user_id'        => $user->id,
                    'phone'          => $country_code.$input['recipient'],
                    'sender_id'      => $sender_id,
                    'message'        => $message,
                    'cost'           => $price,
                    'sending_server' => $sending_server,
                    'status'         => null,
                    'sms_type'       => $sms_type,
            ];

            if (isset($input['api_key'])) {
                $preparedData['api_key'] = $input['api_key'];
            }

            $data = null;

            if ($sms_type == 'plain' || $sms_type == 'unicode') {
                $data = $campaign->sendPlainSMS($preparedData);
            }

            if ($sms_type == 'voice') {
                $preparedData['language'] = $input['language'];
                $preparedData['gender']   = $input['gender'];

                $data = $campaign->sendVoiceSMS($preparedData);
            }

            if ($sms_type == 'mms') {
                if (isset($input['api_key'])) {
                    $preparedData['media_url'] = $input['media_url'];
                } else {
                    $preparedData['media_url'] = Tool::uploadImage($input['mms_file']);
                }


                $data = $campaign->sendMMS($preparedData);
            }

            if ($sms_type == 'whatsapp') {
                if (isset($input['mms_file'])) {
                    $preparedData['media_url'] = Tool::uploadImage($input['mms_file']);
                }

                $data = $campaign->sendWhatsApp($preparedData);
            }

            if (is_object($data)) {
                if ( ! empty($data->status)) {
                    if (substr_count($data->status, 'Delivered') == 1) {
                        if ($user->sms_unit != '-1') {

                            DB::transaction(function () use ($user, $price) {
                                $remaining_balance = $user->sms_unit - $price;
                                $user->lockForUpdate();
                                $user->update(['sms_unit' => $remaining_balance]);
                            });
                        }

                        return response()->json([
                                'status'  => 'success',
                                'data'    => $data,
                                'message' => __('locale.campaigns.message_successfully_delivered'),
                        ]);
                    } else {
                        return response()->json([
                                'status'  => 'info',
                                'message' => $data->status,
                                'data'    => $data,
                        ]);
                    }
                }
            }

            return response()->json([
                    'status'  => 'info',
                    'message' => __('locale.exceptions.something_went_wrong'),
                    'data'    => $data,
            ]);


        }

        return response()->json([
                'status'  => 'error',
                'message' => __('locale.subscription.no_active_subscription'),
        ]);

    }


    /**
     * @param  Campaigns  $campaign
     * @param  array  $input
     *
     * @return JsonResponse
     */
    public function campaignBuilder(Campaigns $campaign, array $input): JsonResponse
    {

        if (Auth::user()->sms_unit != '-1' && Auth::user()->sms_unit == 0) {
            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.campaigns.sending_limit_exceed'),
            ]);
        }

        $sms_type = $input['sms_type'];


        if (Auth::user()->customer->getOption('send_spam_message') == 'no') {
            $spamWords = SpamWord::all()->filter(function ($spamWord) use ($input) {
                if ( true === str_contains(strtolower($input['message']), strtolower($spamWord->word))) {
                    return true;
                }

                return false;
            });

            if ($spamWords->count()) {
                return response()->json([
                        'status'  => 'error',
                        'message' => 'Your message contains spam words.',
                ]);
            }
        }

        //create campaign
        $new_campaign = Campaigns::create([
                'user_id'       => Auth::user()->id,
                'campaign_name' => $input['name'],
                'message'       => $input['message'],
                'sms_type'      => $sms_type,
                'status'        => Campaigns::STATUS_NEW,
        ]);

        if ( ! $new_campaign) {
            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.exceptions.something_went_wrong'),
            ]);
        }

        if ($sms_type == 'unicode') {
            $db_sms_type = 'plain';
        } else {
            $db_sms_type = $sms_type;
        }

        if ($sms_type == 'plain' || $sms_type == 'unicode') {
            $capabilities_type = 'sms';
        } else {
            $capabilities_type = $sms_type;
        }

        $sending_servers = SendingServer::where($db_sms_type, 1)->where('status', 1)->find($input['sending_server']);

        if (empty($sending_servers)) {

            $new_campaign->delete();

            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.campaigns.sending_server_not_available'),
            ]);
        }


        $sender_id = null;
        if (Auth::user()->customer->getOption('sender_id_verification') == 'yes') {
            if (isset($input['originator'])) {
                if ($input['originator'] == 'sender_id') {

                    if ( ! isset($input['sender_id'])) {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_required'),
                        ]);
                    }

                    $sender_id = $input['sender_id'];

                    if (is_array($sender_id) && count($sender_id) > 0) {
                        $invalid   = [];
                        $senderids = Senderid::where('user_id', Auth::user()->id)
                                ->where('status', 'active')
                                ->select('sender_id')
                                ->cursor()
                                ->pluck('sender_id')
                                ->all();

                        foreach ($sender_id as $sender) {
                            if ( ! in_array($sender, $senderids)) {
                                $invalid[] = $sender;
                            }
                        }

                        if (count($invalid)) {

                            $new_campaign->delete();

                            return response()->json([
                                    'status'  => 'error',
                                    'message' => __('locale.sender_id.sender_id_invalid', ['sender_id' => $invalid[0]]),
                            ]);
                        }
                    } else {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_required'),
                        ]);
                    }
                } else {

                    if ( ! isset($input['phone_number'])) {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.phone_numbers_required'),
                        ]);
                    }

                    $sender_id = $input['phone_number'];

                    if (is_array($sender_id) && count($sender_id) > 0) {
                        $type_supported = [];
                        PhoneNumbers::where('user_id', Auth::user()->id)
                                ->where('status', 'assigned')
                                ->cursor()
                                ->reject(function ($number) use ($sender_id, &$type_supported, &$invalid, $capabilities_type) {
                                    if (in_array($number->number, $sender_id) && ! str_contains($number->capabilities, $capabilities_type)) {
                                        return $type_supported[] = $number->number;
                                    }

                                    return $sender_id;
                                })->all();

                        if (count($type_supported)) {

                            $new_campaign->delete();

                            return response()->json([
                                    'status'  => 'error',
                                    'message' => __('locale.sender_id.sender_id_sms_capabilities', ['sender_id' => $type_supported[0], 'type' => $db_sms_type]),
                            ]);
                        }
                    } else {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_required'),
                        ]);
                    }
                }
            } else {

                $new_campaign->delete();

                return response()->json([
                        'status'  => 'error',
                        'message' => __('locale.sender_id.sender_id_required'),
                ]);
            }
        } elseif (Auth::user()->can('view_numbers') && isset($input['originator']) && $input['originator'] == 'phone_number') {
            $sender_id = $input['phone_number'];

            if (is_array($sender_id) && count($sender_id) > 0) {
                $type_supported = [];
                PhoneNumbers::where('user_id', Auth::user()->id)
                        ->where('status', 'assigned')
                        ->cursor()
                        ->reject(function ($number) use ($sender_id, &$type_supported, &$invalid, $capabilities_type) {
                            if (in_array($number->number, $sender_id) && ! str_contains($number->capabilities, $capabilities_type)) {
                                return $type_supported[] = $number->number;
                            }

                            return $sender_id;
                        })->all();

                if (count($type_supported)) {

                    $new_campaign->delete();

                    return response()->json([
                            'status'  => 'error',
                            'message' => __('locale.sender_id.sender_id_sms_capabilities', ['sender_id' => $type_supported[0], 'type' => $db_sms_type]),
                    ]);
                }
            } else {

                $new_campaign->delete();

                return response()->json([
                        'status'  => 'error',
                        'message' => __('locale.sender_id.sender_id_required'),
                ]);
            }
        } else {
            if (isset($input['originator'])) {
                if ($input['originator'] == 'sender_id') {
                    if ( ! isset($input['sender_id'])) {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_required'),
                        ]);
                    }

                    $sender_id = $input['sender_id'];
                } else {

                    if ( ! isset($input['phone_number'])) {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.phone_numbers_required'),
                        ]);
                    }

                    $sender_id = $input['phone_number'];
                }

                if ( ! is_array($sender_id) || count($sender_id) <= 0) {

                    $new_campaign->delete();

                    return response()->json([
                            'status'  => 'error',
                            'message' => __('locale.sender_id.sender_id_required'),
                    ]);
                }
            }
            if (isset($input['sender_id'])) {
                $sender_id           = $input['sender_id'];
                $input['originator'] = 'sender_id';
            }
        }

        $sender_id = array_filter($sender_id);
        if (count($sender_id)) {
            foreach ($sender_id as $id) {

                $data = [
                        'campaign_id' => $new_campaign->id,
                        'sender_id'   => $id,
                ];

                if (isset($input['originator'])) {
                    $data['originator'] = $input['originator'];
                }

                CampaignsSenderid::create($data);
            }
        }

        $total = 0;

        // update contact groups details
        if (isset($input['contact_groups']) && is_array($input['contact_groups']) && count($input['contact_groups']) > 0) {
            $contact_groups = ContactGroups::whereIn('id', $input['contact_groups'])->where('status', true)->where('customer_id', Auth::user()->id)->cursor();
            foreach ($contact_groups as $group) {
                $total += $group->subscribersCount($group->cache);
                CampaignsList::create([
                        'campaign_id'     => $new_campaign->id,
                        'contact_list_id' => $group->id,
                ]);
            }
        }

        // update manual input numbers
        if (isset($input['recipients'])) {
            $recipients = match ($input['delimiter']) {
                ',' => explode(',', $input['recipients']),
                ';' => explode(';', $input['recipients']),
                '|' => explode('|', $input['recipients']),
                'tab' => explode(' ', $input['recipients']),
                'new_line' => explode("\n", $input['recipients']),
                default => [],
            };

            $recipients = collect($recipients)->unique();

            $total += $recipients->count();

            $numbers = [];

            if ($input['country_code'] == 0) {
                $country_code = null;
            } else {
                $country_code = Country::find($input['country_code'])->country_code;
            }

            foreach ($recipients->chunk(500) as $chunk) {
                foreach ($chunk as $number) {
                    $number    = $country_code.$number;
                    $numbers[] = [
                            'campaign_id' => $new_campaign->id,
                            'recipient'   => preg_replace("/\r/", "", $number),
                            'created_at'  => Carbon::now(),
                            'updated_at'  => Carbon::now(),
                    ];
                }
            }
            CampaignsRecipients::insert($numbers);
        }

        if ($total == 0) {

            $new_campaign->delete();

            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.campaigns.contact_not_found'),
            ]);
        }

        if (Auth::user()->sms_unit != '-1') {
            $coverage = PlansCoverageCountries::where('plan_id', $input['plan_id'])->first();

            if ( ! $coverage) {
                return response()->json([
                        'status'  => 'error',
                        'message' => "Please add coverage on your plan.",
                ]);
            }

            $priceOption = json_decode($coverage->options, true);

            $sms_count = 1;
            $price     = 0;

            if (isset($input['message'])) {
                $sms_counter  = new SMSCounter();
                $message_data = $sms_counter->count($input['message']);
                $sms_count    = $message_data->messages;
            }


            if ($sms_type == 'plain' || $sms_type == 'unicode') {
                $unit_price = $priceOption['plain_sms'];
                $price      = $total * $unit_price;
            }

            if ($sms_type == 'voice') {
                $unit_price = $priceOption['voice_sms'];
                $price      = $total * $unit_price;
            }

            if ($sms_type == 'mms') {
                $unit_price = $priceOption['mms_sms'];
                $price      = $total * $unit_price;
            }

            if ($sms_type == 'whatsapp') {
                $unit_price = $priceOption['whatsapp_sms'];
                $price      = $total * $unit_price;
            }

            $price *= $sms_count;

            $balance = Auth::user()->sms_unit;

            if ($price > $balance) {

                $new_campaign->delete();

                return response()->json([
                        'status'  => 'error',
                        'message' => __('locale.campaigns.not_enough_balance', [
                                'current_balance' => $balance,
                                'campaign_price'  => $price,
                        ]),
                ]);
            }
        }

        CampaignsSendingServer::create([
                'campaign_id'       => $new_campaign->id,
                'sending_server_id' => $sending_servers->id,
                'fitness'           => 100,
        ]);


        if (isset($input['advanced']) && $input['advanced'] == "true") {
            if (isset($input['send_copy']) && $input['send_copy'] == "true") {
                Auth::user()->notify(new SendCampaignCopy($input['message'], route('customer.reports.campaign.edit', $new_campaign->uid)));
            }
            // if advanced set true then work with send copy to email and create template
            if (isset($input['create_template']) && $input['create_template'] == "true") {
                // create sms template
                Templates::create([
                        'user_id' => Auth::user()->id,
                        'name'    => $input['name'],
                        'message' => $input['message'],
                        'status'  => true,
                ]);
            }
        }

        // if schedule is available then check date, time and timezone
        if (isset($input['schedule']) && $input['schedule'] == "true") {

            $schedule_date = $input['schedule_date'].' '.$input['schedule_time'];
            $schedule_time = Tool::systemTimeFromString($schedule_date, $input['timezone']);

            $new_campaign->timezone      = $input['timezone'];
            $new_campaign->status        = Campaigns::STATUS_SCHEDULED;
            $new_campaign->schedule_time = $schedule_time;


            if ($input['frequency_cycle'] == 'onetime') {
                // working with onetime schedule
                $new_campaign->schedule_type = Campaigns::TYPE_ONETIME;
            } else {
                // working with recurring schedule
                //if schedule time frequency is not one time then check frequency details
                $recurring_date = $input['recurring_date'].' '.$input['recurring_time'];
                $recurring_end  = Tool::systemTimeFromString($recurring_date, $input['timezone']);

                $new_campaign->schedule_type = Campaigns::TYPE_RECURRING;
                $new_campaign->recurring_end = $recurring_end;

                if (isset($input['frequency_cycle'])) {
                    if ($input['frequency_cycle'] != 'custom') {
                        $schedule_cycle                 = $campaign::scheduleCycleValues();
                        $limits                         = $schedule_cycle[$input['frequency_cycle']];
                        $new_campaign->frequency_cycle  = $input['frequency_cycle'];
                        $new_campaign->frequency_amount = $limits['frequency_amount'];
                        $new_campaign->frequency_unit   = $limits['frequency_unit'];
                    } else {
                        $new_campaign->frequency_cycle  = $input['frequency_cycle'];
                        $new_campaign->frequency_amount = $input['frequency_amount'];
                        $new_campaign->frequency_unit   = $input['frequency_unit'];
                    }
                }
            }
        } else {
            $new_campaign->status = Campaigns::STATUS_QUEUED;
        }

        //update cache
        $new_campaign->cache = json_encode([
                'ContactCount'         => $total,
                'DeliveredCount'       => 0,
                'FailedDeliveredCount' => 0,
                'NotDeliveredCount'    => 0,
        ]);

        if ($sms_type == 'voice') {
            $new_campaign->language = $input['language'];
            $new_campaign->gender   = $input['gender'];
        }

        if ($sms_type == 'mms') {
            $new_campaign->media_url = Tool::uploadImage($input['mms_file']);
        }

        if ($sms_type == 'whatsapp' && isset($input['mms_file'])) {
            $new_campaign->media_url = Tool::uploadImage($input['mms_file']);
        }

        //finally, store data and return response
        $camp = $new_campaign->save();

        if ($camp) {

            try {
                if (isset($schedule_time)) {
                    if ($input['frequency_cycle'] == 'onetime') {
                        $delay_minutes = Carbon::now()->diffInMinutes($schedule_time);
                        dispatch(new StoreCampaignJob($new_campaign->id))->delay(now()->addMinutes($delay_minutes));
                    }
                } else {
                    dispatch(new StoreCampaignJob($new_campaign->id));
                }

                return response()->json([
                        'status'  => 'success',
                        'message' => __('locale.campaigns.campaign_send_successfully'),
                ]);
            } catch (Throwable $exception) {
                $new_campaign->delete();

                return response()->json([
                        'status'  => 'error',
                        'message' => $exception->getMessage(),
                ]);
            }
        }

        $new_campaign->delete();

        return response()->json([
                'status'  => 'success',
                'message' => __('locale.exceptions.something_went_wrong'),
        ]);
    }


    /**
     * @param  Campaigns  $campaign
     * @param  array  $input
     *
     * @return JsonResponse
     */
    public function sendApi(Campaigns $campaign, array $input): JsonResponse
    {
        $user = User::where('status', true)->where('api_token', $input['api_key'])->first();

        if ( ! $user) {
            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.auth.user_not_exist'),
            ]);
        }

        if ($user->sms_unit != '-1' && $user->sms_unit == 0) {
            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.campaigns.sending_limit_exceed'),
            ]);
        }

        if ($user->customer->getOption('send_spam_message') == 'no') {
            $spamWords = SpamWord::all()->filter(function ($spamWord) use ($input) {
                if ( true === str_contains($input['message'], $spamWord->word)) {
                    return true;
                }

                return false;
            });

            if ($spamWords->count()) {
                return response()->json([
                        'status'  => 'error',
                        'message' => 'Your message contains spam words.',
                ]);
            }
        }


        $sms_type = $input['sms_type'];

        //create campaign
        $new_campaign = Campaigns::create([
                'user_id'       => $user->id,
                'campaign_name' => $input['name'],
                'message'       => $input['message'],
                'sms_type'      => $sms_type,
                'status'        => Campaigns::STATUS_NEW,
        ]);

        if ( ! $new_campaign) {
            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.exceptions.something_went_wrong'),
            ]);
        }

        if ($sms_type == 'unicode') {
            $db_sms_type = 'plain';
        } else {
            $db_sms_type = $sms_type;
        }

        $sending_servers = SendingServer::where($db_sms_type, 1)->where('status', 1)->first();

        if (empty($sending_servers)) {

            $new_campaign->delete();

            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.campaigns.sending_server_not_available'),
            ]);
        }


        $sender_id = null;
        if ($user->customer->getOption('sender_id_verification') == 'yes') {
            if (isset($input['originator'])) {
                if ($input['originator'] == 'sender_id') {

                    if ( ! isset($input['sender_id'])) {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_required'),
                        ]);
                    }

                    $sender_id = $input['sender_id'];

                    if (is_array($sender_id) && count($sender_id) > 0) {
                        $invalid   = [];
                        $senderids = Senderid::where('user_id', $user->id)
                                ->where('status', 'active')
                                ->select('sender_id')
                                ->cursor()
                                ->pluck('sender_id')
                                ->all();

                        foreach ($sender_id as $sender) {
                            if ( ! in_array($sender, $senderids)) {
                                $invalid[] = $sender;
                            }
                        }

                        if (count($invalid)) {

                            $new_campaign->delete();

                            return response()->json([
                                    'status'  => 'error',
                                    'message' => __('locale.sender_id.sender_id_invalid', ['sender_id' => $invalid[0]]),
                            ]);
                        }
                    } else {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_required'),
                        ]);
                    }
                } else {
                    $new_campaign->delete();

                    return response()->json([
                            'status'  => 'error',
                            'message' => __('locale.sender_id.sender_id_required'),
                    ]);
                }
            } else {

                $new_campaign->delete();

                return response()->json([
                        'status'  => 'error',
                        'message' => __('locale.sender_id.sender_id_required'),
                ]);
            }
        } else {
            if (isset($input['originator'])) {
                if ($input['originator'] == 'sender_id') {
                    if ( ! isset($input['sender_id'])) {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_required'),
                        ]);
                    }

                    $sender_id = $input['sender_id'];
                } else {
                    $new_campaign->delete();

                    return response()->json([
                            'status'  => 'error',
                            'message' => __('locale.sender_id.sender_id_required'),
                    ]);
                }

                if ( ! is_array($sender_id) || count($sender_id) <= 0) {

                    $new_campaign->delete();

                    return response()->json([
                            'status'  => 'error',
                            'message' => __('locale.sender_id.sender_id_required'),
                    ]);
                }
            }
            if (isset($input['sender_id'])) {
                $sender_id = $input['sender_id'];
            }
        }

        $sender_id = array_filter($sender_id);


        if (count($sender_id)) {
            foreach ($sender_id as $id) {

                $data = [
                        'campaign_id' => $new_campaign->id,
                        'sender_id'   => $id,
                ];

                if (isset($input['originator'])) {
                    $data['originator'] = $input['originator'];
                }

                CampaignsSenderid::create($data);
            }
        }

        // update manual input numbers
        $recipients = explode(',', $input['recipients']);

        if (is_array($recipients) && count($recipients) == 0) {

            $new_campaign->delete();

            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.campaigns.contact_not_found'),
            ]);
        }
        $numbers = [];


        foreach ($recipients as $number) {
            $numbers[] = [
                    'campaign_id' => $new_campaign->id,
                    'recipient'   => preg_replace("/\r/", "", $number),
                    'created_at'  => Carbon::now(),
                    'updated_at'  => Carbon::now(),
            ];
        }

        CampaignsRecipients::insert($numbers);

        $total = count($recipients);

        if ($user->sms_unit != '-1') {
            $sms_count = 1;
            $price     = 0;

            if (isset($input['message'])) {
                $sms_counter  = new SMSCounter();
                $message_data = $sms_counter->count($input['message']);
                $sms_count    = $message_data->messages;
            }


            if ($sms_type == 'plain' || $sms_type == 'unicode') {
                $unit_price = $user->customer->getOption('plain_sms');
                $price      = $total * $unit_price;
            }

            if ($sms_type == 'voice') {
                $unit_price = $user->customer->getOption('voice_sms');
                $price      = $total * $unit_price;
            }

            if ($sms_type == 'mms') {
                $unit_price = $user->customer->getOption('mms_sms');
                $price      = $total * $unit_price;
            }

            if ($sms_type == 'whatsapp') {
                $unit_price = $user->customer->getOption('whatsapp_sms');
                $price      = $total * $unit_price;
            }

            $price *= $sms_count;

            $balance = $user->sms_unit;

            if ($price > $balance) {

                $new_campaign->delete();

                return response()->json([
                        'status'  => 'error',
                        'message' => __('locale.campaigns.not_enough_balance', [
                                'current_balance' => $balance,
                                'campaign_price'  => $price,
                        ]),
                ]);
            }
        }

        CampaignsSendingServer::create([
                'campaign_id'       => $new_campaign->id,
                'sending_server_id' => $sending_servers->id,
                'fitness'           => 100,
        ]);


        // if schedule is available then check date, time and timezone
        if (isset($input['schedule']) && $input['schedule']) {

            $schedule_date = $input['schedule_date'].' '.$input['schedule_time'];

            $schedule_time = Tool::systemTimeFromString($schedule_date, $input['timezone']);

            $new_campaign->timezone      = $input['timezone'];
            $new_campaign->status        = Campaigns::STATUS_SCHEDULED;
            $new_campaign->schedule_time = $schedule_time;

            $new_campaign->schedule_type = Campaigns::TYPE_ONETIME;

        } else {
            $new_campaign->status = Campaigns::STATUS_QUEUED;
        }

        //update cache
        $new_campaign->cache = json_encode([
                'ContactCount'         => $total,
                'DeliveredCount'       => 0,
                'FailedDeliveredCount' => 0,
                'NotDeliveredCount'    => 0,
        ]);

        if ($sms_type == 'voice') {
            $new_campaign->language = $input['language'];
            $new_campaign->gender   = $input['gender'];
        }

        if ($sms_type == 'mms') {
            $new_campaign->media_url = $input['media_url'];
        }

        //finally, store data and return response
        $camp = $new_campaign->save();

        if ($camp) {

            try {
                if (isset($schedule_time)) {
                    $delay_minutes = Carbon::now()->diffInMinutes($schedule_time);
                    dispatch(new StoreCampaignJob($new_campaign->id))->delay(now()->addMinutes($delay_minutes));
                } else {
                    dispatch(new StoreCampaignJob($new_campaign->id));
                }

                return response()->json([
                        'status'  => 'success',
                        'message' => __('locale.campaigns.campaign_send_successfully'),
                ]);
            } catch (Throwable $exception) {
                $new_campaign->delete();

                return response()->json([
                        'status'  => 'error',
                        'message' => $exception->getMessage(),
                ]);
            }
        }

        $new_campaign->delete();

        return response()->json([
                'status'  => 'success',
                'message' => __('locale.exceptions.something_went_wrong'),
        ]);
    }

    /**
     * send message using file
     *
     * @param  Campaigns  $campaign
     * @param  array  $input
     *
     * @return JsonResponse
     */
    public function sendUsingFile(Campaigns $campaign, array $input): JsonResponse
    {

        if (Auth::user()->sms_unit != '-1' && Auth::user()->sms_unit == 0) {
            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.campaigns.sending_limit_exceed'),
            ]);
        }

        $data     = CsvData::find($input['csv_data_file_id']);
        $csv_data = json_decode($data->csv_data, true);

        $db_fields = $input['fields'];

        $form_data = json_decode($input['form_data'], true);

        if (is_array($db_fields) && ! in_array('phone', $db_fields)) {
            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.filezone.phone_number_column_require'),
            ]);
        }

        $collection = collect($csv_data)->skip($data->csv_header);

        $total = $collection->count();

        if ($total == 0) {

            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.campaigns.contact_not_found'),
            ]);
        }

        if (Auth::user()->customer->getOption('send_spam_message') == 'no') {
            $spamWords = SpamWord::all()->filter(function ($spamWord) use ($input) {
                if ( true === str_contains(strtolower($input['message']), strtolower($spamWord->word))) {
                    return true;
                }

                return false;
            });

            if ($spamWords->count()) {
                return response()->json([
                        'status'  => 'error',
                        'message' => 'Your message contains spam words.',
                ]);
            }
        }


        //create campaign
        $new_campaign = Campaigns::create([
                'user_id'       => Auth::user()->id,
                'campaign_name' => $form_data['name'],
                'sms_type'      => $form_data['sms_type'],
                'message'       => $input['message'],
                'upload_type'   => 'file',
                'status'        => Campaigns::STATUS_NEW,
        ]);

        if ( ! $new_campaign) {
            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.exceptions.something_went_wrong'),
            ]);
        }

        if ($form_data['sms_type'] == 'unicode') {
            $db_sms_type = 'plain';
        } else {
            $db_sms_type = $form_data['sms_type'];
        }

        if ($form_data['sms_type'] == 'plain' || $form_data['sms_type'] == 'unicode') {
            $capabilities_type = 'sms';
        } else {
            $capabilities_type = $form_data['sms_type'];
        }


        $sending_servers = SendingServer::where('status', 1)->where($db_sms_type, 1)->find($form_data['sending_server']);

        if (empty($sending_servers)) {

            $new_campaign->delete();

            return response()->json([
                    'status'  => 'error',
                    'message' => __('locale.campaigns.sending_server_not_available'),
            ]);
        }


        $sender_id = null;
        if (Auth::user()->customer->getOption('sender_id_verification') == 'yes') {
            if (isset($form_data['originator'])) {
                if ($form_data['originator'] == 'sender_id') {

                    if ( ! isset($form_data['sender_id'])) {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_required'),
                        ]);
                    }

                    $sender_id = $form_data['sender_id'];

                    if (is_array($sender_id) && count($sender_id) > 0) {
                        $invalid   = [];
                        $senderids = Senderid::where('user_id', Auth::user()->id)
                                ->where('status', 'active')
                                ->select('sender_id')
                                ->cursor()
                                ->pluck('sender_id')
                                ->all();

                        foreach ($sender_id as $sender) {
                            if ( ! in_array($sender, $senderids)) {
                                $invalid[] = $sender;
                            }
                        }

                        if (count($invalid)) {

                            $new_campaign->delete();

                            return response()->json([
                                    'status'  => 'error',
                                    'message' => __('locale.sender_id.sender_id_invalid', ['sender_id' => $invalid[0]]),
                            ]);
                        }
                    } else {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_required'),
                        ]);
                    }
                } else {

                    if ( ! isset($form_data['phone_number'])) {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.phone_numbers_required'),
                        ]);
                    }

                    $sender_id = $form_data['phone_number'];

                    if (is_array($sender_id) && count($sender_id) > 0) {
                        $type_supported = [];
                        PhoneNumbers::where('user_id', Auth::user()->id)
                                ->where('status', 'assigned')
                                ->cursor()
                                ->reject(function ($number) use ($sender_id, &$type_supported, &$invalid, $capabilities_type) {
                                    if (in_array($number->number, $sender_id) && ! str_contains($number->capabilities, $capabilities_type)) {
                                        return $type_supported[] = $number->number;
                                    }

                                    return $sender_id;
                                })->all();

                        if (count($type_supported)) {

                            $new_campaign->delete();

                            return response()->json([
                                    'status'  => 'error',
                                    'message' => __('locale.sender_id.sender_id_sms_capabilities', ['sender_id' => $type_supported[0], 'type' => $db_sms_type]),
                            ]);
                        }
                    } else {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_required'),
                        ]);
                    }
                }
            } else {

                $new_campaign->delete();

                return response()->json([
                        'status'  => 'error',
                        'message' => __('locale.sender_id.sender_id_required'),
                ]);
            }
        } elseif (Auth::user()->can('view_numbers') && isset($form_data['originator']) && $form_data['originator'] == 'phone_number') {
            $sender_id = $form_data['phone_number'];

            if (is_array($sender_id) && count($sender_id) > 0) {
                $type_supported = [];
                PhoneNumbers::where('user_id', Auth::user()->id)
                        ->where('status', 'assigned')
                        ->cursor()
                        ->reject(function ($number) use ($sender_id, &$type_supported, &$invalid, $capabilities_type) {
                            if (in_array($number->number, $sender_id) && ! str_contains($number->capabilities, $capabilities_type)) {
                                return $type_supported[] = $number->number;
                            }

                            return $sender_id;
                        })->all();

                if (count($type_supported)) {

                    $new_campaign->delete();

                    return response()->json([
                            'status'  => 'error',
                            'message' => __('locale.sender_id.sender_id_sms_capabilities', ['sender_id' => $type_supported[0], 'type' => $db_sms_type]),
                    ]);
                }
            } else {

                $new_campaign->delete();

                return response()->json([
                        'status'  => 'error',
                        'message' => __('locale.sender_id.sender_id_required'),
                ]);
            }
        } else {
            if (isset($form_data['originator'])) {
                if ($form_data['originator'] == 'sender_id') {
                    if ( ! isset($form_data['sender_id'])) {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.sender_id_required'),
                        ]);
                    }

                    $sender_id = $form_data['sender_id'];
                } else {

                    if ( ! isset($form_data['phone_number'])) {

                        $new_campaign->delete();

                        return response()->json([
                                'status'  => 'error',
                                'message' => __('locale.sender_id.phone_numbers_required'),
                        ]);
                    }

                    $sender_id = $form_data['phone_number'];
                }

                if ( ! is_array($sender_id) || count($sender_id) <= 0) {

                    $new_campaign->delete();

                    return response()->json([
                            'status'  => 'error',
                            'message' => __('locale.sender_id.sender_id_required'),
                    ]);
                }
            }
            if (isset($form_data['sender_id'])) {
                $sender_id           = $form_data['sender_id'];
                $form_data['originator'] = 'sender_id';
            }
        }


        $sender_id = array_filter($sender_id);
        if (count($sender_id)) {
            foreach ($sender_id as $id) {

                $sender_id_data = [
                        'campaign_id' => $new_campaign->id,
                        'sender_id'   => $id,
                ];

                if (isset($form_data['originator'])) {
                    $sender_id_data['originator'] = $form_data['originator'];
                }

                CampaignsSenderid::create($sender_id_data);
            }
        }


        if (Auth::user()->sms_unit != '-1') {
            $coverage = PlansCoverageCountries::where('plan_id', $form_data['plan_id'])->first();

            if ( ! $coverage) {
                return response()->json([
                        'status'  => 'error',
                        'message' => "Please add coverage on your plan.",
                ]);
            }

            $priceOption = json_decode($coverage->options, true);
            $price       = 0;

            if ($form_data['sms_type'] == 'plain' || $form_data['sms_type'] == 'unicode') {
                $unit_price = $priceOption['plain_sms'];
                $price      = $total * $unit_price;
            }

            if ($form_data['sms_type'] == 'voice') {
                $unit_price = $priceOption['voice_sms'];
                $price      = $total * $unit_price;
            }

            if ($form_data['sms_type'] == 'mms') {
                $unit_price = $priceOption['mms_sms'];
                $price      = $total * $unit_price;
            }

            if ($form_data['sms_type'] == 'whatsapp') {
                $unit_price = $priceOption['whatsapp_sms'];
                $price      = $total * $unit_price;
            }

            $balance = Auth::user()->sms_unit;

            if ($price > $balance) {

                $new_campaign->delete();

                return response()->json([
                        'status'  => 'error',
                        'message' => __('locale.campaigns.not_enough_balance', [
                                'current_balance' => $balance,
                                'campaign_price'  => $price,
                        ]),
                ]);
            }
        }

        CampaignsSendingServer::create([
                'campaign_id'       => $new_campaign->id,
                'sending_server_id' => $sending_servers->id,
                'fitness'           => 100,
        ]);


        // if schedule is available then check date, time and timezone
        if (isset($form_data['schedule']) && $form_data['schedule'] == "true") {

            $schedule_date = $form_data['schedule_date'].' '.$form_data['schedule_time'];
            $schedule_time = Tool::systemTimeFromString($schedule_date, $form_data['timezone']);

            $new_campaign->timezone      = $form_data['timezone'];
            $new_campaign->status        = Campaigns::STATUS_SCHEDULED;
            $new_campaign->schedule_type = Campaigns::TYPE_ONETIME;
            $new_campaign->schedule_time = $schedule_time;
        } else {
            $new_campaign->status = Campaigns::STATUS_QUEUED;
        }


        //update cache
        $new_campaign->cache = json_encode([
                'ContactCount'         => $total,
                'DeliveredCount'       => 0,
                'FailedDeliveredCount' => 0,
                'NotDeliveredCount'    => 0,
        ]);

        if ($form_data['sms_type'] == 'voice') {
            $new_campaign->language = $form_data['language'];
            $new_campaign->gender   = $form_data['gender'];
        }

        if ($form_data['sms_type'] == 'mms') {
            $new_campaign->media_url = $form_data['media_url'];
        }

        //finally, store data and return response
        $camp = $new_campaign->save();

        if ($camp) {

            try {
                if (isset($schedule_time)) {
                    $delay_minutes = Carbon::now()->diffInMinutes($schedule_time);
                    dispatch(new ScheduleBatchJob(Auth::user()->id, $new_campaign->id, $collection, $db_fields, $csv_data[0]))->delay(now()->addMinutes($delay_minutes));

                    return response()->json([
                            'status'  => 'success',
                            'message' => __('locale.campaigns.campaign_successfully_imported_in_background'),
                    ]);

                }

                $batch_list = [];
                Tool::resetMaxExecutionTime();
                $collection->chunk(5000)
                        ->each(function ($lines) use ($new_campaign, &$batch_list, $db_fields, $csv_data) {
                            $batch_list[] = new ImportCampaign(Auth::user()->id, $new_campaign->id, $lines, $db_fields, $csv_data[0]);
                        });

                $import_name = 'ImportCampaigns_'.date('Ymdhms');

                $import_job = ImportJobHistory::create([
                        'name'      => $import_name,
                        'import_id' => $new_campaign->uid,
                        'type'      => 'import_campaign',
                        'status'    => 'processing',
                        'options'   => json_encode(['status' => 'processing', 'message' => 'Import campaign are running']),
                        'batch_id'  => null,
                ]);

                $batch = Bus::batch($batch_list)
                        ->then(function (Batch $batch) use ($new_campaign, $import_name, $import_job) {
                            $new_campaign->processing();
                            $new_campaign->update(['batch_id' => $batch->id]);
                            $import_job->update(['batch_id' => $batch->id]);
                        })
                        ->catch(function (Batch $batch, Throwable $e) {
                            $import_history = ImportJobHistory::where('batch_id', $batch->id)->first();
                            if ($import_history) {
                                $import_history->status  = 'failed';
                                $import_history->options = json_encode(['status' => 'failed', 'message' => $e->getMessage()]);
                                $import_history->save();
                            }

                        })
                        ->finally(function (Batch $batch) use ($new_campaign, $data) {
                            $import_history = ImportJobHistory::where('batch_id', $batch->id)->first();
                            if ($import_history) {
                                $import_history->status  = 'finished';
                                $import_history->options = json_encode(['status' => 'finished', 'message' => 'Import campaign was successfully imported.']);
                                $import_history->save();
                                Campaigns::find($new_campaign->id)->delivered();
                            }

                            $data->delete();
                            //send event notification remaining
                        })
                        ->name($import_name)
                        ->allowFailures(false)
                        ->dispatch();

                $new_campaign->update(['batch_id' => $batch->id]);

                return response()->json([
                        'status'  => 'success',
                        'message' => __('locale.campaigns.campaign_successfully_imported_in_background'),
                ]);


            } catch (Throwable $exception) {
                $new_campaign->delete();

                return response()->json([
                        'status'  => 'error',
                        'message' => $exception->getMessage(),
                ]);
            }
        }

        $new_campaign->delete();

        return response()->json([
                'status'  => 'error',
                'message' => __('locale.exceptions.something_went_wrong'),
        ]);
    }

    /**
     * @inheritDoc
     */
    public function cancel(Campaigns $campaign)
    {
        // TODO: Implement cancel() method.
    }

    /**
     * @inheritDoc
     */
    public function pause(Campaigns $campaign)
    {
        // TODO: Implement pause() method.
    }

    /**
     * @inheritDoc
     */
    public function destroy(Campaigns $campaign)
    {
        // TODO: Implement destroy() method.
    }

    /**
     * @inheritDoc
     */
    public function update(Campaigns $campaign, array $input)
    {
        // TODO: Implement update() method.
    }

    /**
     * @inheritDoc
     */
    public function resend(Campaigns $campaign)
    {
        // TODO: Implement resend() method.
    }
}

© 2025 UnknownSec
afwwrfwafr45458465
Password