Campaigns.php 14.2 KB
<?php

namespace App\Models;

use App\Models\Pivots\DictionaryCampaignVariable;
use App\Models\Pivots\DictionaryCampaign;
use App\Models\Pivots\GoalAdGroup;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;

/**
 * App\Models\Campaigns
 *
 * @property int $id
 * @property int $token
 * @property int $external_id
 * @property string|null $name
 * @property array|null $time_targeting
 * @property array|null $negative_keywords
 * @property array|null $blocked_ips
 * @property array|null $excluded_sites
 * @property array|null $daily_budget
 * @property array|null $bidding_strategy
 * @property array|null $settings
 * @property array|null $counter_ids
 * @property array|null $relevant_keywords
 * @property string|null $attribution_model
 * @property array|null $priority_goals
 * @property string|null $updated_self
 * @property string|null $updated_children
 * @property bool $manage
 * @property bool $enabled
 * @property \Illuminate\Support\Carbon|null $groups_loaded_at
 * @property \Illuminate\Support\Carbon|null $disabled_at
 * @property \Illuminate\Support\Carbon|null $created_at
 * @property \Illuminate\Support\Carbon|null $updated_at
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Dictionary[] $dictionaries
 * @property-read int|null $dictionaries_count
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\AdGroup[] $groups
 * @property-read int|null $groups_count
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Variable[] $dictionaryCampaignVariables
 * @property-read int|null $dictionary_campaign_variables_count
 * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\Variable[] $dictionaryCampaigns
 * @property-read int|null $dictionary_campaigns_count
 * @method static Builder|Campaigns forGroupsLoadable()
 * @method static Builder|Campaigns forManaged($value = true)
 * @method static Builder|Campaigns forEnabled($value = true)
 * @method static Builder|Campaigns notDisabled()
 * @method static Builder|Campaigns disabled()
 * @method static Builder|Campaigns forUpdatedSelf()
 * @method static Builder|Campaigns forUpdatedChildren()
 * @method static Builder|Campaigns newModelQuery()
 * @method static Builder|Campaigns newQuery()
 * @method static Builder|Campaigns query()
 * @method static Builder|Campaigns whereAttributionModel($value)
 * @method static Builder|Campaigns whereBlockedIps($value)
 * @method static Builder|Campaigns whereCounterIds($value)
 * @method static Builder|Campaigns whereCreatedAt($value)
 * @method static Builder|Campaigns whereDailyBudget($value)
 * @method static Builder|Campaigns whereEnabled($value)
 * @method static Builder|Campaigns whereExcludedSites($value)
 * @method static Builder|Campaigns whereExternalId($value)
 * @method static Builder|Campaigns whereGroupsLoadedAt($value)
 * @method static Builder|Campaigns whereId($value)
 * @method static Builder|Campaigns whereManage($value)
 * @method static Builder|Campaigns whereName($value)
 * @method static Builder|Campaigns whereNegativeKeywords($value)
 * @method static Builder|Campaigns wherePriorityGoals($value)
 * @method static Builder|Campaigns whereRelevantKeywordsSettingBudgetPercent($value)
 * @method static Builder|Campaigns whereRelevantKeywordsSettingOptimizeGoalId($value)
 * @method static Builder|Campaigns whereSettings($value)
 * @method static Builder|Campaigns whereTextCampaignStrategyNetwork($value)
 * @method static Builder|Campaigns whereTextCampaignStrategySearch($value)
 * @method static Builder|Campaigns whereTimeTargeting($value)
 * @method static Builder|Campaigns whereToken($value)
 * @method static Builder|Campaigns whereUpdatedSelf($value)
 * @method static Builder|Campaigns whereUpdatedChildren($value)
 * @method static Builder|Campaigns whereBiddingStrategy($value)
 * @method static Builder|Campaigns whereDisabledAt($value)
 * @method static Builder|Campaigns whereRelevantKeywords($value)
 * @method static Builder|Campaigns whereUpdatedAt($value)
 * @mixin \Eloquent
 */
class Campaigns extends Model
{
    use HasFactory;

    protected $fillable = [
        'external_id',
        'token',
        'name',
        'time_targeting',
        'negative_keywords',
        'blocked_ips',
        'excluded_sites',
        'daily_budget',
        'bidding_strategy',
        'settings',
        'counter_ids',
        'relevant_keywords',
        'attribution_model',
        'priority_goals',
        'updated_self',
        'updated_children',
        'manage',
        'enabled',
        'disabled_at',
    ];

    protected $casts = [
        'time_targeting' => 'array',
        'negative_keywords' => 'array',
        'blocked_ips' => 'array',
        'bidding_strategy' => 'json',
        'settings' => 'array',
        'counter_ids' => 'array',
        'relevant_keywords' => 'json',
        'excluded_sites' => 'array',
        'daily_budget' => 'array',
        'priority_goals' => 'array',
        'groups_loaded_at' => 'datetime',
        'updated_self' => 'datetime',
        'updated_children' => 'datetime',
        'manage' => 'boolean',
        'enabled' => 'boolean',
        'disabled_at' => 'datetime',
    ];

