HEX
Server: LiteSpeed
System: Linux s1049.use1.mysecurecloudhost.com 4.18.0-477.27.2.lve.el8.x86_64 #1 SMP Wed Oct 11 12:32:56 UTC 2023 x86_64
User: xedaptot (3356)
PHP: 8.3.31
Disabled: NONE
Upload Files
File: /home/xedaptot/ai.naniguide.com/app/Http/Controllers/Api/CampaignController.php
<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Model\Campaign;
use App\Services\TemplateService;

/**
 * /api/v1/campaigns - API controller for managing campaigns.
 */
class CampaignController extends Controller
{
    /**
     * Display all user's campaigns.
     *
     * GET /api/v1/campaigns
     *
     * @return \Illuminate\Http\Response
     */
    public function index(Request $request)
    {
        $user = \Auth::guard('api')->user();

        // Get page and per_page from request, with default values
        $page = $request->input('page', 1);
        $perPage = $request->input('per_page', 10);

        // Get campaigns with pagination
        $campaignsQuery = \App\Model\Campaign::getAll()
            ->with('email')
            ->where('customer_id', '=', $user->customer->id);

        $total = $campaignsQuery->count();
        $campaigns = $campaignsQuery->skip(($page - 1) * $perPage)->take($perPage)->get();

        $campaigns = $campaigns->map(function ($campaign, $key) {
            return [
                'id' => $campaign->id,
                'uid' => $campaign->uid,
                'name' => $campaign->name,
                'type' => $campaign->type,
                'subscribers' => \App\Library\Cache\AppCache::for($campaign)->read('SubscriberCount', 0),
                'sent_percent' => $campaign->isSending() ? $campaign->deliveredRate(true) : \App\Library\Cache\AppCache::for($campaign)->read('DeliveredRate', 0),
                'sent_label' => ($campaign->isSending() ? $campaign->deliveredCount() : \App\Library\Cache\AppCache::for($campaign)->read('DeliveredCount', 0)) . "/" . (\App\Library\Cache\AppCache::for($campaign)->read('SubscriberCount', 0)),
                'open_rate' => \App\Library\Cache\AppCache::for($campaign)->read('UniqOpenRate', 0),
                'click_rate' => \App\Library\Cache\AppCache::for($campaign)->read('ClickedRate', 0),
                'subject' => $campaign->subject,
                'plain' => $campaign->plain,
                'from_email' => $campaign->from_email,
                'from_name' => $campaign->from_name,
                'reply_to' => $campaign->reply_to,
                'status' => $campaign->status,
                'delivery_at' => $campaign->delivery_at,
                'created_at' => $campaign->created_at,
                'updated_at' => $campaign->updated_at,
            ];
        });

        return \Response::json($campaigns, 200);

        // return \Response::json([
        //     'data' => $campaigns,
        //     'pagination' => [
        //         'total' => $total,
        //         'count' => $campaigns->count(),
        //         'per_page' => $perPage,
        //         'current_page' => $page,
        //         'total_pages' => ceil($total / $perPage),
        //     ]
        // ], 200);
    }

    public function store(Request $request)
    {
        $user = \Auth::guard('api')->user();
        $campaign = $user->customer->local()->newDefaultCampaign();

        // authorize
        if (!$user->can('create', Campaign::class)) {
            return \Response::json(array('status' => 0, 'message' => 'Unauthorized'), 403);
        }

        // validator
        $validator = \Validator::make($request->all(), [
            'name' => 'required',
            'subject' => 'required',
            'from_email' => 'required|email',
            'from_name' => 'required',
            'reply_to' => 'required|email',
            'html' => 'required',
        ]);

        if ($validator->fails()) {
            return response()->json($validator->messages(), 403);
        }

        // save from array
        $campaign->saveFromArray($request->all());

        // set template
        // Delete existing template
        // Find system template by alias
        $originalTemplate = \App\Model\SystemTemplate::getDefaultCampaignApiTemplate()->template;
        $newTemplate = $originalTemplate->copy();

        // @todo: tmp just replace HTML tag here
        $newTemplate->json = str_replace(
            '[HTML]',
            // remove outer quotes from json_encode(), keeping content safely escaped
            substr(json_encode($request->input('html'), JSON_UNESCAPED_UNICODE), 1, -1),
            $newTemplate->json
        );
        $newTemplate->content = str_replace(
            '[HTML]',
            $request->input('html'),
            $newTemplate->content
        );
        $newTemplate->save();

        // Then assign the already-customized template to the campaign email
        TemplateService::for($campaign->email)->replaceWithTemplate($newTemplate);
        $campaign->email->updatePlainFromHtml();
        $campaign->updateLinks();


        // success
        return \Response::json(array(
            'status' => 1,
            'message' => trans('messages.campaign.created'),
            'attributes' => $campaign->getAttributes(),
        ), 200);
    }

