Completed
Push — master ( 237430...8e6d70 )
by Ariel
06:33
created

Appointment::getAnnulationDeadlineAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 8
rs 9.4285
c 1
b 0
f 0
cc 1
eloc 5
nc 1
nop 0
1
<?php
2
3
namespace Timegridio\Concierge\Models;
4
5
use Carbon\Carbon;
6
use Illuminate\Database\Eloquent\Model as EloquentModel;
7
use McCool\LaravelAutoPresenter\HasPresenter;
8
use Timegridio\Concierge\Presenters\AppointmentPresenter;
9
10
/**
11
 * An Appointment can be understood as a reservation of a given Service,
12
 * provided by a given Business, targeted to a Contact, which will take place
13
 * on a determined Date and Time, and might have a duration and or comments.
14
 *
15
 * The Appointment can be issued by the Contact's User or by the Business owner.
16
 */
17
class Appointment extends EloquentModel implements HasPresenter
18
{
19
    /**
20
     * The attributes that are mass assignable.
21
     *
22
     * @var array
23
     */
24
    protected $fillable = ['issuer_id', 'contact_id', 'business_id',
25
        'service_id', 'start_at', 'finish_at', 'duration', 'comments', ];
26
27
    /**
28
     * The attributes that aren't mass assignable.
29
     *
30
     * @var array
31
     */
32
    protected $guarded = ['id', 'hash', 'status', 'vacancy_id'];
33
34
    /**
35
     * The attributes that should be mutated to dates.
36
     *
37
     * @var array
38
     */
39
    protected $dates = ['start_at', 'finish_at'];
40
41
    /**
42
     * Appointment Hard Status Constants.
43
     */
44
    const STATUS_RESERVED = 'R';
45
    const STATUS_CONFIRMED = 'C';
46
    const STATUS_ANNULATED = 'A';
47
    const STATUS_SERVED = 'S';
48
49
    ///////////////
50
    // PRESENTER //
51
    ///////////////
52
53
    /**
54
     * Get Presenter Class.
55
     *
56
     * @return App\Presenters\AppointmentPresenter
57
     */
58
    public function getPresenterClass()
59
    {
60
        return AppointmentPresenter::class;
61
    }
62
63
    /**
64
     * Generate hash and save the model to the database.
65
     *
66
     * @param array $options
67
     *
68
     * @return bool
69
     */
70
    public function save(array $options = [])
71
    {
72
        $this->doHash();
73
74
        return parent::save($options);
75
    }
76
77
    ///////////////////
78
    // Relationships //
79
    ///////////////////
80
81
    /**
82
     * Get the issuer (the User that generated the Appointment).
83
     *
84
     * @return Illuminate\Database\Eloquent\belongsTo
85
     */
86
    public function issuer()
87
    {
88
        return $this->belongsTo(config('auth.providers.users.model'));
89
    }
90
91
    /**
92
     * Get the target Contact (for whom is reserved the Appointment).
93
     *
94
     * @return Illuminate\Database\Eloquent\belongsTo
95
     */
96
    public function contact()
97
    {
98
        return $this->belongsTo(Contact::class);
99
    }
100
101
    /**
102
     * Get the holding Business (that has taken the reservation).
103
     *
104
     * @return Illuminate\Database\Eloquent\belongsTo
105
     */
106
    public function business()
107
    {
108
        return $this->belongsTo(Business::class);
109
    }
110
111
    /**
112
     * Get the reserved Service.
113
     *
114
     * @return Illuminate\Database\Eloquent\belongsTo
115
     */
116
    public function service()
117
    {
118
        return $this->belongsTo(Service::class);
119
    }
120
121
    /**
122
     * Get the Vacancy (that justifies the availability of resources for the
123
     * Appointment generation).
124
     *
125
     * @return Illuminate\Database\Eloquent\belongsTo
126
     */
127
    public function vacancy()
128
    {
129
        return $this->belongsTo(Vacancy::class);
130
    }
131
132
    ///////////
133
    // Other //
134
    ///////////
135
136
    /**
137
     * Get the User through Contact.
138
     *
139
     * @return User
140
     */
141
    public function user()
142
    {
143
        return $this->contact->user;
0 ignored issues
show
Documentation introduced by
The property contact does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
144
    }
145
146
    /**
147
     * Determine if the new Appointment will hash-crash with another existing
148
     * Appointment.
149
     *
150
     * @return bool
151
     */
152
    public function duplicates()
153
    {
154
        return !self::where('hash', $this->hash)->get()->isEmpty();
0 ignored issues
show
Documentation introduced by
The property hash does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
155
    }
156
157
    ///////////////
158
    // Accessors //
159
    ///////////////
160
161
    /**
162
     * Get Hash.
163
     *
164
     * @return string
165
     */
166
    public function getHashAttribute()
167
    {
168
        return isset($this->attributes['hash'])
169
            ? $this->attributes['hash']
170
            : $this->doHash();
171
    }
172
173
    /**
174
     * Get Finish At:
175
     * Calculates the start_at time plus duration in minutes.
176
     *
177
     * @return Carbon
178
     */
179
    public function getFinishAtAttribute()
180
    {
181
        if (array_get($this->attributes, 'finish_at') !== null) {
182
            return Carbon::parse($this->attributes['finish_at']);
183
        }
184
185
        if (is_numeric($this->duration)) {
0 ignored issues
show
Documentation introduced by
The property duration does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
186
            return $this->start_at->addMinutes($this->duration);
0 ignored issues
show
Documentation introduced by
The property start_at does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
Documentation introduced by
The property duration does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
187
        }
188
189
        return $this->start_at;
0 ignored issues
show
Documentation introduced by
The property start_at does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
190
    }
191
192
    /**
193
     * Get TimeZone (from the Business).
194
     *
195
     * @return string
196
     */
197
    public function getTZAttribute()
198
    {
199
        return $this->business->timezone;
0 ignored issues
show
Documentation introduced by
The property business does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
200
    }
201
202
    /**
203
     * Get the human readable status name.
204
     *
205
     * @return string
206
     */
207
    public function getStatusLabelAttribute()
208
    {
209
        $labels = [
210
            Self::STATUS_RESERVED  => 'reserved',
211
            Self::STATUS_CONFIRMED => 'confirmed',
212
            Self::STATUS_ANNULATED => 'annulated',
213
            Self::STATUS_SERVED    => 'served',
214
            ];
215
216
        return array_key_exists($this->status, $labels)
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
217
            ? $labels[$this->status]
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
218
            : '';
219
    }
220
221
    /**
222
     * Get the date of the Appointment.
223
     *
224
     * @return string
225
     */
226
    public function getDateAttribute()
227
    {
228
        return $this->start_at
0 ignored issues
show
Documentation introduced by
The property start_at does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
229
                    ->timezone($this->business->timezone)
0 ignored issues
show
Documentation introduced by
The property business does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
230
                    ->toDateString();
231
    }
232
233
    /**
234
     * Get user-friendly unique identification code.
235
     *
236
     * @return string
237
     */
238
    public function getCodeAttribute()
239
    {
240
        $length = $this->business->pref('appointment_code_length');
0 ignored issues
show
Documentation introduced by
The property business does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
241
242
        return strtoupper(substr($this->hash, 0, $length));
0 ignored issues
show
Documentation introduced by
The property hash does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
243
    }
244
245
    //////////////
246
    // Mutators //
247
    //////////////
248
249
    /**
250
     * Generate Appointment hash.
251
     *
252
     * @return string
253
     */
254
    public function doHash()
255
    {
256
        return $this->attributes['hash'] = md5(
257
            $this->start_at.'/'.
0 ignored issues
show
Documentation introduced by
The property start_at does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
258
            $this->contact_id.'/'.
0 ignored issues
show
Documentation introduced by
The property contact_id does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
259
            $this->business_id.'/'.
0 ignored issues
show
Documentation introduced by
The property business_id does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
260
            $this->service_id
0 ignored issues
show
Documentation introduced by
The property service_id does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
261
        );
262
    }
263
264
    /**
265
     * Set start at.
266
     *
267
     * @param Carbon $datetime
268
     */
269
    public function setStartAtAttribute(Carbon $datetime)
270
    {
271
        $this->attributes['start_at'] = $datetime;
272
    }
273
274
    /**
275
     * Set finish_at attribute.
276
     *
277
     * @param Carbon $datetime
278
     */
279
    public function setFinishAtAttribute(Carbon $datetime)
280
    {
281
        $this->attributes['finish_at'] = $datetime;
282
    }
283
284
    /**
285
     * Set Comments.
286
     *
287
     * @param string $comments
288
     */
289
    public function setCommentsAttribute($comments)
290
    {
291
        $this->attributes['comments'] = trim($comments) ?: null;
292
    }
293
294
    /////////////////
295
    // HARD STATUS //
296
    /////////////////
297
298
    /**
299
     * Determine if is Reserved.
300
     *
301
     * @return bool
302
     */
303
    public function isReserved()
304
    {
305
        return $this->status == Self::STATUS_RESERVED;
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
306
    }
307
308
    ///////////////////////////
309
    // Calculated attributes //
310
    ///////////////////////////
311
312
    /**
313
     * Appointment Status Workflow.
314
     *
315
     * Hard Status: Those concrete values stored in DB
316
     * Soft Status: Those values calculated from stored values in DB
317
     *
318
     * Suggested transitions (Binding is not mandatory)
319
     *     Reserved -> Confirmed -> Served
320
     *     Reserved -> Served
321
     *     Reserved -> Annulated
322
     *     Reserved -> Confirmed -> Annulated
323
     *
324
     * Soft Status
325
     *     (Active)   [ Reserved  | Confirmed ]
326
     *     (InActive) [ Annulated | Served    ]
327
     */
328
329
    /**
330
     * Determine if is Active.
331
     *
332
     * @return bool
333
     */
334
    public function isActive()
335
    {
336
        return
337
            $this->status == Self::STATUS_CONFIRMED ||
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
338
            $this->status == Self::STATUS_RESERVED;
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
339
    }
340
341
    /**
342
     * Determine if is Pending.
343
     *
344
     * @return bool
345
     */
346
    public function isPending()
347
    {
348
        return $this->isActive() && $this->isFuture();
349
    }
350
351
    /**
352
     * Determine if is Future.
353
     *
354
     * @return bool
355
     */
356
    public function isFuture()
357
    {
358
        return !$this->isDue();
359
    }
360
361
    /**
362
     * Determine if is due.
363
     *
364
     * @return bool
365
     */
366
    public function isDue()
367
    {
368
        return $this->start_at->isPast();
0 ignored issues
show
Documentation introduced by
The property start_at does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
369
    }
370
371
    ////////////
372
    // Scopes //
373
    ////////////
374
375
    /////////////////////////
376
    // Hard Status Scoping //
377
    /////////////////////////
378
379
    /**
380
     * Scope to Contacts Collection.
381
     *
382
     * @param Illuminate\Database\Query $query
383
     *
384
     * @return Illuminate\Database\Query
385
     */
386
    public function scopeForContacts($query, $contacts)
387
    {
388
        return $query->whereIn('contact_id', $contacts->pluck('id'));
389
    }
390
391
    /**
392
     * Scope to Unarchived Appointments.
393
     *
394
     * @param Illuminate\Database\Query $query
395
     *
396
     * @return Illuminate\Database\Query
397
     */
398
    public function scopeUnarchived($query)
399
    {
400
        return $query
401
            ->where(function ($query) {
402
                $query->whereIn('status', [Self::STATUS_RESERVED, Self::STATUS_CONFIRMED])
403
                    ->where('start_at', '<=', Carbon::parse('today midnight')->timezone('UTC'))
404
                    ->orWhere(function ($query) {
405
                        $query->where('start_at', '>=', Carbon::parse('today midnight')->timezone('UTC'));
406
                    });
407
            });
408
    }
409
410
    /**
411
     * Scope to Served Appointments.
412
     *
413
     * @param Illuminate\Database\Query $query
414
     *
415
     * @return Illuminate\Database\Query
416
     */
417
    public function scopeServed($query)
418
    {
419
        return $query->where('status', '=', Self::STATUS_SERVED);
420
    }
421
422
    /**
423
     * Scope to Annulated Appointments.
424
     *
425
     * @param Illuminate\Database\Query $query
426
     *
427
     * @return Illuminate\Database\Query
428
     */
429
    public function scopeAnnulated($query)
430
    {
431
        return $query->where('status', '=', Self::STATUS_ANNULATED);
432
    }
433
434
    /////////////////////////
435
    // Soft Status Scoping //
436
    /////////////////////////
437
438
    /**
439
     * Scope to not Served Appointments.
440
     *
441
     * @param Illuminate\Database\Query $query
442
     *
443
     * @return Illuminate\Database\Query
444
     */
445
    public function scopeUnServed($query)
446
    {
447
        return $query->where('status', '<>', Self::STATUS_SERVED);
448
    }
449
450
    /**
451
     * Scope to Active Appointments.
452
     *
453
     * @param Illuminate\Database\Query $query
454
     *
455
     * @return Illuminate\Database\Query
456
     */
457
    public function scopeActive($query)
458
    {
459
        return $query->whereIn('status', [Self::STATUS_RESERVED, Self::STATUS_CONFIRMED]);
460
    }
461
462
    /**
463
     * Scope of Business.
464
     *
465
     * @param Illuminate\Database\Query $query
466
     * @param int                       $businessId
467
     *
468
     * @return Illuminate\Database\Query
469
     */
470
    public function scopeOfBusiness($query, $businessId)
471
    {
472
        return $query->where('business_id', '=', $businessId);
473
    }
474
475
    /**
476
     * Scope of date.
477
     *
478
     * @param Illuminate\Database\Query $query
479
     * @param Carbon                    $date
480
     *
481
     * @return Illuminate\Database\Query
482
     */
483
    public function scopeOfDate($query, Carbon $date)
484
    {
485
        return $query->whereRaw('date(`start_at`) = ?', [$date->timezone('UTC')->toDateString()]);
486
    }
487
488
    /**
489
     * Scope only future appointments.
490
     *
491
     * @param Illuminate\Database\Query $query
492
     *
493
     * @return Illuminate\Database\Query
494
     */
495
    public function scopeFuture($query)
496
    {
497
        $todayMidnight = Carbon::parse('today midnight')->timezone('UTC');
498
499
        return $query->where('start_at', '>=', $todayMidnight);
500
    }
501
502
    /**
503
     * Scope only till date.
504
     *
505
     * @param Illuminate\Database\Query $query
506
     * @param Carbon                    $date
507
     *
508
     * @return Illuminate\Database\Query
509
     */
510
    public function scopeTillDate($query, Carbon $date)
511
    {
512
        return $query->where('start_at', '<=', $date->timezone('UTC'));
513
    }
514
515
    /**
516
     * Between Dates.
517
     *
518
     * @param Illuminate\Database\Query $query
519
     * @param Carbon                    $startAt
520
     * @param Carbon                    $finishAt
521
     *
522
     * @return Illuminate\Database\Query
523
     */
524
    public function scopeAffectingInterval($query, Carbon $startAt, Carbon $finishAt)
525
    {
526
        return $query
527
            ->where(function ($query) use ($startAt, $finishAt) {
528
529 View Code Duplication
                $query->where(function ($query) use ($startAt, $finishAt) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
530
                    $query->where('finish_at', '>=', $finishAt->timezone('UTC'))
531
                          ->where('start_at', '<=', $startAt->timezone('UTC'));
532
                })
533 View Code Duplication
                ->orWhere(function ($query) use ($startAt, $finishAt) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
534
                    $query->where('finish_at', '<', $finishAt->timezone('UTC'))
535
                          ->where('finish_at', '>', $startAt->timezone('UTC'));
536
                })
537 View Code Duplication
                ->orWhere(function ($query) use ($startAt, $finishAt) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
538
                    $query->where('start_at', '>', $startAt->timezone('UTC'))
539
                          ->where('start_at', '<', $finishAt->timezone('UTC'));
540
                })
541 View Code Duplication
                ->orWhere(function ($query) use ($startAt, $finishAt) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
542
                    $query->where('start_at', '>', $startAt->timezone('UTC'))
543
                          ->where('finish_at', '<', $finishAt->timezone('UTC'));
544
                });
