Spamworldpro Mini Shell
Spamworldpro


Server : Apache
System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64
User : corals ( 1002)
PHP Version : 7.4.33
Disable Function : exec,passthru,shell_exec,system
Directory :  /home/corals/job-board.corals.io/Corals/modules/Subscriptions/Classes/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/corals/job-board.corals.io/Corals/modules/Subscriptions/Classes/UsageManager.php
<?php

namespace Corals\Modules\Subscriptions\Classes;

use Corals\Modules\Subscriptions\Exceptions\LimitReachedException;
use Corals\Modules\Subscriptions\Facades\SubscriptionsManager as SubscriptionsManagerFacade;
use Corals\Modules\Subscriptions\Models\Feature;
use Corals\Modules\Subscriptions\Models\FeatureModel;
use Corals\Modules\Subscriptions\Models\PlanUsage;
use Corals\Modules\Utility\Models\ListOfValue\ListOfValue;
use Corals\Settings\Facades\Settings;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class UsageManager
{
    public function getModelFeatures($model, $subscription = null)
    {
        if (is_null($subscription) && func_num_args() === 1) {
            $subscription = $this->getUserSubscription();
        }

        if (!$subscription) {
            return [];
        }

        $plan = $subscription->plan;

        if (is_object($model)) {
            $modelClass = get_class($model);
        } else {
            $modelClass = $model;
        }

        $planFeaturesIds = $plan->features()->pluck('features.id')->toArray();

        $modelFeaturesIds = FeatureModel::query()->where('model', $modelClass)
            ->whereIn('feature_id', $planFeaturesIds)->pluck('feature_id')
            ->toArray();

        return $plan->features()->whereIn('feature_id', $modelFeaturesIds)->get();
    }

    /**
     * @param $model
     * @param $usageDetails
     * @param null $product
     * @param null $plan
     * @param null $user
     * @return null
     * @throws \Exception
     */
    public function recordAUsage($model, $usageDetails, $product = null, $plan = null, $user = null)
    {
        $subscription = $this->getUserSubscription($product, $plan, $user);

        $features = $this->getModelFeatures($model, $subscription);

        foreach ($features as $feature) {
            $cycleId = null;
            $currentCycle = null;

            if ($feature->per_cycle) {
                $currentCycle = SubscriptionsManagerFacade::getCurrentCycle($subscription);

                $cycleId = $currentCycle->id;
            }

            $reachedLimit = $this->isFeatureUsageReachedLimit($feature, $subscription, $currentCycle);

            if ($reachedLimit) {
                throw new LimitReachedException($subscription, $feature, $currentCycle);
            }

            PlanUsage::query()->create([
                'subscription_id' => $subscription->id,
                'feature_id' => $feature->id,
                'cycle_id' => $cycleId,
                'usage_details' => $usageDetails,
            ]);
        }
    }

    public function getUserSubscription($product = null, $plan = null, $user = null)
    {
        if (is_null($user)) {
            $user = user()->getOwner();
        }

        $subscription = $user->currentSubscription($product, $plan);

        if (!$subscription) {
            return null;
        }

        return $subscription;
    }

    /**
     * @param $model
     * @return bool
     * @throws \Exception
     */
    public function isModelUsageReachedLimit($model)
    {
        $subscription = $this->getUserSubscription();

        $features = $this->getModelFeatures($model, $subscription);

        $reachedLimit = false;

        foreach ($features as $feature) {
            $currentCycle = null;

            if ($feature->per_cycle) {
                $currentCycle = SubscriptionsManagerFacade::getCurrentCycle($subscription);
            }

            $reachedLimit = $this->isFeatureUsageReachedLimit($feature, $subscription, $currentCycle);

            if ($reachedLimit) {
                $this->flashLimitReachedMessage($feature);
                break;
            }
        }

        return $reachedLimit;
    }

    /**
     * @param $feature
     */
    protected function flashLimitReachedMessage($feature): void
    {
        push_to_general_site_notifications(
            $feature->limit_reached_message,
            'warning',
            "feature_{$feature->id}"
        );
    }

    /**
     * @param $feature
     * @param null $subscription
     * @param null $currentCycle
     * @return bool
     * @throws \Exception
     */
    public function isFeatureUsageReachedLimit($feature, $subscription = null, $currentCycle = null)
    {
        $reachedLimit = false;


        [$subscription, $currentCycle] = $this->getSubscriptionAndCycle($feature, $subscription, $currentCycle);

        $planFeature = $subscription->plan->features()->where('feature_id', $feature->id)->first();

        $usageQuery = $this->getFeatureUsageQuery($feature, $subscription, $currentCycle);

        switch ($planFeature->type) {
            case 'quantity':
                $usageCount = $usageQuery->count();

                if ($planFeature->pivot->value == $usageCount) {
                    $reachedLimit = true;
                }
                break;
            case 'boolean':
                $reachedLimit = $usageQuery->exists();
                break;
        }

        return $reachedLimit;
    }

    /**
     * @param $subscription
     * @param $currentCycle
     * @param $feature
     * @return \Illuminate\Database\Eloquent\Builder
     */
    protected function getFeatureUsageQuery($feature, $subscription, $currentCycle)
    {
        return PlanUsage::query()->where([
            ['subscription_id', '=', $subscription->id],
            ['cycle_id', '=', optional($currentCycle)->id],
            ['feature_id', '=', $feature->id],
        ]);
    }

    /**
     * @param $feature
     * @param null $subscription
     * @param null $currentCycle
     * @return array
     * @throws \Exception
     */
    protected function getSubscriptionAndCycle($feature, $subscription = null, $currentCycle = null): array
    {
        if (is_null($subscription)) {
            $subscription = $this->getUserSubscription();
        }

        if ($feature->per_cycle && is_null($currentCycle) && func_num_args() != 3) {
            $currentCycle = SubscriptionsManagerFacade::getCurrentCycle($subscription);
        }

        return [
            $subscription,
            $currentCycle
        ];
    }

    /**
     * @param Feature $feature
     * @param null $subscription
     * @param null $currentCycle
     * @return mixed
     * @throws \Exception
     */
    public function getFeatureUsageStatistics(Feature $feature, $subscription = null, $currentCycle = null)
    {
        [$subscription, $currentCycle] = $this->getSubscriptionAndCycle($feature, $subscription, $currentCycle);

        $featureUsageCount = $this->getFeatureUsageQuery($feature, $subscription, $currentCycle)->count();

        $planFeature = $subscription->plan->features()->where('feature_id', $feature->id)->first();


        if (method_exists($this, $method = sprintf("get%sFeatureStatistics", Str::studly($planFeature->type)))) {
            return $this->{$method}($feature, $featureUsageCount, $planFeature->pivot->value);
        }

        return [];
    }

    /**
     * @param $featureUsageCount
     * @param $featureLimit
     * @return array
     */
    protected function getQuantityFeatureStatistics($feature, $featureUsageCount, $featureLimit)
    {
        if ($featureLimit) {
            $usedPercentage = ($featureUsageCount / $featureLimit) * 100;
        }

        return [
            'feature_name' => $feature->name,
            'feature_caption' => $feature->caption,
            'feature_usage_count' => $featureUsageCount,
            'feature_limit' => $featureLimit,
            'used_percentage' => $usedPercentage ?? 0
        ];
    }

    /**
     * @param $model
     * @param null $model_id
     * @return \Illuminate\Database\Eloquent\Builder[]|\Illuminate\Database\Eloquent\Collection
     */
    public function getPlanUsageByModel($model, $model_id = null)
    {
        if (is_object($model)) {
            $modelClass = get_class($model);
        } else {
            $modelClass = $model;
        }

        $modelClass = addcslashes($modelClass, '\\');

        $modelTypeQueryString = sprintf("JSON_EXTRACT(usage_details, '$.model_type') = '%s'", $modelClass);

        $modelPlanUsage = PlanUsage::query()->whereRaw($modelTypeQueryString);

        if (!is_null($model_id)) {
            $modelIdQueryString = sprintf("JSON_EXTRACT(usage_details, '$.model_id') = %s", $model_id);

            $modelPlanUsage->whereRaw($modelIdQueryString);
        }

        return $modelPlanUsage->get();
    }


    /**
     * @param $feature
     * @param null $source
     * @param null $code
     * @return array
     */
    public function getSourceValues($feature, $source = null, $code = null)
    {
        if ($feature) {
            $extras = $feature->extras['config'] ?? [];
            $source = Arr::get($extras, 'source');
            $code = Arr::get($extras, 'code');
        }

        switch ($source) {
            case 'settings':
                return Settings::get($code, []);
            case 'list_of_values':
                return ListOfValue::query()->join('utility_list_of_values as children', 'utility_list_of_values.id',
                    'children.parent_id')
                    ->where('utility_list_of_values.code', $code)->pluck('children.value', 'children.id')->toArray();
            case 'config':
                return get_array_key_translation(config($code));
            default:
                return [];
        }
    }

    /**
     * @param $source
     * @param $code
     * @return array
     */
    public function getPlanFeatureConfig($source, $code): array
    {
        if (!($currentSubscription = user()->currentSubscription)) {
            return [];
        }


        $feature = $currentSubscription->plan->features()->whereRaw(
            "json_search(json_keys(extras),'one','config') is not null 
            AND 
        json_search(json_extract(extras,'$.config.source'),'one', ?) is not null
            AND
       json_search(json_extract(extras,'$.config.code'),'one', ?) is not null", [$source, $code]
        )->first();

        $sourceValues = $this->getSourceValues(null, $source, $code);

        if (!$feature) {
            return $sourceValues;
        }

        $featureKeys = explode(',', $feature->pivot->value);

        if (empty($featureKeys)) {
            return [];
        }

        return Arr::only($sourceValues, $featureKeys);
    }
}

Spamworldpro Mini