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/Model/EmailVerificationServer.php
<?php

namespace App\Model;

use Illuminate\Database\Eloquent\Model;
use App\Library\Traits\HasUid;
use Exception;
use Monolog\Logger;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Formatter\LineFormatter;
use App\Library\RateTracker;
use App\Library\DynamicRateTracker;
use App\Library\RateLimit;
use App\Library\RateTrackerInterface;
use App\Library\CreditTracker;
use App\Library\Contracts\CreditTrackerInterface;
use App\Verification\DriverRegistry;
use App\Verification\Drivers\VerificationDriver;

class EmailVerificationServer extends Model
{
    use HasUid;
    protected $connection = 'mysql';

    // set the table name
    protected $table = 'email_verification_servers';

    // Logger
    protected $logger;
    protected $service;
    private ?VerificationDriver $driverInstance = null;

    public const STATUS_ACTIVE = 'active';
    public const STATUS_INACTIVE = 'inactive';
    public const WAIT = 30;

    protected $fillable = ['type', 'name', 'options', 'status', 'admin_id', 'customer_id'];

    protected $casts = [
        'options' => 'array',
    ];

    /**
     * Driver registry accessor — single source of truth for verification vendor logic.
     * Single source of truth for vendor logic — see docs/verification/COMPREHENSIVE-DESIGN.md.
     */
    public function driver(): VerificationDriver
    {
        return $this->driverInstance ??= DriverRegistry::resolve($this);
    }

    public function newFromBuilder($attributes = [], $connection = null)
    {
        $model = parent::newFromBuilder($attributes, $connection);
        $model->driverInstance = null;
        return $model;
    }

    private const OTHERWISE = '*';

    /**
     * Associations.
     *
     * @var object | collect
     */
    public function customer()
    {
        return $this->belongsTo('App\Model\Customer');
    }

    public function admin()
    {
        return $this->belongsTo('App\Model\Admin');
    }


    /**
     * Verify a single email — delegates to the registry-resolved driver.
     */
    public function verify(string $email): array
    {
        return $this->driver()->verify($email);
    }

    /**
     * Items per page.
     *
     * @var array
     */
    public static $itemsPerPage = 25;

    /**
     * Filter items.
     *
     * @return collect
     */
    public static function filter($request)
    {
        $user = $request->user();
        $query = self::select('email_verification_servers.*');

        // Keyword
        if (!empty(trim($request->keyword))) {
            foreach (explode(' ', trim($request->keyword)) as $keyword) {
                $query = $query->where(function ($q) use ($keyword) {
                    $q->orwhere('email_verification_servers.name', 'like', '%'.$keyword.'%')
                        ->orWhere('email_verification_servers.type', 'like', '%'.$keyword.'%');
                });
            }
        }

        // filters
        $filters = $request->all();
        if (!empty($filters)) {
            if (!empty($filters['type'])) {
                $query = $query->where('email_verification_servers.type', '=', $filters['type']);
            }
        }

        // Other filter
        if (!empty($request->customer_id)) {
            $query = $query->where('email_verification_servers.customer_id', '=', $request->customer_id);
        }

        if (!empty($request->admin_id)) {
            $query = $query->where('email_verification_servers.admin_id', '=', $request->admin_id);
        }

        // remove customer sending servers
        if (!empty($request->no_customer)) {
            $query = $query->whereNull('customer_id');
        }

        return $query;
    }

    /**
     * Search items.
     *
     * @return collect
     */
    public static function search($request)
    {
        $query = self::filter($request);

        if (!empty($request->sort_order)) {
            $query = $query->orderBy($request->sort_order, $request->sort_direction);
        }

        return $query;
    }

    /**
     * Get campaign validation rules — base rules + per-vendor rules from driver class.
     */
    public function rules()
    {
        $rules = array(
            'name' => 'required',
            'type' => 'required',
            'options.limit_value' => 'required',
            'options.limit_base' => 'required',
            'options.limit_unit' => 'required',
        );

        if ($this->type && DriverRegistry::has($this->type)) {
            $registry = DriverRegistry::all();
            $driverClass = $registry[$this->type];
            $vendorRules = $driverClass::validationRules()['cols'] ?? [];
            foreach ($vendorRules as $field => $rule) {
                $rules['options.' . $field] = $rule;
            }
        }

        return $rules;
    }