    public function update(Request $request, $id)
    {
        $user = \Auth::guard('api')->user();
        $campaign = \App\Model\Campaign::findByUid($id);

        // authorize
        if (!$user->can('update', $campaign)) {
            return \Response::json(array('status' => 0, 'message' => 'Unauthorized'), 403);
        }

        // validator
        $validator = \Validator::make($request->all(), [
        ]);

        if ($validator->fails()) {
            return response()->json($validator->messages(), 403);
        }

        // save from array
        $campaign->saveFromArray($request->all());

        // success
        return \Response::json(array(
            'status' => 1,
            'message' => trans('messages.campaign.updated'),
            'attributes' => $campaign->getAttributes(),
        ), 200);
    }

    /**
     * Display the specified campaign information.
     *
     * GET /api/v1/campaigns/{id}
     *
     * @param int $id Campaign's id
     *
     * @return \Illuminate\Http\Response
     */
    public function show($id)
    {
        $user = \Auth::guard('api')->user();

        $item = \App\Model\Campaign::where('uid', '=', $id)
            ->first();

        // check if item exists
        if (!$item) {
            return \Response::json(array('message' => 'Campaign not found'), 404);
        }

        // authorize
        if (!$user->can('read', $item)) {
            return \Response::json(array('message' => 'Unauthorized'), 401);
        }

        // statistics
        $campaign = [
            'id' => $item->id,
            'uid' => $item->uid,
            'name' => $item->name,
            'list' => ($item->mailList ? $item->mailList->name : ''),
            'segment' => ($item->segment ? $item->segment->name : ''),
            'from_email' => $item->from_email,
            'from_name' => $item->from_name,
            'remind_message' => $item->remind_message,
            'status' => $item->status,
            'created_at' => $item->created_at,
            'updated_at' => $item->updated_at,
        ];

        // statistics
        $statistics = [
            'subscriber_count' => $item->subscribersCount(),
            'uniq_open_rate' => $item->openRate(),
            'delivered_rate' => $item->deliveredRate(),
            'unique_open_count' => $item->uniqueOpenCount(),
            'open_rate' => $item->openRate(),
            'uniq_open_count' => $item->openUniqCount(),
            'last_open' => ($item->lastOpen() ? $item->lastOpen()->created_at : ''),
            'click_rate' => $item->clickRate(),
            'click_count' => $item->clickCount(),
            'abuse_feedback_count' => $item->abuseFeedbackCount(),
            'last_click' => ($item->lastClick() ? $item->lastClick()->created_at : ''),
            'click_count' => $item->clickCount(),
            'bounce_count' => $item->bounceCount(),
            'unsubscribe_count' => $item->unsubscribeCount(),
            'links' => $item->getTopLinks()->get()->pluck(['url']),
            'top_locations' => $item->topLocations()->get()->pluck('ip_address'),
            'top_active_subscribers' => $item->getTopActiveSubscribers()->get()->map(function ($i) {
                return [
                    'uid'    => $i->uid,
                    'email'  => $i->email,
                    'opens'  => (int) $i->opens,
                    'clicks' => (int) $i->clicks,
                ];
            }),
        ];

        return \Response::json(['campaign' => $campaign, 'statistics' => $statistics], 200);
    }

