Completed
Push — develop ( e28d64...cdb1f2 )
by Adolfo
01:10
created

Plan::isNotFree()   A

Complexity

Conditions 2
Paths 2

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 2
nc 2
nop 0
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_active', '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_active
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_active = 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_active' => $is_active,
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 subscriptions()
81
    {
82
        return $this->hasMany(config('subscriptions.entities.plan_subscription'));
83
    }
84
85
    public function addFeature(PlanFeatureContract $feature)
86
    {
87
        $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...
88
    }
89
90
    public function features()
91
    {
92
        return $this->hasMany(config('subscriptions.entities.plan_feature'));
93
    }
94
95
    public function isDefault(): bool
96
    {
97
        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...
98
    }
99
100
    public function isActive(): bool
101
    {
102
        return $this->is_active;
0 ignored issues
show
Documentation introduced by
The property is_active 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...
103
    }
104
105
    public function isFree(): bool
106
    {
107
        return $this->intervals()->count() == 0 || $this->intervals()->first()->price == 0;
108
    }
109
110
    public function intervals()
111
    {
112
        return $this->hasMany(config('subscriptions.entities.plan_interval'), 'plan_id')
113
            ->orderBy('price');
114
    }
115
116
    public function isNotFree(): bool
117
    {
118
        return $this->intervals()->count() > 0 && $this->intervals()->first()->price > 0;
119
    }
120
121
    public function hasManyIntervals(): bool
122
    {
123
        return $this->intervals()->count() > 1;
124
    }
125
126
    public function setFree()
127
    {
128
        $this->intervals()->delete();
129
    }
130
131
    public function setDefault()
132
    {
133
        $myGroup = $this->myGroup();
134
        $calledClass = get_called_class();
135
136
        $currentDefaults = $calledClass::query()
137
            ->byGroup($myGroup)
138
            ->isDefault()
139
            ->get();
140
141
        $currentDefaults->each(function ($plan) {
142
            $plan->is_default = false;
143
            $plan->save();
144
        });
145
146
        $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...
147
        $this->save();
148
    }
149
150
    public function myGroup(): ?GroupContract
151
    {
152
        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...
153
    }
154
155
    public function changeToGroup(GroupContract $group): void
156
    {
157
        $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...
158
159
        if (! self::defaultExists($group)) {
160
            $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...
161
        }
162
163
        $this->save();
164
    }
165
166
    public function getName()
167
    {
168
        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...
169
    }
170
171
    public function getDescription()
172
    {
173
        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...
174
    }
175
176
    public function delete()
177
    {
178
        if($this->subscriptions()->count() > 0) {
179
            throw new PlanErrorException('You cannot delete this plan because this has subscriptions.');
180
        }
181
        return parent::delete();
182
    }
183
184
}
185