Completed
Pull Request — master (#96)
by
unknown
05:29
created

Device::dashPageNum()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 9
ccs 0
cts 6
cp 0
rs 9.6666
cc 1
eloc 6
nc 1
nop 1
crap 2
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
     * Check if the device is ready for a command
263
     *
264
     * @return boolean
265
     */
266
    public function isReadyForCommand()
267
    {
268
        return ($this->cover_status == 'open' || $this->cover_status == 'closed' || $this->cover_status == 'locked');
269
    }
270
    
271
    /**
272
     * Check if the current time is during the devices scheduled time to be open
273
     *
274
     * @return boolean
275
     */
276
    public function isDuringScheduleOpen()
277
    {
278
        $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...
279
        //Get the open, close, and current time in the users timezone
280
        $open_time = new Carbon($this->open_time, $timezone);
281
        $close_time = new Carbon($this->close_time, $timezone);
282
        $time_now = Carbon::now($timezone);
283
    
284
        //Check if the current time is during the open schedule or not
285
        if ($time_now->gt($open_time) && $time_now->lt($close_time))
286
            return true;
287
        else
288
            return false;
289
    }
290
    
291
    /**
292
     * Get the covers actual status based on the current command and the devices status
293
     *
294
     * @return string
295
     */
296
    public function actualCoverStatus()
297
    {
298
        $status = '';
0 ignored issues
show
Unused Code introduced by
$status is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
299
        $isOpen = $this->cover_status === 'open';
300
        $isClosed = $this->cover_status === 'closed';
301
            
302
        switch ($this['cover_command'])
303
        {
304
            case 'open':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
305
                if ($isOpen)
306
                    $status = 'open';
307
                else
308
                    $status = 'opening';
309
                break;
310
            case 'close':
0 ignored issues
show
Coding Style introduced by
case statements should be defined using a colon.

As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next break.

There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.

switch ($expr) {
    case "A": { //wrong
        doSomething();
        break;
    }
    case "B"; //wrong
        doSomething();
        break;
    case "C": //right
        doSomething();
        break;
}

To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.

Loading history...
311
                if ($isClosed)
312
                    $status = 'closed';
313
                else
314
                    $status = 'closing';
315
                break;
316
            case 'lock':
317
                $status = 'locked';
318
                break;
319
            default:
320
                $status = 'error';
321
        }
322
    
323
        if ($this->cover_status === 'error')
324
            $status = 'error';
325
        
326
        return $status;
327
    }
328
    
329
    /**
330
     * Get the page number of the device for the dashboard device table pagination
331
     *
332
     * @param int $limit
333
     * @return int
334
     */
335
    public function dashPageNum($limit)
336
    {
337
        $pos = Device::where('location_id', '=', $this->location_id)
338
            ->where('name', '<=', $this->name)
339
            ->orderBy('name', 'ASC')
340
            ->count();
341
        
342
        return ceil($pos / $limit);
343
    }
344
}
345