    /**
     * Pause campaign.
     *
     * GET /api/v1/campaigns/{id}
     *
     * @param int $id Campaign's id
     *
     * @return \Illuminate\Http\Response
     */
    public function pause($id)
    {
        $user = \Auth::guard('api')->user();

        $campaign = \App\Model\Campaign::where('uid', '=', $id)
            ->first();

        // check if item exists
        if (!$campaign) {
            return \Response::json(array('message' => 'Campaign not found'), 404);
        }

        // authorize
        if (!$user->can('pause', $campaign)) {
            return \Response::json(array('message' => 'Unauthorized'), 401);
        }

        $campaign->pause();

        // statistics
        $campaign = [
            'id' => $campaign->id,
            'uid' => $campaign->uid,
            'name' => $campaign->name,
            'list' => ($campaign->mailList ? $campaign->mailList->name : ''),
            'segment' => ($campaign->segment ? $campaign->segment->name : ''),
            'from_email' => $campaign->from_email,
            'from_name' => $campaign->from_name,
            'remind_message' => $campaign->remind_message,
            'status' => $campaign->status,
            'created_at' => $campaign->created_at,
            'updated_at' => $campaign->updated_at,
        ];

        return \Response::json([
            'status' => 'success',
            'message' => 'The campaign was paused',
            'campaign' => $campaign], 200);
    }

    public function run($id)
    {
        $user = \Auth::guard('api')->user();
        $campaign = \App\Model\Campaign::findByUid($id);

        // check if item exists
        if (!$campaign) {
            return \Response::json(array('message' => 'Campaign not found'), 404);
        }

        // authorize
        if (!$user->can('run', $campaign)) {
            return \Response::json(array('message' => 'Unauthorized'), 401);
        }

        if ($policyError = $campaign->validateLaunchPolicy($user->customer)) {
            return \Response::json(['message' => $policyError], 422);
        }

        // @todo
        $campaign->execute($force = false, ACM_QUEUE_TYPE_BATCH);

        // statistics
        $campaign = [
            'id' => $campaign->id,
            'uid' => $campaign->uid,
            'name' => $campaign->name,
            'list' => ($campaign->mailList ? $campaign->mailList->name : ''),
            'segment' => ($campaign->segment ? $campaign->segment->name : ''),
            'from_email' => $campaign->from_email,
            'from_name' => $campaign->from_name,
            'remind_message' => $campaign->remind_message,
            'status' => $campaign->status,
            'created_at' => $campaign->created_at,
            'updated_at' => $campaign->updated_at,
        ];

        return \Response::json([
            'status' => 'success',
            'message' => 'The campaign was launched',
            'campaign' => $campaign], 200);
    }

    public function resume($id)
    {
        $user = \Auth::guard('api')->user();
        $campaign = \App\Model\Campaign::findByUid($id);

        // check if item exists
        if (!$campaign) {
            return \Response::json(array('message' => 'Campaign not found'), 404);
        }

        // authorize
        if (!$user->can('resume', $campaign)) {
            return \Response::json(array('message' => 'Unauthorized'), 401);
        }

        // @todo
        $campaign->resume(ACM_QUEUE_TYPE_BATCH);

        // statistics
        $campaign = [
            'id' => $campaign->id,
            'uid' => $campaign->uid,
            'name' => $campaign->name,
            'list' => ($campaign->mailList ? $campaign->mailList->name : ''),
            'segment' => ($campaign->segment ? $campaign->segment->name : ''),
            'from_email' => $campaign->from_email,
            'from_name' => $campaign->from_name,
            'remind_message' => $campaign->remind_message,
            'status' => $campaign->status,
            'created_at' => $campaign->created_at,
            'updated_at' => $campaign->updated_at,
        ];

        return \Response::json([
            'status' => 'success',
            'message' => 'The campaign was resumed',
            'campaign' => $campaign], 200);
    }

    public function delete($uid)
    {
        $user = \Auth::guard('api')->user();
        $campaign = \App\Model\Campaign::findByUid($uid);

        // check if item exists
        if (!$campaign) {
            return \Response::json(array('status' => 0, 'message' => 'Campaign list not found'), 404);
        }

        // authorize
        if (!$user->can('delete', $campaign)) {
            return \Response::json(array('status' => 0, 'message' => 'Unauthorized'), 401);
        }

        $campaign->deleteAndCleanup();

        return \Response::json(array('status' => 1, 'message' => 'Deleted'), 200);
    }

    public function downloadTrackingLog(Request $request, $uid)
    {
        $user = \Auth::guard('api')->user();
        $campaign = \App\Model\Campaign::findByUid($uid);

        // Check if campaign exists
        if (!$campaign) {
            return \Response::json(['message' => 'Campaign not found'], 404);
        }

        // Authorize
        if (!$user->can('read', $campaign)) {
            return \Response::json(['message' => 'Unauthorized'], 401);
        }

        // Prepare CSV headers
        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="tracking_logs.csv"',
        ];

