Issues (43)

src/Traits/TransformMethodsTrait.php (8 issues)

1
<?php
2
3
namespace Nip\Collections\Traits;
4
5
use JsonSerializable;
6
use Nip\Collections\AbstractCollection;
7
use Nip\Collections\ArrayInterface;
8
use Nip\Utility\Arr;
9
10
/**
11
 * Class TransformMethodsTrait
12
 * @package Nip\Collections\Traits
13
 */
14
trait TransformMethodsTrait
15
{
16
    protected $serializable = ['items'];
17
18
    /**
19
     * Get the values of a given key.
20
     *
21
     * @param string|array|int|null $value
22
     * @param string|null $key
23
     * @return static
24
     */
25
    public function pluck($value, $key = null)
26
    {
27
        return new static(Arr::pluck($this->items, $value, $key));
0 ignored issues
show
The call to Nip\Collections\Traits\T...odsTrait::__construct() has too many arguments starting with Nip\Utility\Arr::pluck($...s->items, $value, $key). ( Ignorable by Annotation )

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

27
        return /** @scrutinizer ignore-call */ new static(Arr::pluck($this->items, $value, $key));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
28
    }
29
30
    /**
31
     * Run a map over each of the items.
32
     *
33
     * @param callable $callback
34
     * @return static
35
     */
36
    public function map(callable $callback)
37
    {
38
        $keys = array_keys($this->items);
39
40
        $items = array_map($callback, $this->items, $keys);
41
42
        return new static(array_combine($keys, $items));
0 ignored issues
show
The call to Nip\Collections\Traits\T...odsTrait::__construct() has too many arguments starting with array_combine($keys, $items). ( Ignorable by Annotation )

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

42
        return /** @scrutinizer ignore-call */ new static(array_combine($keys, $items));

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
43
    }
44
45
    /**
46
     * Run a dictionary map over the items.
47
     *
48
     * The callback should return an associative array with a single key/value pair.
49
     *
50
     * @param callable $callback
51
     * @return static
52
     */
53
    public function mapToDictionary(callable $callback)
54
    {
55
        $dictionary = [];
56
57
        foreach ($this->items as $key => $item) {
58
            $pair = $callback($item, $key);
59
60
            $key = key($pair);
61
62
            $value = reset($pair);
63
64
            if (!isset($dictionary[$key])) {
65
                $dictionary[$key] = [];
66
            }
67
68
            $dictionary[$key][] = $value;
69
        }
70
71
        return new static($dictionary);
0 ignored issues
show
The call to Nip\Collections\Traits\T...odsTrait::__construct() has too many arguments starting with $dictionary. ( Ignorable by Annotation )

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

71
        return /** @scrutinizer ignore-call */ new static($dictionary);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
72
    }
73
74
    /**
75
     * Run an associative map over each of the items.
76
     *
77
     * The callback should return an associative array with a single key/value pair.
78
     *
79
     * @param  callable  $callback
80
     * @return static
81
     */
82
    public function mapWithKeys(callable $callback)
83
    {
84
        $result = [];
85
86
        foreach ($this->items as $key => $value) {
87
            $assoc = $callback($value, $key);
88
89
            foreach ($assoc as $mapKey => $mapValue) {
90
                $result[$mapKey] = $mapValue;
91
            }
92
        }
93
94
        return new static($result);
0 ignored issues
show
The call to Nip\Collections\Traits\T...odsTrait::__construct() has too many arguments starting with $result. ( Ignorable by Annotation )

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

94
        return /** @scrutinizer ignore-call */ new static($result);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
95
    }
96
97
    /**
98
     * Concatenate values of a given key as a string.
99
     *
100
     * @param string $value
101
     * @param string|null $glue
102
     * @return string
103
     */
104
    public function implode($value, $glue = null)
105
    {
106
        $first = $this->first();
0 ignored issues
show
It seems like first() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

106
        /** @scrutinizer ignore-call */ 
107
        $first = $this->first();
Loading history...
107
108
        if (is_array($first) || is_object($first)) {
109
            return implode($glue, $this->pluck($value)->all());
0 ignored issues
show
It seems like all() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

109
            return implode($glue, $this->pluck($value)->/** @scrutinizer ignore-call */ all());
Loading history...
It seems like $glue can also be of type null; however, parameter $glue of implode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

109
            return implode(/** @scrutinizer ignore-type */ $glue, $this->pluck($value)->all());
Loading history...
110
        }
111
112
        return implode($value, $this->items);
113
    }
114
115
    /**
116
     * Transform each item in the collection using a callback.
117
     *
118
     * @param callable $callback
119
     * @return $this
120
     */
121
    public function transform(callable $callback)
122
    {
123
        $this->items = $this->map($callback)->all();
0 ignored issues
show
Bug Best Practice introduced by
The property items does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
124
125
        return $this;
126
    }
127
128
    /**
129
     * Reduce the collection to a single value.
130
     *
131
     * @param  callable  $callback
132
     * @param  mixed $initial
133
     * @return mixed
134
     */
135
    public function reduce(callable $callback, $initial = null)
136
    {
137
        $result = $initial;
138
139
        foreach ($this as $key => $value) {
140
            $result = $callback($result, $value, $key);
141
        }
142
143
        return $result;
144
    }
145
146
    /**
147
     * @return array
148
     */
149
    public function toArray(): array
150
    {
151
        return array_map(function ($value) {
152
            return $value instanceof ArrayInterface ? $value->toArray() : $value;
153
        }, $this->items);
154
    }
155
156
    /**
157
     * Returns a serialized string representation of this array object.
158
     *
159
     * @link http://php.net/manual/en/serializable.serialize.php Serializable::serialize()
160
     *
161
     * @return string a PHP serialized string.
162
     */
163
    public function serialize(): string
164
    {
165
        $properties = $this->__sleep();
166
        $data = [];
167
        foreach ($properties as $property) {
168
            $data[$property] = $this->{$property};
169
        }
170
        return serialize($data);
171
    }
172
173
    /**
174
     * @return array
175
     */
176
    public function __sleep()
177
    {
178
        return $this->serializable;
179
    }
180
181
    /**
182
     * Converts a serialized string representation into an instance object.
183
     *
184
     * @link http://php.net/manual/en/serializable.unserialize.php Serializable::unserialize()
185
     *
186
     * @param string $serialized A PHP serialized string to unserialize.
187
     *
188
     * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
189
     */
190
    public function unserialize($serialized): void
191
    {
192
        /** @var array<array-key, T> $data */
193
        $data = unserialize($serialized, ['allowed_classes' => $this->unserializeAllowedClasses()]);
194
        if (!is_array($data)) {
195
            return;
196
        }
197
        foreach ($data as $property => $value) {
198
            $this->{$property} = $value;
199
        }
200
    }
201
202
    /**
203
     * Specify data which should be serialized to JSON
204
     * @link http://php.net/manual/en/jsonserializable.jsonserialize.php
205
     * @return mixed data which can be serialized by <b>json_encode</b>,
206
     * which is a value of any type other than a resource.
207
     * @since 5.4.0
208
     */
209
    public function jsonSerialize()
210
    {
211
        return array_map(function ($value) {
212
            if ($value instanceof JsonSerializable) {
213
                return $value->jsonSerialize();
214
            } else {
215
                return $value;
216
            }
217
        }, $this->items);
218
    }
219
220
    protected function unserializeAllowedClasses()
221
    {
222
        return false;
223
    }
224
}
225