Completed
Push — master ( 526b4c...259497 )
by Adeola
02:28
created

EmojiController::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 1
Metric Value
c 3
b 1
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
/**
4
 * @author: Raimi Ademola <[email protected]>
5
 * @copyright: 2016 Andela
6
 */
7
namespace Demo;
8
9
10
use Exception;
11
use Carbon\Carbon;
12
use Firebase\JWT\JWT;
13
use Illuminate\Database\Capsule\Manager as Capsule;
14
use Psr\Http\Message\ResponseInterface as Response;
15
16
class EmojiController
17
{
18
    public $authController;
19
20
    /**
21
     * This is a constructor; a default method  that will be called automatically during class instantiation.
22
     */
23
    public function __construct()
24
    {
25
        $this->authController = new AuthController();
26
    }
27
28
    /**
29
     * Get all emojis.
30
     *
31
     * @param Slim\Http\Request  $request
32
     * @param Slim\Http\Response $response
33
     * @param array              $args
34
     *
35
     * @return Slim\Http\Response
36
     */
37 View Code Duplication
    public function getAllEmojis($request, $response, $args)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $args is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Duplication introduced by
This method seems to be duplicated in 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...
38
    {
39
        $emoji = Emoji::with('keywords', 'created_by')->get();
40
41
        if (count($emoji) > 0) {
42
            return $response->withJson($emoji);
43
        }
44
45
        return $response->withJson(['message' => 'Oops, No Emoji to display'], 404);
46
    }
47
48
    /**
49
     * Get a single emoji.
50
     *
51
     * @param Slim\Http\Request  $request
52
     * @param Slim\Http\Response $response
53
     * @param array              $args
54
     *
55
     * @return Slim\Http\Response
56
     */
57 View Code Duplication
    public function getSingleEmoji($request, $response, $args)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Duplication introduced by
This method seems to be duplicated in 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...
58
    {
59
        $emoji = Emoji::with('keywords', 'created_by')->find($args['id']);
60
61
        if (count($emoji) < 1) {
62
            return $response->withJson(['message' => 'The requested Emoji is not found.'], 404);
63
        }
64
65
        return $response->withJson($emoji);
66
    }
67
68
    /**
69
     * This method creates emoji and keywords associated with it.
70
     *
71
     * @param $request
72
     * @param $response
73
     * @param $requestParams
74
     *
75
     * @return json response
76
     */
77
    public function CreateEmoji($request, $response, $requestParams)
0 ignored issues
show
Unused Code introduced by
The parameter $requestParams is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
78
    {
79
        $requestParams     = $request->getParsedBody();
80
        $validateUserData = $this->authController->validateUserData(['name', 'chars', 'category', 'keywords'], $requestParams);
81
82
        if (is_array($validateUserData)) {
83
            return $response->withJson($validateUserData, 400);
84
        }
85
        
86
        $validateEmptyInput = $this->checkEmptyInput($requestParams['name'], $requestParams['chars'], $requestParams['category'], $requestParams['keywords']);
87
88
        if (is_array($validateEmptyInput)) {
89
            return $response->withJson($validateEmptyInput, 401);
90
        }
91
92
        $validateEmojiDuplicate = $this->checkDuplicateEmoji($requestParams['name'], $requestParams['chars']);
93
94
        if (is_array($validateEmojiDuplicate)) {
95
            return $response->withJson($validateEmojiDuplicate, 400);
96
        }
97
98
        $emoji = Emoji::create([
99
            'name'       => strtolower($requestParams['name']),
100
            'chars'      => $requestParams['chars'],
101
            'category'   => $requestParams['category'],
102
            'created_at' => Carbon::now()->toDateTimeString(),
103
            'updated_at' => Carbon::now()->toDateTimeString(),
104
            'created_by' => $this->getUserId($request, $response),
105
        ]);
106
107
        $this->createEmojiKeywords($emoji->id, $requestParams['keywords']);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Demo\Emoji>. 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...
108
109
        return $response->withJson($emoji->toArray(), 201);
110
    }
111
112
    /**
113
     * This method updates an emoji by using Patch.
114
     *
115
     * @param $request
116
     * @param $response
117
     * @param $args
118
     *
119
     * @return json $response
120
     */
121
    public function updateEmojiByPatch($request, $response, $args)
122
    {
123
        $updateParams = $request->getParsedBody();
124
125
        $validateUserData = $this->authController->validateUserData(['name'], $updateParams);
126
       
127
        if (is_array($validateUserData)) {
128
            return $response->withJson($validateUserData, 400);
129
        }
130
131
        $validateArgs = $this->validateArgs($request, $response, $args);
132
133
        if (is_array($validateArgs)) {
134
            return $response->withJson($validateArgs, 401);
135
        }
136
137
        Emoji::where('id', '=', $args['id'])
138
            ->update(['name' => strtolower($updateParams['name']), 'updated_at' => Carbon::now()->toDateTimeString()]);
139
140
        return $response->withJson(['message' => 'Emoji has been updated successfully'], 200);
141
    }
142
143
    /**
144
     * This method updates an emoji by using put.
145
     *
146
     * @param $request
147
     * @param $response
148
     * @param $args
149
     *
150
     * @return json $response
151
     */
152
    public function updateEmojiByPut($request, $response, $args)
153
    {
154
        $updateParams = $request->getParsedBody();
155
156
        $validateUserData = $this->authController->validateUserData(['name', 'chars', 'category'], $updateParams);
157
       
158
        if (is_array($validateUserData)) {
159
            return $response->withJson($validateUserData, 400);
160
        }
161
162
        $validateArgs = $this->validateArgs($request, $response, $args);
163
164
        if (is_array($validateArgs)) {
165
            return $response->withJson($validateArgs, 401);
166
        }
167
168
        Emoji::where('id', '=', $args['id'])
169
            ->update(['name' => strtolower($updateParams['name']), 'chars' => $updateParams['chars'], 'category' => $updateParams['category'], 'updated_at' => Carbon::now()->toDateTimeString()]);
170
171
        return $response->withJson(['message' => 'Emoji has been updated successfully'], 200);
172
    }
173
174
    /**
175
     * This method deletes an emoji.
176
     *
177
     * @param Slim\Http\Request  $request
178
     * @param Slim\Http\Response $response
179
     * @param array              $args
180
     *
181
     * @return json response
182
     */
183
    public function deleteEmoji($request, $response, $args)
184
    {
185
        $validateArgs = $this->validateArgs($request, $response, $args);
186
187
        if (is_array($validateArgs)) {
188
            return $response->withJson($validateArgs, 401);
189
        }
190
191
        Emoji::where('id', '=', $args['id'])->delete();
192
193
        return $response->withJson(['message' => 'Emoji successfully deleted.'], 200);
194
    }
195
196
    /**
197
     * This method authenticate and returns user id.
198
     *
199
     * @param $response
200
     * @param $request
201
     *
202
     * @return user id
203
     */
204
    public function getUserId($request, $response)
205
    {
206
        $jwtoken = $request->getHeader('HTTP_AUTHORIZATION');
207
208
        try {
209
            if (isset($jwtoken)) {
210
                $secretKey    = getenv('APP_SECRET');
211
                $jwt          = $jwtoken[0];
212
                $decodedToken = JWT::decode($jwt, $secretKey, ['HS512']);
213
                $tokenInfo    = (array) $decodedToken;
214
                $userInfo     = (array) $tokenInfo['data'];
215
216
                return $userInfo['userId'];
217
            }
218
        } catch (Exception $e) {
219
            return $response->withJson(['status: fail, msg: Unauthorized']);
220
        }
221
    }
222
223
    /**
224
     * This method solves for rightful owner of a record.
225
     *
226
     * @param $response
227
     * @param $request
228
     * @param $args
229
     *
230
     * @return user id
231
     */
232
    public function getTheOwner($request, $response, $args)
233
    {
234
        return Capsule::table('emojis')
235
            ->where('id', '=', $args['id'])
236
            ->where('created_by', '=', $this->getUserId($request, $response));
237
    }
238
239
    /**
240
     * This method creates emoji keywords.
241
     *
242
     * @param $emoji_id
243
     * @param $keywords
244
     *
245
     * @return keyword id
246
     */
247
    public function createEmojiKeywords($emoji_id, $keywords)
248
    {
249
        if (isset($keywords)) {
250
            $splittedKeywords = explode(',', $keywords);
251
            $created_at       = Carbon::now()->toDateTimeString();
252
            $updated_at       = Carbon::now()->toDateTimeString();
253
254
            foreach ($splittedKeywords as $keyword) {
255
                $emojiKeyword = Keyword::create([
256
                    'emoji_id'     => $emoji_id,
257
                    'keyword_name' => $keyword,
258
                    'created_at'   => $created_at,
259
                    'updated_at'   => $updated_at,
260
                ]);
261
            }
262
263
            return $emojiKeyword->id;
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Demo\Keyword>. 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...
Bug introduced by
The variable $emojiKeyword does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
264
        }
265
266
        return true;
267
    }
268
269
    /**
270
     * This method checks for empty input from user.
271
     *
272
     * @param $inputName
273
     * @param $inputChars
274
     * @param $inputCategory
275
     * @param $inputKeywords
276
     *
277
     * @return bool
278
     */
279
    public function checkEmptyInput($inputName, $inputChars, $inputCategory, $inputKeywords)
280
    {
281
        if (empty($inputName) || empty($inputChars) || empty($inputCategory) || empty($inputKeywords)) {
282
            return ['message' => 'All fields must be provided.'];
283
        }
284
285
        return true;
286
    }
287
288
    /**
289
     * This method checks for duplicate emoji.
290
     *
291
     * @param $inputName
292
     * @param $inputChars
293
     *
294
     * @return bool
295
     */
296
    public function checkDuplicateEmoji($inputName, $inputChars)
297
    {
298
        $nameCheck = Capsule::table('emojis')->where('name', '=', strtolower($inputName))->get();
299
        $charsCheck = Capsule::table('emojis')->where('chars', '=', $inputChars)->get();
300
       
301
        if ($nameCheck || $charsCheck) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $nameCheck of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
Bug Best Practice introduced by
The expression $charsCheck of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
302
303
            return ['message' => 'The emoji already exist in the database.'];
304
        }
305
306
        return true;
307
    }
308
309
    /**
310
     * This method checks for empty input from user.
311
     *
312
     * @param $request
313
     * @param $response
314
     * @param $args
315
     *
316
     * @return bool
317
     */
318
    public function validateArgs($request, $response, $args)
319
    {
320
        $emoji = Emoji::find($args['id']);
321
        
322
        if (count($emoji) < 1) {
323
            return ['message' => 'Action cannot be performed because the id supplied is invalid'];
324
        }
325
326
        if (is_null($this->getTheOwner($request, $response, $args)->first())) {
0 ignored issues
show
Documentation Bug introduced by
The method first does not exist on object<Demo\User>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
327
            return ['message' => 'Action cannot be performed because you are not the creator'];
328
        }
329
330
        return true;
331
    }
332
}
333