Completed
Pull Request — master (#96)
by Brandon
02:26
created

Device::isReadyForCommand()   A

Complexity

Conditions 4
Paths 2

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
ccs 0
cts 5
cp 0
rs 9.2
cc 4
eloc 5
nc 2
nop 0
crap 20
1
<?php
2
3
namespace App;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Database\Eloquent\SoftDeletes;
7
use Carbon\Carbon;
8
use Illuminate\Support\Facades\Auth;
9
use Spatie\Activitylog\Traits\LogsActivity;
10
//use Spatie\Activitylog\Traits\CausesActivity;
11
use App\Sensor;
12
use App\SensorData;
13
14
class Device extends Model
15
{
16
    use SoftDeletes;
17
    use LogsActivity;
18
    //use CausesActivity;
19
    
20
    /**
21
     * The attributes that should be mutated to dates.
22
     *
23
     * @var array
24
     */
25
    protected $dates = [
26
        'deleted_at'
27
    ];
28
    
29
    /**
30
     * The attributes that should be hidden for arrays.
31
     *
32
     * @var array
33
     */
34
    protected $hidden = ['token'];
35
    
36
    /**
37
     * The attributes that are mass assignable.
38
     *
39
     * @var array
40
     */
41
    protected $fillable = [
42
        'name', 'location_id', 'uuid', 'version', 'hostname', 'ip', 'mac_address', 
43
        'time', 'cover_command', 'cover_status', 'error_msg', 'limitsw_open', 'limitsw_closed',
44
        'light_in', 'light_out', 'update_rate', 'image_rate', 'sensor_rate', 
45
        'open_time', 'close_time'
46
    ];
47
    
48
    /**
49
     * The attributes to ignore in the Activity Log
50
     *
51
     * @var array
52
     */
53
    protected static $ignoreChangedAttributes = ['updated_at'];
54
    
55
    /**
56
     * The attributes to log in the Activity Log
57
     *
58
     * @var array
59
     */
60
    protected static $logAttributes = [
61
        'name', 'location_id', 'uuid', 'version', 'hostname', 'ip', 'mac_address', 
62
        'time', 'cover_status', 'error_msg', 'limitsw_open', 'limitsw_closed', 
63
        'light_in', 'light_out', 'update_rate', 'image_rate', 'sensor_rate', 
64
        'open_time', 'close_time'
65
    ];
66
    
67
    /**
68
     * Only log those that have actually changed after the update.
69
     *
70
     * @var array
71
     */
72
    protected static $logOnlyDirty = true;
73
    
74
    /**
75
     * Update the updated_at and created_at timestamps?
76
     *
77
     * @var array
78
     */
79
    public $timestamps = true;
80
    
81
    /**
82
     * Get the location for the device
83
     */
84
    public function location()
85
    {
86
        return $this->belongsTo('App\Location', 'location_id');
87
    }
88
    
89
    /**
90
     * Get the site for the device using model accessor
91
     */
92
    public function getSiteAttribute()
93
    {
94
        return $this->location->site ?? (object)[];
95
    }
96
    
97
    /**
98
     * Accessor: Get the open time of the device converted to hours and minutes
99
     * If it is a device accessing the time use UTC
100
     * If it is a user accessing the time use their preferred timezone
101
     *
102
     * @param  string $value
103
     * @return string
104
     */
105 View Code Duplication
    public function getOpenTimeAttribute($value)
106
    {
107
        $time = new Carbon($value, 'UTC');
108
        
109
        //If the user is logged in then use there preferred timezone
110
        if (Auth::check())
111
            $time = $time->setTimezone(Auth::user()->timezone);
0 ignored issues
show
Bug introduced by
Accessing timezone on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
112
113
        return $time->format('H:i');
114
    }
115
    
116
    /**
117
     * Accessor: Get the close time of the device converted to hours and minutes
118
     * If it is a device accessing the time use UTC
119
     * If it is a user accessing the time use their preferred timezone
120
     *
121
     * @param  string $value
122
     * @return string
123
     */
124 View Code Duplication
    public function getCloseTimeAttribute($value)
125
    {
126
        $time = new Carbon($value, 'UTC');
127
    
128
        //If the user is logged in then use there preferred timezone
129
        if (Auth::check())
130
            $time = $time->setTimezone(Auth::user()->timezone);
0 ignored issues
show
Bug introduced by
Accessing timezone on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
131
        
132
        return $time->format('H:i');
133
    }
134
    
135
    /**
136
     * Set the open time to UTC
137
     * If it is a device saving the time use UTC
138
     * If it is a user saving the time use their preferred timezone
139
     *
140
     * @param  string  $value
141
     * @return void
142
     */
143 View Code Duplication
    public function setOpenTimeAttribute($value)
144
    {
145
        //If the user is logged in then use there preferred timezone
146
        if (Auth::check())
147
        {
148
            $time = new Carbon($value, Auth::user()->timezone);
0 ignored issues
show
Bug introduced by
Accessing timezone on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
149
            $time = $time->setTimezone('UTC');
150
        }
151
        else
152
            $time = new Carbon($value, 'UTC');
153
        
154
        $this->attributes['open_time'] = $time->format('H:i:s');
155
    }
156
    
157
    /**
158
     * Set the close time to UTC
159
     * If it is a device saving the time use UTC
160
     * If it is a user saving the time use their preferred timezone
161
     *
162
     * @param  string  $value
163
     * @return void
164
     */
165 View Code Duplication
    public function setCloseTimeAttribute($value)
166
    {
167
        //If the user is logged in then use there preferred timezone
168
        if (Auth::check())
169
        {
170
            $time = new Carbon($value, Auth::user()->timezone);
0 ignored issues
show
Bug introduced by
Accessing timezone on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
171
            $time = $time->setTimezone('UTC');
172
        }
173
        else
174
            $time = new Carbon($value, 'UTC');
175
        
176
        $this->attributes['close_time'] = $time->format('H:i:s');
177
    }
178
    
179
    /**
180
     * Scope a query to only include devices belonging to a given location
181
     *
182
     * @param \Illuminate\Database\Eloquent\Builder $query
183
     * @param int $location_id
184
     * @return \Illuminate\Database\Eloquent\Builder
185
     */
186
    public function scopeByLocation($query, $location_id)
187
    {
188
        return $query->where('location_id', $location_id);
189
    }
190
    
191
    /**
192
     * Scope a query to limit the included columns to only include what is publicly needed to be displayed on the
193
     * dashboard
194
     *
195
     * @param \Illuminate\Database\Eloquent\Builder $query
196
     * @return \Illuminate\Database\Eloquent\Builder
197
     */
198
    public function scopePublicDashData($query)
199
    {
200
        return $query->select([
0 ignored issues
show
Bug introduced by
The method select() does not exist on Illuminate\Database\Eloquent\Builder. Did you maybe mean createSelectWithConstraint()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
201
            'id',
202
            'name',
203
            'location_id',
204
            'cover_command',
205
            'cover_status',
206
            'open_time',
207
            'close_time',
208
            'update_rate',
209
            'image_rate',
210
            'sensor_rate',
211
        ]);
212
    }
213
    
214
    /**
215
     * Create a new API token for the device.
216
     */
217
    public function generateToken()
218
    {
219
        $this->token = str_random(60);
220
        $this->save();
221
        
222
        return $this->token;
223
    }
224
    
225
    /**
226
     * Get a device by uuid
227
     *
228
     * @param string $uuid
229
     * @return Device|Illuminate\Database\Eloquent\Model
230
     */
231
    public static function getDeviceByUUID($uuid)
232
    {
233
        return self::where('uuid', $uuid)->first();
234
    }
235
    
236
    /**
237
     * Get the deviceimage record associated with the device.
238
     */
239
    public function image()
240
    {
241
        return $this->hasOne('App\Deviceimage');
242
    }
243
    
244
245
    /**
246
     * Get the sensors associated with the device.
247
     */
248
    public function sensors()
249
    {
250
        return $this->hasMany('App\Sensor');
251
    }
252
    
253
    /**
254
     * Get the sensor data associated with the device.
255
     */
256
    public function data()
257
    {
258
        return $this->hasManyThrough('App\SensorData', 'App\Sensor');
259
    }
260
    
261
    /**
262
     * Is the device ready for a command
263
     *
264
     * @return boolean
265
     */
266
    public function isReadyForCommand()
267
    {
268
        $isReady = false;
269
        
270
        if ($this->cover_status == 'open' || $this->cover_status == 'closed' || $this->cover_status == 'locked')
271
            $isReady = true;
272
        
273
        return $isReady;
274
    }
275
    
276
    /**
277
     * Is the device schedule during open hours
278
     *
279
     * @return boolean
280
     */
281
    public function isDuringScheduleOpen()
282
    {
283
        $isOpenHours = false;
284
    
285
        $timezone = Auth::user()->timezone;
0 ignored issues
show
Bug introduced by
Accessing timezone on the interface Illuminate\Contracts\Auth\Authenticatable suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
286
        //Get the open, close, and current time in the users timezone
287
        $open_time = new Carbon($this->open_time, $timezone);
288
        $close_time = new Carbon($this->close_time, $timezone);
289
        $time_now = Carbon::now($timezone);
290
    
291
        //Check if the current time is during the open schedule or not
292
        if ($time_now->gt($open_time) && $time_now->lt($close_time))
293
            $isOpenHours = true;
294
        
295
        return $isOpenHours;
296
    }
297
}
298