Completed
Push — master ( 8c4f30...29607e )
by Temitope
02:58
created

EmojiController::checkForDuplicateEmoji()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 16
rs 9.4285
cc 3
eloc 11
nc 3
nop 1
1
<?php
2
/**
3
 * @author   Temitope Olotin <[email protected]>
4
 * @license  <https://opensource.org/license/MIT> MIT
5
 */
6
namespace Laztopaz\EmojiRestfulAPI;
7
8
use Firebase\JWT\JWT;
9
use Psr\Http\Message\ResponseInterface as Response;
10
use Psr\Http\Message\ServerRequestInterface as Request;
11
use Illuminate\Database\Capsule\Manager as Capsule;
12
13
class EmojiController
14
{
15
    private $auth;
16
17
    public function __construct(Oauth $auth)
18
    {
19
        $this->auth = $auth;
20
    }
21
22
    /**
23
     * This method list all emojis.
24
     *
25
     * @param $response
26
     *
27
     * @return json $emojis
28
     */
29
    public function listAllEmoji(Response $response)
30
    {
31
        $emojis = Emoji::with('keywords', 'category', 'created_by')->get();
32
        $emojis = $emojis->toArray();
33
34
        if (count($emojis) > 0) {
35
            return $response
36
            ->withJson($this->formatEmoji($emojis), 200);
37
        }
38
39
        return $response->withJson(['status'], 404);
40
    }
41
42
    /**
43
     * This method get a single emoji.
44
     *
45
     * @param $response
46
     * @param $args
47
     *
48
     * @return json $emoji
49
     */
50
    public function getSingleEmoji(Response $response, $args)
51
    {
52
        $id = $args['id'];
53
54
        $emoji = Emoji::where('id', '=', $id)->with('keywords', 'category', 'created_by')->get();
55
        $emoji = $emoji->toArray();
56
57
        if (count($emoji) > 0) {
58
            return $response
59
            ->withJson($this->formatEmoji($emoji), 200);
60
        }
61
62
        return $response->withJson(['message' => 'Emoji not found'], 404);
63
    }
64
65
    /**
66
     * This method creates a new emoji.
67
     *
68
     * @param $args
69
     *
70
     * @return json $response;
71
     */
72
    public function createEmoji(Request $request, Response $response)
73
    {
74
        $requestParams = $request->getParsedBody();
75
76
        $emojiKeyword = $requestParams['keywords'];
77
78
        $userId = $this->getCurrentUserId($request, $response);
79
80
        if (is_array($requestParams)) {
81
            $created_at = date('Y-m-d h:i:s');
82
83
            if (! $this->checkForDuplicateEmoji($requestParams['name'])) {
84
                $emoji = Emoji::create(
85
                [
86
                    'name'       => $requestParams['name'],
87
                    'char'       => $requestParams['char'],
88
                    'created_at' => $created_at,
89
                    'category'   => $requestParams['category'],
90
                    'created_by' => $userId,
91
                ]);
92
93
                if ($emoji->id) {
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Laztopaz\EmojiRestfulAPI\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...
94
                    $createdKeyword = $this->createEmojiKeywords($emoji->id, $emojiKeyword);
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Laztopaz\EmojiRestfulAPI\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...
Unused Code introduced by
$createdKeyword 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...
95
96
                    return $response->withJson($emoji->toArray(), 201);
97
                }
98
            }
99
100
            return $response->withJson(['message' => 'Emoji cannot be duplicated'], 400);
101
        }
102
    }
103
104
    /**
105
     * This method updates an emoji.
106
     *
107
     * @param $request
108
     * @param $response
109
     *
110
     * @return json
111
     */
112
    public function updateEmojiByPutVerb(Request $request, Response $response, $args)
113
    {
114
        $upateParams = $request->getParsedBody();
115
116
        if (is_array($upateParams)) {
117
            $id = $args['id'];
118
119
            $emoji = Emoji::find($id);
120
121
            if ($emoji->id) {
122
                $emoji->name = $upateParams['name'];
123
                $emoji->char = $upateParams['char'];
124
                $emoji->category = $upateParams['category'];
125
                $emoji->updated_at = date('Y-m-d h:i:s');
126
                $emoji->save();
0 ignored issues
show
Bug introduced by
The method save does only exist in Illuminate\Database\Eloquent\Model, but not in Illuminate\Database\Eloq...ase\Eloquent\Collection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
127
128
                return $response->withJson(['message' => 'Record updated successfully'], 201);
129
            }
130
131
            return $response->withJson(['message' => 'Record cannot be updated'], 404);
132
        }
133
    }
134
135
    /**
136
     * This method updates an emoji partially.
137
     *
138
     * @param $request
139
     * @param $response
140
     *
141
     * @return json
142
     */
143
    public function updateEmojiByPatchVerb(Request $request, Response $response, $args)
144
    {
145
        $upateParams = $request->getParsedBody();
146
147
        if (is_array($upateParams)) {
148
            $id = $args['id'];
149
150
            $emoji = Emoji::find($id);
151
            if ($emoji->id) {
152
                $emoji->name = $upateParams['name'];
153
                $emoji->updated_at = date('Y-m-d h:i:s');
154
                $emoji->save();
0 ignored issues
show
Bug introduced by
The method save does only exist in Illuminate\Database\Eloquent\Model, but not in Illuminate\Database\Eloq...ase\Eloquent\Collection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
155
156
                return $response->withJson($emoji->toArray(), 201);
0 ignored issues
show
Bug introduced by
The method toArray does only exist in Illuminate\Database\Eloq...Database\Eloquent\Model, but not in Illuminate\Database\Eloquent\Builder.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
157
            }
158
159
            return $response->withJson(['message' => 'No record to update'], 404);
160
        }
161
    }
162
163
    /**
164
     * This method deletes an emoji.
165
     *
166
     * @param $request
167
     * @param $response
168
     * @param $args
169
     *
170
     * @return json
171
     */
172
    public function deleteEmoji(Request $request, Response $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...
173
    {
174
        $id = $args['id'];
175
176
        $emoji = Emoji::find($id);
177
        if ($emoji->id) {
178
            $emoji->delete();
0 ignored issues
show
Bug introduced by
The method delete does only exist in Illuminate\Database\Eloq...Database\Eloquent\Model, but not in Illuminate\Database\Eloquent\Collection.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
179
            // Delete keywords associated with the emoji
180
            Keyword::where('emoji_id', '=', $id)->delete();
181
182
            return $response->withJson(['message' => 'Emoji was sucessfully deleted'], 204);
183
        }
184
185
        return $response->withJson(['message' => 'Emoji cannot be deleted'], 404);
186
    }
187
188
    /**
189
     * This method creates emoji keywords.
190
     *
191
     * @param $request
192
     * @param $response
193
     * @param $args
194
     *
195
     * @return $id
0 ignored issues
show
Documentation introduced by
The doc-type $id could not be parsed: Unknown type name "$id" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
196
     */
197 View Code Duplication
    public function createEmojiKeywords($emoji_id, $keywords)
0 ignored issues
show
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...
198
    {
199
        if ($keywords) {
200
            $splittedKeywords = explode(',', $keywords);
201
202
            $created_at = date('Y-m-d h:i:s');
203
204
            foreach ($splittedKeywords as $keyword) {
205
                $emojiKeyword = Keyword::create([
206
                        'emoji_id'     => $emoji_id,
207
                        'keyword_name' => $keyword,
208
                        'created_at'   => $created_at,
209
                ]);
210
            }
211
        }
212
213
        return $emojiKeyword->id;
0 ignored issues
show
Documentation introduced by
The property id does not exist on object<Laztopaz\EmojiRestfulAPI\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...
214
    }
215
216
    /**
217
     * This method format emoji result
218
     *
219
     * @param $emojis
220
     *
221
     * @return array $emojis
222
     */
223
    public function formatEmoji(array $emojis)
224
    {
225
        foreach ($emojis as $key => &$value) {
226
            $value['created_by'] = $value['created_by']['firstname'].' '.$value['created_by']['lastname'];
227
            $value['category'] = $value['category']['category_name'];
228
            $value['keywords'] = array_map(function ($key) { return $key['keyword_name']; }, $value['keywords']);
229
        }
230
231
        return $emojis;
232
    }
233
234
    /**
235
     * This method authenticate and return user id.
236
     */
237
    public function getCurrentUserId($request, $response)
238
    {
239
        $loadEnv = DatabaseConnection::loadEnv();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $loadEnv is correct as \Laztopaz\EmojiRestfulAP...seConnection::loadEnv() (which targets Laztopaz\EmojiRestfulAPI...seConnection::loadEnv()) seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Unused Code introduced by
$loadEnv 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...
240
241
        $jwtoken = $request->getHeader('HTTP_AUTHORIZATION');
242
243
        try {
244
            if (isset($jwtoken)) {
245
                $secretKey = base64_decode(getenv('secret'));
246
247
                $jwt = json_decode($jwtoken[0], true);
248
249
                //decode the JWT using the key from config
250
                $decodedToken = JWT::decode($jwt['jwt'], $secretKey, ['HS512']);
251
252
                $tokenInfo = (array) $decodedToken;
253
254
                $userInfo = (array) $tokenInfo['dat'];
255
256
                return $userInfo['id'];
257
            }
258
        } catch (\Exception $e) {
259
            return $response->withJson(['status' => $e->getMessage()], 401);
260
        }
261
    }
262
263
    /**
264
     * This method checks for duplicate emoji
265
     *
266
     * @param $name
267
     *
268
     * @return boolean true
269
     */
270
    public function checkForDuplicateEmoji($emojiName)
271
    {
272
        if (isset($emojiName)) {
273
            $emojiFound = Capsule::table('emojis')
274
            ->where('name', '=', strtoupper($emojiName))
275
            ->orWhere('name', '=', strtolower($emojiName))
276
            ->orWhere('name', '=', ucwords($emojiName))
277
            ->orWhere('name', '=', $emojiName)
278
            ->get();
279
            
280
            if (count($emojiFound) > 0) {
281
                return true;
282
            }
283
        }
284
        return false;
285
    }
286
}
287