545
546
            });
547
    }
548
549
    //////////////////////////
550
    // Soft Status Checkers //
551
    //////////////////////////
552
553
    /**
554
     * User is target contact of the appointment.
555
     *
556
     * @param int $userId
557
     *
558
     * @return bool
559
     */
560
    public function isTarget($userId)
561
    {
562
        return $this->contact->isProfileOf($userId);
0 ignored issues
show
Documentation introduced by
The property contact does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
563
    }
564
565
    /**
566
     * User is issuer of the appointment.
567
     *
568
     * @param int $userId
569
     *
570
     * @return bool
571
     */
572
    public function isIssuer($userId)
573
    {
574
        return $this->issuer->id == $userId;
0 ignored issues
show
Documentation introduced by
The property issuer does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
575
    }
576
577
    /**
578
     * User is owner of business.
579
     *
580
     * @param int $userId
581
     *
582
     * @return bool
583
     */
584
    public function isOwner($userId)
585
    {
586
        return $this->business->owners->contains($userId);
0 ignored issues
show
Documentation introduced by
The property business does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
587
    }
588
589
    /**
590
     * can be annulated by user.
591
     *
592
     * @param int $userId
593
     *
594
     * @return bool
595
     */
596
    public function canAnnulate($userId)
597
    {
598
        return $this->isOwner($userId) ||
599
            ($this->isIssuer($userId) && $this->isOnTimeToAnnulate()) ||
600
            ($this->isTarget($userId) && $this->isOnTimeToAnnulate());
601
    }
