Passed
Branch 2.0 (f5ddb0)
by Samuel
04:04
created

ModelNotFoundHandler::extractEntityName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 5
nc 2
nop 1
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace SMartins\Exceptions\Handlers;
4
5
use SMartins\Exceptions\JSONAPI\Error;
6
use SMartins\Exceptions\JSONAPI\Source;
7
8
class ModelNotFoundHandler extends AbstractHandler
9
{
10
    /**
11
     * {@inheritDoc}
12
     */
13
    public function handle()
14
    {
15
        $entity = $this->extractEntityName($this->exception->getModel());
0 ignored issues
show
Bug introduced by
The method getModel() does not exist on Exception. Did you maybe mean getCode()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

15
        $entity = $this->extractEntityName($this->exception->/** @scrutinizer ignore-call */ getModel());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
16
17
        $detail = __('exception::exceptions.model_not_found.title', ['model' => $entity]);
18
19
        return (new Error)->setStatus(404)
0 ignored issues
show
Bug Best Practice introduced by
The expression return new SMartins\Exce...)))->setDetail($detail) returns the type SMartins\Exceptions\JSONAPI\Error which is incompatible with the return type mandated by SMartins\Exceptions\Hand...stractHandler::handle() of array|Illuminate\Support\Collection.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
20
            ->setCode($this->getCode('model_not_found'))
21
            ->setSource((new Source())->setPointer('data/id'))
22
            ->setTitle(snake_case(class_basename($this->exception)))
23
            ->setDetail($detail);
24
    }
25
26
    /**
27
     * Get entity name based on model path to mount the message.
28
     *
29
     * @param  string $model
30
     * @return string
31
     */
32
    public function extractEntityName($model)
33
    {
34
        $classNames = (array) explode('\\', $model);
35
36
        $entityName = end($classNames);
37
38
        if ($this->entityHasTranslation($entityName)) {
39
            return __('exception::exceptions.models.'.$entityName);
0 ignored issues
show
Bug Best Practice introduced by
The expression return __('exception::ex...models.' . $entityName) also could return the type array which is incompatible with the documented return type string.
Loading history...
40
        }
41
42
        return $entityName;
43
    }
44
45
    /**
46
     * Check if entity returned on ModelNotFoundException has translation on
47
     * exceptions file.
48
     *
49
     * @param  string $entityName The model name to check if has translation
50
     * @return bool               Has translation or not
51
     */
52
    public function entityHasTranslation(string $entityName): bool
53
    {
54
        $hasKey = in_array($entityName, $this->translationModelKeys());
55
56
        if ($hasKey) {
57
            return ! empty($hasKey);
58
        }
59
60
        return false;
61
    }
62
63
    /**
64
     * Get the models keys on exceptions lang file.
65
     *
66
     * @return array An array with keys to translate
67
     */
68
    private function translationModelKeys(): array
69
    {
70
        return array_keys(__('exception::exceptions.models'));
71
    }
72
}
73