HEX
Server: nginx/1.18.0
System: Linux test-ipsremont 5.4.0-214-generic #234-Ubuntu SMP Fri Mar 14 23:50:27 UTC 2025 x86_64
User: ips (1000)
PHP: 8.0.30
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //var/www/quadcode/app/Helpers/ActiveCampaignHelper.php
<?php

namespace App\Helpers;

use Illuminate\Http\Client\Response;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Psr\Log\LoggerInterface;

class ActiveCampaignHelper
{

    // https://developers.activecampaign.com/

    private LoggerInterface $logger;
    private string $host;
    private string $token;

    const STATUS_ACTIVE = 1;
    const STATUS_UNSUBSCRIBED = 2;

    const CUSTOM_FIELD_LANDING_URL = '6';
    const CUSTOM_FIELD_UTM_SOURCE = '7';
    const CUSTOM_FIELD_UTM_MEDIUM = '8';
    const CUSTOM_FIELD_UTM_CAMPAIGN = '9';
    const CUSTOM_FIELD_UTM_CONTENT = '10';
    const CUSTOM_FIELD_UTM_TERMS = '11';
    const CUSTOM_FIELD_COUNTRY_BY_IP = '12';

    private static array $customFields = [
        'landing_url' => self::CUSTOM_FIELD_LANDING_URL,
        'utm_source' => self::CUSTOM_FIELD_UTM_SOURCE,
        'utm_medium' => self::CUSTOM_FIELD_UTM_MEDIUM,
        'utm_campaign' => self::CUSTOM_FIELD_UTM_CAMPAIGN,
        'utm_content' => self::CUSTOM_FIELD_UTM_CONTENT,
        'utm_term' => self::CUSTOM_FIELD_UTM_TERMS,
        'lang_by_browser' => self::CUSTOM_FIELD_COUNTRY_BY_IP,
    ];

    public function __construct()
    {
        $this->logger = Log::channel('activeCampaign');
        $this->host = env('ACTIVE_CAMPAIGN_HOST');
        $this->token = env('ACTIVE_CAMPAIGN_TOKEN');
    }

    public function check(): bool
    {
        return !empty($this->host) && !empty($this->token);
    }

    private function convertLead(array $data = []): array
    {
        $contact = ['email' => $data['email']];
        if (!empty($data['first_name'])) {
            $contact['firstName'] = $data['first_name'];
        }
        if (!empty($data['last_name'])) {
            $contact['lastName'] = $data['last_name'];
        }
        if (!empty($data['phone'])) {
            $contact['phone'] = $data['phone'];
        }
        $contact['fieldValues'] = [];

        foreach (self::$customFields as $field => $externalKey) {
            if (!empty($data[$field])) {
                $contact['fieldValues'][] = [
                    'field' => $externalKey,
                    'value' => $data[$field],
                ];
            }
        }

        return ['contact' => $contact];
    }

    private function request(string $method, string $apiMethod, array $data = [], string $title = ''): Response
    {
        $headers = ['Api-Token' => $this->token];

        $requestLog = [
            'method' => $method,
            'headers' => $headers,
            'host' => $this->host,
            'apiMethod' => $apiMethod,
        ];
        if (!empty($data)) {
            $requestLog['data'] = $data;
        }
        $this->logger->info($title . ' request', $requestLog);

        $time = microtime(true);
        $http = Http::withHeaders($headers);
        $response = match ($method) {
            'POST' => $http->post($this->host . $apiMethod, $data),
            default => $http->get($this->host . $apiMethod, $data),
        };
        $time = (microtime(true) - $time) * 1000000;
        if ($time < 250000) {
            // API has a rate limit of 5 requests per second per account.
            usleep(250000 - $time);
        }

        $responseLog = [
            'status' => $response->status(),
            'headers' => $response->headers(),
            'body' => $response->body(),
        ];

        if ($response->successful()) {
            $this->logger->info($title . ' response', $responseLog);
        } else {
            $this->logger->error($title . ' response', $responseLog);
        }

        return $response;
    }

    // MARK: - Lists

    public function getAllLists(int $limit = 20, int $offset = 0): Response
    {
        return $this->request('GET', '/api/3/lists', compact('limit', 'offset'));
    }

    // MARK: - Users

    public function me(): Response
    {
        return $this->request('GET', '/api/3/users/me', title: 'Search contact');
    }

    // MARK: - Contacts

    public function searchContact(array $filter): Response
    {
        return $this->request('GET', '/api/3/contacts', $filter, 'Search contact');
    }

    public function createContact(array $data): Response
    {
        $data = $this->convertLead($data);

        return $this->request('POST', '/api/3/contacts', $data, 'Create contact');
    }

    // MARK: - Contact lists

    public function updateListStatus(int $contactId, int $listId, int $status = self::STATUS_ACTIVE): Response
    {
        $data = [
            'contactList' => [
                'list' => $listId,
                'contact' => $contactId,
                'status' => $status,
            ],
        ];

        return $this->request('POST', '/api/3/contactLists', $data, 'Update list status');
    }

    public function subscribeContact(int $contactId, int $listId): Response
    {
        return $this->updateListStatus($contactId, $listId);
    }

    public function unsubscribeContact(int $contactId, int $listId): Response
    {
        return $this->updateListStatus($contactId, $listId, self::STATUS_UNSUBSCRIBED);
    }

}