Completed
Pull Request — master (#82)
by Brandon
02:15
created

ApiController::sensor()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 56
Code Lines 22

Duplication

Lines 3
Ratio 5.36 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 3
loc 56
ccs 0
cts 18
cp 0
rs 9.0544
cc 4
eloc 22
nc 4
nop 1
crap 20

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Http\Controllers;
4
5
use Validator;
6
use Illuminate\Http\Request;
7
use App\Device;
8
use App\Deviceimage;
9
use App\User;
10
use App\Sensor;
11
use App\SensorData;
12
use Illuminate\Support\Facades\Cache;
13
use Illuminate\Support\Facades\Storage;
14
15
class ApiController extends Controller
16
{
17
    /**
18
     * Creates a json response for all the devices.
19
     *
20
     * @return Response
21
     */    
22
    public function index()
23
    {
24
        return response()->json(['data' => 'SmartSettia API - Bad request type.'], 400);
25
    }
26
27
    /**
28
     * Creates a json response for a specifc device.
29
     *
30
     * @param  Device  $device
31
     * @return Response
32
     */    
33
    public function show(Device $device)
34
    {
35
        return response()->json($device, 200);
36
    }
37
38
    /**
39
     * Updates the status of a device.
40
     *
41
     * @param  Request  $request
42
     * @return Response
43
     */
44
    public function update(Request $request)
45
    {
46
        // Validate the request
47
        $validator = Validator::make($request->all(), [
48
            'uuid'          => 'required|string|max:255|exists:devices,uuid',
49
            'token'         => 'required|string|max:60',
50
            'version'       => 'nullable|string|max:32',
51
            'hostname'      => 'nullable|string|max:255',
52
            'ip'            => 'nullable|ip',
53
            'mac_address'   => 'nullable|string|min:12|max:12',
54
            'time'          => 'nullable|date',
55
            'cover_status'  => 'nullable|string|max:32',
56
            'error_msg'     => 'nullable|string',
57
            'limitsw_open'   => 'nullable|boolean',
58
            'limitsw_closed' => 'nullable|boolean',
59
            'light_in'      => 'nullable|numeric',
60
            'light_out'     => 'nullable|numeric',
61
            'cpu_temp'      => 'nullable|numeric',
62
            'temperature'   => 'nullable|numeric',
63
            'humidity'      => 'nullable|numeric',
64
        ]);
65
        
66
        // If validation fails, send the validation error back with status 400.
67
        if ($validator->fails()) {
68
            return response()->json(['data' => $validator->errors()], 400);
69
        }
70
        
71
        // Get the device record.
72
        $device = Device::getDeviceByUUID($request->input('uuid'));
73
        
74
        // If token doesnt match then send 401 unauthorized.
75 View Code Duplication
        if ($request->input('token') != $device->token) {
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...
76
            return response()->json(['data' => 'Bad token.'], 401);
77
        }
78
        
79
        // Update the device.
80
        $device->version = $request->input('version');
81
        $device->hostname = $request->input('hostname');
82
        $device->ip = $request->input('ip');
83
        $device->mac_address = $request->input('mac_address');
84
        $device->time = $request->input('time');
85
        $device->cover_status = $request->input('cover_status');
86
        $device->error_msg = $request->input('error_msg');
87
        $device->limitsw_open = $request->input('limitsw_open');
88
        $device->limitsw_closed = $request->input('limitsw_closed');
89
        $device->light_in = $request->input('light_in');
90
        $device->light_out = $request->input('light_out');
91
        $device->cpu_temp = $request->input('cpu_temp');
92
        $device->temperature = $request->input('temperature');
93
        $device->humidity = $request->input('humidity');
94
        
95
        $device->save();
96
        
97
        // A 'Registered' event is created and will trigger any relevant
98
        // observers, such as sending a confirmation email or any 
99
        // code that needs to be run as soon as the device is created.
100
        //event(new Registered(true));
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
101
        
102
        // Return the new device info including the token.
103
        return response()->json(['data' => $device->toArray()], 201);
104
    }
105
    
106
    /**
107
     * Updates the sensors of a device.
108
     *
109
     * @param  Request  $request
110
     * @return Response
111
     */
112
    public function sensor(Request $request)
113
    {
114
        // Validate the request
115
        $validator = Validator::make($request->all(), [
116
            'uuid'          => 'required|string|max:255|exists:devices,uuid',
117
            'token'         => 'required|string|max:60',
118
            'sensor_data.*.name'   => 'required',
119
            'sensor_data.*.type'   => 'required',
120
            'sensor_data.*.value'  => 'required',
121
        ]);
122
        
123
        // If validation fails, send the validation error back with status 400.
124
        if ($validator->fails()) {
125
            return response()->json(['data' => $validator->errors()], 400);
126
        }
127
        
128
        // Get the device record.
129
        $device = Device::getDeviceByUUID($request->input('uuid'));
130
        
131
        // If token doesnt match then send 401 unauthorized.
132 View Code Duplication
        if ($request->input('token') != $device->token) {
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...
133
            return response()->json(['data' => 'Bad token.'], 401);
134
        }
135
        
136
        // Update the device.
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
137
// 		"sensor_data": {
138
// 			{ "name": "cpu", "type": "cpu_temperature", "value": cpu_temp() },
139
// 			{ "name": "temperature", "type": "temperature", "value": temperature() },
140
// 			{ "name": "humidity", "type": "humidity", "value": humidity() },
141
// 			{ "name": "moisture_01", "type": "moisture", "value": 0.00 },
142
// 			{ "name": "moisture_02", "type": "moisture", "value": 0.00 },
143
// 			{ "name": "light_in", "type": "light", "value": 0.00 },
144
// 			{ "name": "light_out", "type": "light", "value": 0.00 }
145
// 		}
146
        $sensor_datas = $request->input('sensor_data');
147
        foreach ($sensor_datas as $sensor_data) {
0 ignored issues
show
Bug introduced by
The expression $sensor_datas of type string|array is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
148
            $sensor = Sensor::firstOrCreate([
149
                "device_id" => $device->id,
150
                "name" => $sensor_data['name'], 
151
                "type" => $sensor_data['type']
152
            ]);
153
            
154
            SensorData::create([
155
                "sensor_id" => $sensor->id,
156
                "value" => $sensor_data['value']
157
            ]);
158
        }
159
        
160
        // A 'Registered' event is created and will trigger any relevant
161
        // observers, such as sending a confirmation email or any 
162
        // code that needs to be run as soon as the device is created.
163
        //event(new Registered(true));
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
164
        
165
        // Return the new device info including the token.
166
        return response()->json(['data' => $device->toArray()], 201);
167
    }
168
    
169
    /**
170
     * Registers a new device.
171
     *
172
     * @param  Request  $request
173
     * @return Response
174
     */
175
    public function register(Request $request)
176
    {
177
        // Validate the request.
178
        $validator = Validator::make($request->all(), [
179
            'uuid' => 'required|string|max:255',
180
            'challenge' => 'required|string|min:6',
181
        ]);
182
        
183
        // If validation fails, send the validation error back with status 400.
184
        if ($validator->fails()) {
185
            return response()->json(['data' => $validator->errors()], 400);
186
        }
187
        
188
        // If challenge string doesnt match then send 401 unauthorized.
189
        if ($request->input('challenge') != env('API_CHALLENGE', 'temppass')) {
190
            return response()->json(['data' => 'Bad challenge.'], 401);
191
        }
192
        
193
        // If the uuid already exists then just send them the record.
194
        if ($device = Device::getDeviceByUUID($request->input('uuid'))) {
195
            return response()->json([ 'data' => [ 
196
                'name' => $device->name,
197
                'uuid' => $device->uuid,
198
                'id' => $device->id,
199
                'token' => $device->token,
200
            ]], 200);
201
        }
202
        
203
        // Create the new device.
204
        $device = new Device;
205
        $device->name = 'New Device';
206
        $device->uuid = $request->input('uuid');
207
        $device->save();
208
        
209
        // Create an api token for the new device.
210
        $device->generateToken();
211
        
212
        // A 'Registered' event is created and will trigger any relevant
213
        // observers, such as sending a confirmation email or any 
214
        // code that needs to be run as soon as the device is created.
215
        //event(new Registered(true));
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
216
        //Notification::send(User::managers(), new DeviceRegister($device));
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
217
        
218
        // Return the new device info including the token.
219
        return response()->json([ 'data' => [ 
220
            'name' => $device->name,
221
            'uuid' => $device->uuid,
222
            'id' => $device->id,
223
            'token' => $device->token,
224
        ]], 201);
225
    }
226
    
227
    /**
228
     * Updates the image for a device.
229
     *
230
     * @param  Request  $request
231
     * @return Response
232
     */
233
    public function image(Request $request) {
234
        // Validate the request.
235
        $validator = Validator::make($request->all(), [
236
            'uuid'          => 'required|string|max:255|exists:devices,uuid',
237
            'token'         => 'required|string|max:60',
238
            'image'         => 'required|image|mimes:jpeg,jpg|max:2048',
239
        ]);
240
        
241
        // If validation fails, send the validation error back with status 400.
242
        if ($validator->fails()) {
243
            return response()->json(['data' => $validator->errors()], 400);
244
        }
245
        
246
        // Get the device record.
247
        $device = Device::getDeviceByUUID($request->input('uuid'));
248
        
249
        // If token doesnt match then send 401 unauthorized.
250
        if ($request->input('token') != $device->token) {
251
            return response()->json(['data' => 'Bad token.'], 401);
252
        }
253
        
254
        // Save the image to disk.
255
        $path = $request->file('image')->storeAs('deviceimage', $device['id'], 'private');
256
        
257
        // Update the url for the image.
258
        $deviceimage = Deviceimage::updateOrCreate(
259
            ['device_id' => $device['id']],
260
            ['url' => $path]
261
        );
262
        
263
        // Force the updated_at timestamp to update as the url may not change.
264
        $deviceimage->touch();
265
        
266
        return response()->json([ 'data' => [ 
267
            'id' => $deviceimage['id'],
268
            'url' => $path,
269
        ]], 201);
270
    }
271
}
272
273
// HTTP STATUS CODES:
274
// 200: OK. The standard success code and default option.
275
// 201: Object created. Useful for the store actions.
276
// 204: No content. When an action was executed successfully, but there is no content to return.
277
// 206: Partial content. Useful when you have to return a paginated list of resources.
278
// 400: Bad request. The standard option for requests that fail to pass validation.
279
// 401: Unauthorized. The user needs to be authenticated.
280
// 403: Forbidden. The user is authenticated, but does not have the permissions to perform an action.
281
// 404: Not found. This will be returned automatically by Laravel when the resource is not found.
282
// 500: Internal server error. Ideally you're not going to be explicitly returning this, but if something unexpected breaks, this is what your user is going to receive.
283
// 503: Service unavailable. Pretty self explanatory, but also another code that is not going to be returned explicitly by the application.