602
603
    /**
604
     * Determine if it is still possible to annulate according business policy.
605
     *
606
     * @return bool
607
     */
608
    public function isOnTimeToAnnulate()
609
    {
610
        $graceHours = $this->business->pref('appointment_annulation_pre_hs');
0 ignored issues
show
Documentation introduced by
The property business does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
611
612
        $diff = $this->start_at->diffInHours(Carbon::now());
0 ignored issues
show
Documentation introduced by
The property start_at does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
613
614
        return intval($diff) >= intval($graceHours);
615
    }
616
617
    /**
618
     * can Serve.
619
     *
620
     * @param int $userId
621
     *
622
     * @return bool
623
     */
624
    public function canServe($userId)
625
    {
626
        return $this->isOwner($userId);
627
    }
628
629
    /**
630
     * can confirm.
631
     *
632
     * @param int $userId
633
     *
634
     * @return bool
635
     */
636
    public function canConfirm($userId)
637
    {
638
        return $this->isIssuer($userId) || $this->isOwner($userId);
639
    }
640
641
    /**
642
     * is Serveable by user.
643
     *
644
     * @param int $userId
645
     *
646
     * @return bool
647
     */
648
    public function isServeableBy($userId)
649
    {
650
        return $this->isServeable() && $this->canServe($userId);
651
    }
