Passed
Push — master ( 8005df...2d92e4 )
by Darío
03:27
created

ErrorTrait::_error()   B

Complexity

Conditions 9
Paths 12

Size

Total Lines 28
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 9
eloc 13
nc 12
nop 2
dl 0
loc 28
rs 8.0555
c 0
b 0
f 0
1
<?php
2
/**
3
 * DronePHP (http://www.dronephp.com)
4
 *
5
 * @link      http://github.com/Pleets/DronePHP
6
 * @copyright Copyright (c) 2016-2018 Pleets. (http://www.pleets.org)
7
 * @license   http://www.dronephp.com/license
8
 * @author    Darío Rivera <[email protected]>
9
 */
10
11
namespace Drone\Error;
12
13
/**
14
 * ErrorTrait trait
15
 *
16
 * Standard error management for some classes
17
 */
18
trait ErrorTrait
19
{
20
    /**
21
     * Common errors
22
     *
23
     * @var array
24
     */
25
    protected $standardErrors = [
26
27
        # File errros
28
        1 => 'Failed to open stream \'%file%\', Permission Denied!',
29
        2 => 'No such file or directory \'%file%\'',
30
        3 => 'File exists \'%file%\'',
31
        4 => 'Stream \'%file%\' is Not a directory',
32
33
        # JSON errors
34
        10 => 'Failed to decode JSON file \'%file%\'',
35
        11 => 'Failed to encode JSON file \'%file%\'',
36
37
        # Database related errors
38
        20 => 'The transaction was already started',
39
        21 => 'The transaction has not been started',
40
        22 => 'Transaction cannot be empty',
41
    ];
42
43
    /**
44
     * Failure messages
45
     *
46
     * This member stores all failure messages as an array of key/value pairs.
47
     *
48
     * key:   The the code of the error (usually in Errno class). Also the ERROR_CONSTANT.
49
     * value: The error message.
50
     *
51
     * If the key is not an integer, the error is not in Errno class.
52
     *
53
     * @var array
54
     */
55
    protected $errors = [];
56
57
    /**
58
     * Returns an array with all failure messages
59
     *
60
     * @return array
61
     */
62
    public function getErrors()
63
    {
64
        return $this->errors;
65
    }
66
67
    /**
68
     * Returns true if there is at least one error or false if not
69
     *
70
     * @return array
71
     */
72
    public function hasErrors()
73
    {
74
        return (bool) count($this->errors);
0 ignored issues
show
Bug Best Practice introduced by
The expression return (bool)count($this->errors) returns the type boolean which is incompatible with the documented return type array.
Loading history...
75
    }
76
77
    /**
78
     * Adds an error
79
     *
80
     * When the error is standard (i.e. exists in Errno class) the behavior is as follow:
81
     * - _error(int ERROR_CONSTANT): Adds a standard error without replace the wildcard
82
     * - _error(int ERROR_CONSTANT, string $message): Adds a standard error replacing the wildcard
83
     *
84
     * When the error is non-standard (i.e. is not a member of Errno class) the behavior is as follow:
85
     * - _error(int $code, string $message): Adds a non-standard error
86
     * - _error(string $message): Adds a non-standard error creating a generated base64 code
87
     *
88
     * @param integer $code
89
     * @param string  $message
90
     *
91
     * @return null
92
     */
93
    protected function _error($code, $message = null)
94
    {
95
        if (!is_null($code) && !is_integer($code))
0 ignored issues
show
introduced by
The condition is_null($code) is always false.
Loading history...
introduced by
The condition is_integer($code) is always true.
Loading history...
96
            throw new \InvalidArgumentException("Invalid type given. Integer expected");
97
98
        if (is_null($code))
0 ignored issues
show
introduced by
The condition is_null($code) is always false.
Loading history...
99
            $code = preg_replace('/=|\/|\+/', "", base64_encode($message));
100
        else
101
        {
102
            if (!array_key_exists($code, $this->standardErrors) && empty($message))
103
                /*
104
                 * "This kind of exception should lead directly to a fix in your code"
105
                 * Non-standard errors must have a message to describe the error, make sure
106
                 * you execute the error() method with a message as the second parameter.
107
                 *
108
                 * Ref: http://php.net/manual/en/class.logicexception.php
109
                 */
110
                throw new \LogicException('The message does not be empty in non-standard errors!');
111
        }
112
113
        if (!array_key_exists($code, $this->errors))
114
            $this->errors[$code] = (array_key_exists($code, $this->standardErrors))
115
                ?
116
                    is_null($message)
117
                        ? preg_replace('/\s\'%[a-zA-Z]*%\'/', $message, $this->standardErrors[$code])
118
                        # if $message is not null it will replace the %file% wildcard
119
                        : preg_replace('/%[a-zA-Z]*%/', $message, $this->standardErrors[$code])
120
                : $message;
121
    }
122
123
    function __call($method, $arguments)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
124
    {
125
        if ($method == 'error')
126
        {
127
            switch (count($arguments))
128
            {
129
                case 1:
130
                    if (is_integer($arguments[0]))
131
                        return call_user_func([$this, '_error'], array_shift($arguments));
132
                    else
133
                        return call_user_func([$this, '_error'], null, array_shift($arguments));
134
                    break;
135
                case 2:
136
                    return call_user_func([$this, '_error'], $arguments[0], $arguments[1]);
137
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
138
            }
139
        }
140
    }
141
}