    /**
     * Frequency time unit options.
     *
     * @return array
     */
    public static function quotaTimeUnitOptions()
    {
        return [
            ['value' => 'minute', 'text' => trans('messages.minute')],
            ['value' => 'hour', 'text' => trans('messages.hour')],
            ['value' => 'day', 'text' => trans('messages.day')],
        ];
    }

    /**
     * Server status select options.
     *
     * @return array
     */
    public static function statusSelectOptions()
    {
        return [
            ['value' => self::STATUS_ACTIVE, 'text' => trans('messages.email_verification_server_status_'.self::STATUS_ACTIVE)],
            ['value' => self::STATUS_INACTIVE, 'text' => trans('messages.email_verification_server_status_'.self::STATUS_INACTIVE)],
        ];
    }

    /**
     * Get all items.
     *
     * @return collect
     */
    public static function getAll()
    {
        return self::where('status', '=', 'active');
    }

    /**
     * Disable verification server.
     *
     * @return array
     */
    public function disable()
    {
        $this->status = self::STATUS_INACTIVE;
        $this->save();
    }

    /**
     * Enable verification server.
     *
     * @return array
     */
    public function enable()
    {
        $this->status = self::STATUS_ACTIVE;
        $this->save();
    }

    /**
     * Get all active items.
     *
     * @return collect
     */
    public static function getAllActive()
    {
        return self::where('status', '=', SendingServer::STATUS_ACTIVE);
    }

    /**
     * Get all active system items.
     *
     * @return collect
     */
    public static function getAllAdminActive()
    {
        return self::getAllActive()->fromSystem();
    }

    public static function scopeFromSystem($query)
    {
        return $query->whereNotNull('admin_id');
    }


    public function getSpeedLimitString()
    {
        $options = $this->options ?? [];

        return number_format($options['limit_value']) . " / {$options['limit_base']} {$options['limit_unit']}";
    }

    public function getTypeName()
    {
        if (!DriverRegistry::has($this->type)) {
            return 'Error: Driver not registered for type ' . $this->type;
        }
        $registry = DriverRegistry::all();
        $driverClass = $registry[$this->type];
        return $driverClass::displayName();
    }

    // For testing, do not save!
    public function setLimit(int $value, int $periodValue, string $periodUnit)
    {
        $options = $this->options ?? [];
        $options['limit_base'] = $periodValue;
        $options['limit_unit'] = $periodUnit;
        $options['limit_value'] = $value;
        $this->options = $options;
    }

    public function getRateTracker(): RateTrackerInterface
    {
        // server-level admin-configured rate limit (distinct from vendor's intrinsic limit
        // exposed via driver's HasRateLimit capability). Always 'verify' bucket.
        $options = $this->options ?? [];

        $limits = [];
        if ($options['limit_value'] != RateLimit::UNLIMITED) {
            $limits[] = new RateLimit(
                $options['limit_value'],
                $options['limit_base'],
                $options['limit_unit'],
                "Verification credits limit of {$options['limit_value']} per {$options['limit_base']} {$options['limit_unit']}",
            );
        }

        if (config('custom.distributed_mode')) {
            $key = 'verification-server-verify-email-rate-tracking-log-'.$this->uid;
            $tracker = new DynamicRateTracker($key, $limits);
        } else {
            $file = storage_path('app/quota/verification-server-verify-email-rate-tracking-log-'.$this->uid);
            $tracker = new RateTracker($file, $limits);
        }

        return $tracker;
    }

    public function getCreditTracker(): CreditTrackerInterface
    {
        $file = storage_path('app/quota/verification-server-credits-'.$this->uid);
        return new CreditTracker($file, $createFile = true, "Verification server credits for server \"{$this->name}\"");
    }

    public function logger()
    {
        if (is_null($this->logger)) {
            $formatter = new LineFormatter("[%datetime%] %channel%.%level_name%: %message%\n");
            $logfile = storage_path('logs/' . php_sapi_name() . "/everification-{$this->uid}-{$this->type}.log");
            $stream = new RotatingFileHandler($logfile, 0, 'debug');
            $stream->setFormatter($formatter);
            $pid = getmypid();
            $logger = new Logger($pid);
            $logger->pushHandler($stream);

            // Set
            $this->logger = $logger;
        }

        return $this->logger;
    }

    public static function newDefault()
    {
        $server =  new self();
        $server->status = self::STATUS_ACTIVE;

        return $server;
    }

    public function setOptions($options)
    {
        $this->options = json_encode($options);
    }
}