652
653
    /**
654
     * is Confirmable By user.
655
     *
656
     * @param int $userId
657
     *
658
     * @return bool
659
     */
660
    public function isConfirmableBy($userId)
661
    {
662
        return
663
            $this->isConfirmable() &&
664
            $this->shouldConfirmBy($userId) &&
665
            $this->canConfirm($userId);
666
    }
667
668
    /**
669
     * is Annulable By user.
670
     *
671
     * @param int $userId
672
     *
673
     * @return bool
674
     */
675
    public function isAnnulableBy($userId)
676
    {
677
        return $this->isAnnulable() && $this->canAnnulate($userId);
678
    }
679
680
    /**
681
     * Determine if the queried userId may confirm the appointment or not.
682
     *
683
     * @param int $userId
684
     *
685
     * @return bool
686
     */
687
    public function shouldConfirmBy($userId)
688
    {
689
        return ($this->isSelfIssued() && $this->isOwner($userId)) ||
690
               ($this->isOwner($this->issuer->id) && $this->isIssuer($userId));
0 ignored issues
show
Documentation introduced by
The property issuer does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
691
    }
692
693
    /**
694
     * Determine if the target Contact's User is the same of the Appointment
695
     * issuer User.
696
     *
697
     * @return bool
698
     */
699
    public function isSelfIssued()