    /**
     * @return Collection
     */
    static public function getPropertiesWatch()
    {
        return collect([
            'name',
            'negative_keywords',
            'blocked_ips',
            'excluded_sites',
            'daily_budget',
            'bidding_strategy',
            'settings',
            'counter_ids',
            'relevant_keywords',
            'attribution_model',
            'priority_goals',
        ]);
    }

    /**
     * @return array
     */
    static public function getSettingOptionsAllow()
    {
        return [
            'ADD_METRICA_TAG',
            'ADD_OPENSTAT_TAG',
            'ADD_TO_FAVORITES',
            'ENABLE_AREA_OF_INTEREST_TARGETING',
            'ENABLE_COMPANY_INFO',
            'ENABLE_SITE_MONITORING',
            'EXCLUDE_PAUSED_COMPETING_ADS',
            'MAINTAIN_NETWORK_CPC',
            'REQUIRE_SERVICING',
            'CAMPAIGN_EXACT_PHRASE_MATCHING_ENABLED',
        ];
    }

    public static function boot()
    {
        parent::boot();

        static::created(function (Campaigns $campaign) {
            if ($campaign->manage) {
                $campaign->copyInGoalCampaign();
                $campaign->copyGroupInGoalGroup();
            }
        });

        static::updated(function (Campaigns $campaign) {

            if ($campaign->manage !== $campaign->getOriginal('manage')) {
                if ($campaign->manage) {
                    $campaign->copyInGoalCampaign();
                    $campaign->copyGroupInGoalGroup();
                } else {
                    $campaign->dictionaries()->detach();
                }
            }

            if (DictionaryCampaign::getPropertiesCopyWithPivot()->first(function ($property_name) use ($campaign) {
                return $campaign->{$property_name} !== $campaign->getOriginal($property_name);
            })) {
                $campaign->dictionaryCampaigns()->enabled()->updated()->update(
                    DictionaryCampaign::copyPropertyFromMain($campaign)
                );
            }

            if (self::getPropertiesWatch()->first(function ($property_name) use ($campaign) {
                return $campaign->{$property_name} !== $campaign->getOriginal($property_name);
            })) {
                $campaign->dictionaryCampaigns()->forExternal()->update([
                    'updated_need' => Carbon::now(),
                ]);
            }

        });
    }

    private function copyInGoalCampaign()
    {
        $campaign = $this;

        Dictionary::whereNotNull('token_id')->get()->each(function (Dictionary $dictionary) use ($campaign) {

            $campaign->dictionaries()->syncWithoutDetaching([
                $dictionary->getKey() => DictionaryCampaign::copyPropertyFromMain($campaign),
            ]);

        });
    }

    public function copyGroupInGoalGroup()
    {
        $campaign = $this;

        $campaign->dictionaryCampaigns()->get()->each(function (DictionaryCampaign $dictionaryCampaign) use ($campaign) {

            $campaign->groups()->get()->each(function (AdGroup $adGroup) use ($dictionaryCampaign) {

                $dictionaryCampaign->groups()->updateOrCreate([
                    'campaign_external_id' => $dictionaryCampaign->external_id,
                    'ad_group_id' => $adGroup->getKey(),
                ], GoalAdGroup::copyPropertyFromMain($adGroup));

            });

        });
    }