        // Generate CSV content
        $filePath = $campaign->generateTrackingLogCsv('tracking_logs');

        // Return CSV response
        return response()->download($filePath, $campaign->uid . '_tracking_logs.csv', $headers)
            ->deleteFileAfterSend(true);
    }

    public function downloadOpenLog(Request $request, $uid)
    {
        $user = \Auth::guard('api')->user();
        $campaign = \App\Model\Campaign::findByUid($uid);

        // Check if campaign exists
        if (!$campaign) {
            return \Response::json(['message' => 'Campaign not found'], 404);
        }

        // Authorize
        if (!$user->can('read', $campaign)) {
            return \Response::json(['message' => 'Unauthorized'], 401);
        }

        // Prepare CSV headers
        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="tracking_logs.csv"',
        ];

        // Generate CSV content
        $filePath = $campaign->generateTrackingLogCsv('open_logs');

        // Return CSV response
        return response()->download($filePath, $campaign->uid . '_open_logs.csv', $headers)
            ->deleteFileAfterSend(true);
    }

    public function downloadClickLog(Request $request, $uid)
    {
        $user = \Auth::guard('api')->user();
        $campaign = \App\Model\Campaign::findByUid($uid);

        // Check if campaign exists
        if (!$campaign) {
            return \Response::json(['message' => 'Campaign not found'], 404);
        }

        // Authorize
        if (!$user->can('read', $campaign)) {
            return \Response::json(['message' => 'Unauthorized'], 401);
        }

        // Prepare CSV headers
        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="tracking_logs.csv"',
        ];

        // Generate CSV content
        $filePath = $campaign->generateTrackingLogCsv('click_logs');

        // Return CSV response
        return response()->download($filePath, $campaign->uid . '_click_logs.csv', $headers)
            ->deleteFileAfterSend(true);
    }

    public function downloadBounceLog(Request $request, $uid)
    {
        $user = \Auth::guard('api')->user();
        $campaign = \App\Model\Campaign::findByUid($uid);

        // Check if campaign exists
        if (!$campaign) {
            return \Response::json(['message' => 'Campaign not found'], 404);
        }

        // Authorize
        if (!$user->can('read', $campaign)) {
            return \Response::json(['message' => 'Unauthorized'], 401);
        }

        // Prepare CSV headers
        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="tracking_logs.csv"',
        ];

        // Generate CSV content
        $filePath = $campaign->generateTrackingLogCsv('bounce_logs');

        // Return CSV response
        return response()->download($filePath, $campaign->uid . '_bounce_logs.csv', $headers)
            ->deleteFileAfterSend(true);
    }

    public function downloadFeedbackLog(Request $request, $uid)
    {
        $user = \Auth::guard('api')->user();
        $campaign = \App\Model\Campaign::findByUid($uid);

        // Check if campaign exists
        if (!$campaign) {
            return \Response::json(['message' => 'Campaign not found'], 404);
        }

        // Authorize
        if (!$user->can('read', $campaign)) {
            return \Response::json(['message' => 'Unauthorized'], 401);
        }

        // Prepare CSV headers
        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="tracking_logs.csv"',
        ];

        // Generate CSV content
        $filePath = $campaign->generateTrackingLogCsv('feedback_logs');

        // Return CSV response
        return response()->download($filePath, $campaign->uid . '_feedback_logs.csv', $headers)
            ->deleteFileAfterSend(true);
    }

    public function downloadUnsubscribeLog(Request $request, $uid)
    {
        $user = \Auth::guard('api')->user();
        $campaign = \App\Model\Campaign::findByUid($uid);

        // Check if campaign exists
        if (!$campaign) {
            return \Response::json(['message' => 'Campaign not found'], 404);
        }

        // Authorize
        if (!$user->can('read', $campaign)) {
            return \Response::json(['message' => 'Unauthorized'], 401);
        }

        // Prepare CSV headers
        $headers = [
            'Content-Type' => 'text/csv',
            'Content-Disposition' => 'attachment; filename="tracking_logs.csv"',
        ];

        // Generate CSV content
        $filePath = $campaign->generateTrackingLogCsv('unsubscribe_logs');

        // Return CSV response
        return response()->download($filePath, $campaign->uid . '_unsubscribe_logs.csv', $headers)
            ->deleteFileAfterSend(true);
    }

}