700
    {
701
        if (!$this->issuer) {
0 ignored issues
show
Documentation introduced by
The property issuer does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
702
            return false;
703
        }
704
        if (!$this->contact) {
0 ignored issues
show
Documentation introduced by
The property contact does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
705
            return false;
706
        }
707
        if (!$this->contact->user) {
0 ignored issues
show
Documentation introduced by
The property contact does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
708
            return false;
709
        }
710
711
        return $this->issuer->id == $this->contact->user->id;
0 ignored issues
show
Documentation introduced by
The property issuer does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
Documentation introduced by
The property contact does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
712
    }
713
714
    /**
715
     * Determine if the Serve action can be performed.
716
     *
717
     * @return bool
718
     */
719
    public function isServeable()
720
    {
721
        return $this->isActive() && $this->isDue();
722
    }
723
724
    /**
725
     * Determine if the Confirm action can be performed.
726
     *
727
     * @return bool
728
     */
729
    public function isConfirmable()
730
    {
731
        return $this->status == self::STATUS_RESERVED && $this->isFuture();
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
732
    }
733
734
    /**
735
     * Determine if the Annulate action can be performed.
736
     *
737
     * @return bool
738
     */
739
    public function isAnnulable()
740
    {
741
        return $this->isActive();
742
    }
743
744
    /////////////////////////
