Completed
Push — develop ( cdb1f2...9ac1a5 )
by Adolfo
01:17
created

Plan::scopeEnabled()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 1
1
<?php
2
3
namespace Sagitarius29\LaravelSubscriptions;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Database\Eloquent\Builder;
7
use Sagitarius29\LaravelSubscriptions\Contracts\PlanContract;
8
use Sagitarius29\LaravelSubscriptions\Contracts\GroupContract;
9
use Sagitarius29\LaravelSubscriptions\Contracts\PlanFeatureContract;
10
use Sagitarius29\LaravelSubscriptions\Exceptions\PlanErrorException;
11
12
abstract class Plan extends Model implements PlanContract
13
{
14
    protected $table = 'plans';
15
16
    protected $fillable = [
17
        'name', 'description', 'free_days', 'sort_order', 'is_enabled', 'is_default', 'group',
18
    ];
19
20
    /**
21
     * @param  string  $name
22
     * @param  string  $description
23
     * @param  int  $free_days
24
     * @param  int  $sort_order
25
     * @param  bool  $is_enabled
26
     * @param  bool  $is_default
27
     * @param  GroupContract|null  $group
28
     * @return Model|PlanContract
29
     */
30
    public static function create(
31
        string $name,
32
        string $description,
33
        int $free_days,
34
        int $sort_order,
35
        bool $is_enabled = false,
36
        bool $is_default = false,
37
        GroupContract $group = null
38
    ): PlanContract {
39
        $attributes = [
40
            'name' => $name,
41
            'description' => $description,
42
            'free_days' => $free_days,
43
            'sort_order' => $sort_order,
44
            'is_enabled' => $is_enabled,
45
            'is_default' => $is_default,
46
            'group' => $group,
47
        ];
48
        $calledClass = get_called_class();
49
50
        if (! self::defaultExists($group)) {
51
            $attributes['is_default'] = true;
52
        }
53
54
        $plan = new $calledClass($attributes);
55
        $plan->save();
56
57
        return $plan;
58
    }
59
60
    private static function defaultExists(GroupContract $group = null): bool
61
    {
62
        $calledClass = get_called_class();
63
64
        return $calledClass::query()
65
            ->byGroup($group)
66
            ->isDefault()
67
            ->exists();
68
    }
69
70
    public function scopeByGroup(Builder $q, GroupContract $group = null)
71
    {
72
        return $q->where('group', $group);
73
    }
74
75
    public function scopeIsDefault(Builder $q)
76
    {
77
        return $q->where('is_default', 1);
78
    }
79
80
    public function scopeEnabled(Builder $q)
81
    {
82
        return $q->where('is_enabled', 1);
83
    }
84
85
    public function scopeDisabled(Builder $q)
86
    {
87
        return $q->where('is_enabled', 1);
88
    }
89
90
    public function subscriptions()
91
    {
92
        return $this->hasMany(config('subscriptions.entities.plan_subscription'));
93
    }
94
95
    public function addFeature(PlanFeatureContract $feature)
96
    {
97
        $this->features()->save($feature);
0 ignored issues
show
Documentation introduced by
$feature is of type object<Sagitarius29\Lara...ts\PlanFeatureContract>, but the function expects a object<Illuminate\Database\Eloquent\Model>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
98
    }
99
100
    public function addFeatures(array $features)
101
    {
102
        $this->features()->saveMany($features);
103
    }
104
105
    public function features()
106
    {
107
        return $this->hasMany(config('subscriptions.entities.plan_feature'));
108
    }
109
110
    public function isDefault(): bool
111
    {
112
        return $this->is_default;
0 ignored issues
show
Documentation introduced by
The property is_default does not exist on object<Sagitarius29\LaravelSubscriptions\Plan>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
113
    }
114
115
    public function isEnabled(): bool
116
    {
117
        return $this->is_enabled;
0 ignored issues
show
Documentation introduced by
The property is_enabled does not exist on object<Sagitarius29\LaravelSubscriptions\Plan>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
118
    }
119
120
    public function isDisabled(): bool
121
    {
122
        return ! $this->is_enabled;
0 ignored issues
show
Documentation introduced by
The property is_enabled does not exist on object<Sagitarius29\LaravelSubscriptions\Plan>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
123
    }
124
125
    public function isFree(): bool
126
    {
127
        return $this->intervals()->count() == 0 || $this->intervals()->first()->price == 0;
128
    }
129
130
    public function intervals()
131
    {
132
        return $this->hasMany(config('subscriptions.entities.plan_interval'), 'plan_id')
133
            ->orderBy('price');
134
    }
135
136
    public function isNotFree(): bool
137
    {
138
        return $this->intervals()->count() > 0 && $this->intervals()->first()->price > 0;
139
    }
140
141
    public function hasManyIntervals(): bool
142
    {
143
        return $this->intervals()->count() > 1;
144
    }
145
146
    public function setFree()
147
    {
148
        $this->intervals()->delete();
149
    }
150
151
    public function setDefault()
152
    {
153
        $myGroup = $this->myGroup();
154
        $calledClass = get_called_class();
155
156
        $currentDefaults = $calledClass::query()
157
            ->byGroup($myGroup)
158
            ->isDefault()
159
            ->get();
160
161
        $currentDefaults->each(function ($plan) {
162
            $plan->is_default = false;
163
            $plan->save();
164
        });
165
166
        $this->is_default = true;
0 ignored issues
show
Documentation introduced by
The property is_default does not exist on object<Sagitarius29\LaravelSubscriptions\Plan>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
167
        $this->save();
168
    }
169
170
    public function myGroup(): ?GroupContract
171
    {
172
        return empty($this->group) ? null : new \Sagitarius29\LaravelSubscriptions\Entities\Group($this->group);
0 ignored issues
show
Documentation introduced by
The property group does not exist on object<Sagitarius29\LaravelSubscriptions\Plan>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
173
    }
174
175
    public function changeToGroup(GroupContract $group): void
176
    {
177
        $this->group = $group;
0 ignored issues
show
Documentation introduced by
The property group does not exist on object<Sagitarius29\LaravelSubscriptions\Plan>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
178
179
        if (! self::defaultExists($group)) {
180
            $this->is_default = true;
0 ignored issues
show
Documentation introduced by
The property is_default does not exist on object<Sagitarius29\LaravelSubscriptions\Plan>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
181
        }
182
183
        $this->save();
184
    }
185
186
    public function getName()
187
    {
188
        return $this->name;
0 ignored issues
show
Documentation introduced by
The property name does not exist on object<Sagitarius29\LaravelSubscriptions\Plan>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
189
    }
190
191
    public function getDescription()
192
    {
193
        return $this->description;
0 ignored issues
show
Documentation introduced by
The property description does not exist on object<Sagitarius29\LaravelSubscriptions\Plan>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
194
    }
195
196
    public function delete()
197
    {
198
        if($this->subscriptions()->count() > 0) {
199
            throw new PlanErrorException('You cannot delete this plan because this has subscriptions.');
200
        }
201
        return parent::delete();
202
    }
203
204
}
205