    public function getBiddingStrategyAttribute($bidding_strategy)
    {
        $bidding_strategy = json_decode($bidding_strategy, true);

        if (!$bidding_strategy)
            return $bidding_strategy;

        if (!isset($bidding_strategy['Network']['NetworkDefault']) && $bidding_strategy['Network']['BiddingStrategyType'] === 'NETWORK_DEFAULT') {
            $bidding_strategy['Network']['NetworkDefault'] = (object)[];
        } elseif (isset($bidding_strategy['Network']['NetworkDefault']) && is_null($bidding_strategy['Network']['NetworkDefault']['LimitPercent'])) {
            unset($bidding_strategy['Network']['NetworkDefault']);
        }

        if (isset($bidding_strategy['Network']['WbMaximumClicks']) && is_null($bidding_strategy['Network']['WbMaximumClicks']['BidCeiling'])) {
            unset($bidding_strategy['Network']['WbMaximumClicks']['BidCeiling']);
        }

        if (isset($bidding_strategy['Network']['WbMaximumConversionRate']) && is_null($bidding_strategy['Network']['WbMaximumConversionRate']['BidCeiling'])) {
            unset($bidding_strategy['Network']['WbMaximumConversionRate']['BidCeiling']);
        }

        if (isset($bidding_strategy['Network']['AverageCpc']) && is_null($bidding_strategy['Network']['AverageCpc']['BidCeiling'])) {
            unset($bidding_strategy['Network']['AverageCpc']['BidCeiling']);
        }

        if (isset($bidding_strategy['Network']['WeeklyClickPackage']) && is_null($bidding_strategy['Network']['WeeklyClickPackage']['BidCeiling'])) {
            unset($bidding_strategy['Network']['WeeklyClickPackage']['BidCeiling']);
        }

        if (isset($bidding_strategy['Network']['AverageRoi']) && is_null($bidding_strategy['Network']['AverageRoi']['BidCeiling'])) {
            unset($bidding_strategy['Network']['AverageRoi']['BidCeiling']);
        }

        if (isset($bidding_strategy['Network']['PayForConversion']) && is_null($bidding_strategy['Network']['PayForConversion']['WeeklySpendLimit'])) {
            unset($bidding_strategy['Network']['PayForConversion']['WeeklySpendLimit']);
        }

        if (isset($bidding_strategy['Search']['WbMaximumClicks']) && is_null($bidding_strategy['Search']['WbMaximumClicks']['BidCeiling'])) {
            unset($bidding_strategy['Search']['WbMaximumClicks']['BidCeiling']);
        }

        if (isset($bidding_strategy['Search']['WbMaximumConversionRate']) && is_null($bidding_strategy['Search']['WbMaximumConversionRate']['BidCeiling'])) {
            unset($bidding_strategy['Search']['WbMaximumConversionRate']['BidCeiling']);
        }

        if (isset($bidding_strategy['Search']['AverageCpc']) && is_null($bidding_strategy['Search']['AverageCpc']['BidCeiling'])) {
            unset($bidding_strategy['Search']['AverageCpc']['BidCeiling']);
        }

        if (isset($bidding_strategy['Search']['AverageCpa']) && is_null($bidding_strategy['Search']['AverageCpa']['BidCeiling'])) {
            unset($bidding_strategy['Search']['AverageCpa']['BidCeiling']);
        }

        if (isset($bidding_strategy['Search']['AverageCpa']) && is_null($bidding_strategy['Search']['AverageCpa']['WeeklySpendLimit'])) {
            unset($bidding_strategy['Search']['AverageCpa']['WeeklySpendLimit']);
        }

        if (isset($bidding_strategy['Search']['AverageRoi']) && is_null($bidding_strategy['Search']['AverageRoi']['BidCeiling'])) {
            unset($bidding_strategy['Search']['AverageRoi']['BidCeiling']);
        }

        if (isset($bidding_strategy['Search']['AverageRoi']) && is_null($bidding_strategy['Search']['AverageRoi']['WeeklySpendLimit'])) {
            unset($bidding_strategy['Search']['AverageRoi']['WeeklySpendLimit']);
        }

        if (isset($bidding_strategy['Search']['AverageRoi']) && is_null($bidding_strategy['Search']['AverageRoi']['Profitability'])) {
            unset($bidding_strategy['Search']['AverageRoi']['Profitability']);
        }

        if (isset($bidding_strategy['Search']['PayForConversion']) && is_null($bidding_strategy['Search']['PayForConversion']['WeeklySpendLimit'])) {
            unset($bidding_strategy['Search']['PayForConversion']['WeeklySpendLimit']);
        }

        return $bidding_strategy;
    }

    public function groups()
    {
        return $this->hasMany(AdGroup::class, 'campaign_id');
    }

    public function dictionaryCampaigns()
    {
        return $this->hasMany(DictionaryCampaign::class, 'campaign_id');
    }

    public function dictionaryCampaignVariables()
    {
        return $this->hasManyThrough(DictionaryCampaignVariable::class, DictionaryCampaign::class, 'campaign_id', 'dictionary_campaign_id');
    }

    public function dictionaries()
    {
        return $this->belongsToMany(Dictionary::class, 'dictionary_campaigns', 'campaign_id', 'dictionary_id')
            ->using(DictionaryCampaign::class)
            ->withPivot(DictionaryCampaign::getWithPivot())
            ->withTimestamps();
    }

    public function scopeForUpdatedSelf(Builder $query)
    {
        $query->whereNotNull('updated_self');
    }

    public function scopeForUpdatedChildren(Builder $query)
    {
        $query->whereNotNull('updated_children');
    }

    public function scopeForGroupsLoadable(Builder $query)
    {
        $query->whereNull('groups_loaded_at');
    }

    public function scopeForManaged(Builder $query, $manage = true)
    {
        $query->where('manage', $manage);
    }

    public function scopeForEnabled(Builder $query, $enabled = true)
    {
        $query->where('enabled', $enabled);
    }

    public function scopeDisabled(Builder $query)
    {
        return $query->whereNotNull('disabled_at');
    }

    public function scopeNotDisabled(Builder $query)
    {
        return $query->whereNull('disabled_at');
    }

}