745
    // Hard Status Actions //
746
    /////////////////////////
747
748
    /**
749
     * Check and perform Confirm action.
750
     *
751
     * @return $this
752
     */
753
    public function doReserve()
754
    {
755
        if ($this->status === null) {
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
756
            $this->status = self::STATUS_RESERVED;
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
757
        }
758
759
        return $this;
760
    }
761
762
    /**
763
     * Check and perform Confirm action.
764
     *
765
     * @return $this
766
     */
767
    public function doConfirm()
768
    {
769
        if ($this->isConfirmable()) {
770
            $this->status = self::STATUS_CONFIRMED;
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
771
772
            return $this->save();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->save(); (boolean) is incompatible with the return type documented by Timegridio\Concierge\Models\Appointment::doConfirm of type Timegridio\Concierge\Models\Appointment.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
773
        }
774
775
        return $this;
776
    }
777
778
    /**
779
     * Check and perform Annulate action.
780
     *
781
     * @return $this
782
     */
783
    public function doAnnulate()
784
    {
785
        if ($this->isAnnulable()) {
786
            $this->status = self::STATUS_ANNULATED;
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
787
788
            return $this->save();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->save(); (boolean) is incompatible with the return type documented by Timegridio\Concierge\Mod...Appointment::doAnnulate of type Timegridio\Concierge\Models\Appointment.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
789
        }
790
791
        return $this;
792
    }
793
794
    /**
795
     * Check and perform Serve action.
796
     *
797
     * @return $this
798
     */
799
    public function doServe()
800
    {
801
        if ($this->isServeable()) {
802
            $this->status = self::STATUS_SERVED;
0 ignored issues
show
Documentation introduced by
The property status does not exist on object<Timegridio\Concierge\Models\Appointment>. 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...
803
804
            return $this->save();
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->save(); (boolean) is incompatible with the return type documented by Timegridio\Concierge\Models\Appointment::doServe of type Timegridio\Concierge\Models\Appointment.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
805
        }
806
807
        return $this;
808
    }
809
}
810