Completed
Push — master ( 60eb47...8a4d2e )
by Fabrizio
9s
created

ExtraParams::jsonSerialize()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
3
namespace Fenos\Notifynder\Notifications;
4
5
use ArrayAccess;
6
use JsonSerializable;
7
use Illuminate\Contracts\Support\Arrayable;
8
use Illuminate\Contracts\Support\Jsonable;
9
use stdClass;
10
11
/**
12
 * Class Jsonable.
13
 */
14
class ExtraParams implements ArrayAccess, Arrayable, Jsonable, JsonSerializable
15
{
16
    /**
17
     * @var array|stdClass|string
18
     */
19
    protected $extraParams;
20
21
    /**
22
     * Jsonable constructor.
23
     *
24
     * @param $extraParams
25
     */
26
    public function __construct($extraParams)
27
    {
28
        if ($this->isJson($extraParams)) {
29
            $this->extraParams = json_decode($extraParams, true);
30
        } else {
31
            $this->extraParams = (array) $extraParams;
32
        }
33
    }
34
35
    /**
36
     * Convert the model instance to JSON.
37
     *
38
     * @param  int  $options
39
     * @return string
40
     */
41
    public function toJson($options = 0)
42
    {
43
        return json_encode($this->jsonSerialize(), $options);
44
    }
45
46
    /**
47
     * Convert the object into something JSON serializable.
48
     *
49
     * @return array
50
     */
51
    public function jsonSerialize()
52
    {
53
        return $this->toArray();
54
    }
55
56
    /**
57
     * @return array
58
     */
59
    public function toArray()
60
    {
61
        // Already possible json
62
        if ($this->isJson($this->extraParams)) {
63
            return json_decode($this->extraParams, true);
64
        }
65
66
        return $this->extraParams;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->extraParams; (array|stdClass|string) is incompatible with the return type declared by the interface Illuminate\Contracts\Support\Arrayable::toArray of type array.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
67
    }
68
69
    /**
70
     * The __toString method allows a class to decide how it will react when it is converted to a string.
71
     *
72
     * @return string
73
     */
74
    public function __toString()
75
    {
76
        $extraParams = $this->extraParams;
77
78
        if (is_array($extraParams) || $extraParams instanceof stdClass) {
79
            return $this->toJson();
80
        }
81
82
        return $extraParams;
83
    }
84
85
    /**
86
     * Check if the extra param
87
     * exists.
88
     *
89
     * @param $name
90
     * @return bool
91
     */
92
    public function has($name)
93
    {
94
        $arr = $this->extraParams;
95
96
        return isset($arr[$name]);
97
    }
98
99
    /**
100
     * is utilized for reading data from inaccessible members.
101
     *
102
     * @param $name string
103
     * @return mixed
104
     */
105
    public function __get($name)
106
    {
107
        $params = $this->toArray();
108
109
        if (array_key_exists($name, $params)) {
110
            return $params[$name];
111
        }
112
    }
113
114
    /**
115
     * Whether a offset exists.
116
     *
117
     * @param mixed $offset
118
     * @return bool
119
     */
120
    public function offsetExists($offset)
121
    {
122
        return $this->has($offset);
123
    }
124
125
    /**
126
     * @param mixed $offset
127
     * @return mixed Can return all value types.
128
     */
129
    public function offsetGet($offset)
130
    {
131
        return $this->extraParams[$offset];
132
    }
133
134
    /**
135
     * @param mixed $offset
136
     * @param mixed $value
137
     */
138
    public function offsetSet($offset, $value)
139
    {
140
        $this->extraParams[$offset] = $value;
141
    }
142
143
    /**
144
     * @param mixed $offset
145
     */
146
    public function offsetUnset($offset)
147
    {
148
        unset($this->extraParams[$offset]);
149
    }
150
151
    /**
152
     * Check if the value
153
     * is a json string.
154
     *
155
     * @param $value
156
     * @return bool
157
     */
158 View Code Duplication
    public function isJson($value)
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...
159
    {
160
        if (! is_string($value)) {
161
            return false;
162
        }
163
164
        json_decode($value);
165
166
        return json_last_error() == JSON_ERROR_NONE;
167
    }
168
}
169