Completed
Push — master ( 79d117...cc4d96 )
by Fabrizio
02:21
created

NotifynderBuilder::refresh()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 1 Features 0
Metric Value
c 1
b 1
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 0
1
<?php namespace Fenos\Notifynder\Builder;
2
3
use ArrayAccess;
4
use Carbon\Carbon;
5
use Fenos\Notifynder\Contracts\NotifynderCategory;
6
use Fenos\Notifynder\Exceptions\NotificationBuilderException;
7
use InvalidArgumentException;
8
use Traversable;
9
use Closure;
10
11
/**
12
 * Class NotifynderBuilder
13
 *
14
 * The builder is a main factor of Notifynder, it make sure
15
 * that the notification is decorated and validated before
16
 * are passed to the Sender Classes. It also helps you to
17
 * create multi notifications with the same simple and easy sintax.
18
 *
19
 * @package Fenos\Notifynder\Builder
20
 */
21
class NotifynderBuilder implements ArrayAccess
22
{
23
    use BuilderRules;
24
25
    /**
26
     * @var string notification to store
27
     */
28
    public $date;
29
30
    /**
31
     * Builder data
32
     *
33
     * @var array
34
     */
35
    protected $notifications = [];
36
37
    /**
38
     * @var NotifynderCategory
39
     */
40
    private $notifynderCategory;
41
42
    /**
43
     * @param NotifynderCategory $notifynderCategory
44
     */
45
    function __construct(NotifynderCategory $notifynderCategory)
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...
46
    {
47
        $this->notifynderCategory = $notifynderCategory;
48
    }
49
50
    /**
51
     * Set who will send the notification
52
     *
53
     * @return $this
54
     */
55
    public function from()
56
    {
57
        $from = func_get_args();
58
59
        $this->setEntityAction($from, 'from');
60
61
        return $this;
62
    }
63
64
    /**
65
     * Set who will receive the notification
66
     *
67
     * @return $this
68
     */
69
    public function to()
70
    {
71
        $from = func_get_args();
72
73
        $this->setEntityAction($from, 'to');
74
75
        return $this;
76
    }
77
78
    /**
79
     * Set the url of the notification
80
     *
81
     * @param $url
82
     * @return $this
83
     */
84
    public function url($url)
85
    {
86
        $this->isString($url);
87
88
        $this->setBuilderData('url', $url);
89
90
        return $this;
91
    }
92
93
    /**
94
     * Set expire time
95
     *
96
     * @param $datetime
97
     * @return $this
98
     */
99
    public function expire($datetime)
100
    {
101
        $this->isCarbon($datetime);
102
        $this->setBuilderData('expire_time', $datetime);
103
104
        return $this;
105
    }
106
107
    /**
108
     * Set Category and covert it, to the id
109
     * if name of it given
110
     *
111
     * @param $category
112
     * @return $this
113
     */
114
    public function category($category)
115
    {
116
        if (!is_numeric($category)) {
117
            $category = $this->notifynderCategory
118
                            ->findByName($category)->id;
119
        }
120
121
        $this->setBuilderData('category_id', $category);
122
123
        return $this;
124
    }
125
126
    /**
127
     * Set extra value
128
     *
129
     * @param $extra
130
     * @return $this
131
     */
132
    public function extra(array $extra = [])
133
    {
134
        $this->isReadyArrToFormatInJson($extra);
135
136
        $jsonExtraValues = json_encode($extra);
137
138
        $this->setBuilderData('extra', $jsonExtraValues);
139
140
        return $this;
141
    }
142
143
    /**
144
     * Build the array with the builder inside
145
     * a Closure, it has more flexibility for
146
     * the generation of your array
147
     *
148
     *
149
     * @param callable|Closure $closure
150
     * @return array|false
151
     * @throws NotificationBuilderException
152
     */
153
    public function raw(Closure $closure)
154
    {
155
        $builder = $closure($this);
156
157
        if (! is_null($builder)) {
158
            return $this->toArray();
159
        }
160
161
        return false;
162
    }
163
164
    /**
165
     * Loop the datas for create
166
     * multi notifications array
167
     *
168
     * @param          $dataToIterate
169
     * @param  Closure $builder
170
     * @return $this
171
     * @throws NotificationBuilderException
172
     */
173
    public function loop($dataToIterate, Closure $builder)
174
    {
175
        if ($this->isIterable($dataToIterate)) {
176
            $notifications = [];
177
178
            $newBuilder = new self($this->notifynderCategory);
179
180
            foreach ($dataToIterate as $key => $data) {
181
                $builder($newBuilder, $data, $key);
182
                $notifications[] = $newBuilder->toArray();
183
            }
184
185
            $this->notifications = $notifications;
186
            return $this;
187
        }
188
189
        $error = "The data passed must be itarable";
190
        throw new InvalidArgumentException($error);
191
    }
192
193
    /**
194
     * Compose the builder to
195
     * the array
196
     *
197
     * @throws NotificationBuilderException
198
     * @return mixed
199
     */
200
    public function toArray()
201
    {
202
        $hasMultipleNotifications = $this->isMultidimensionalArray($this->notifications);
203
204
        // If the builder is handling a single notification
205
        // we will validate only it
206
        if (! $hasMultipleNotifications) {
207
208
            $this->setDate();
209
210
            if ($this->hasRequiredFields($this->notifications)) {
211
                return $this->notifications;
212
            }
213
        }
214
215
        // If has multiple Notifications
216
        // we will validate one by one
217
        if ($hasMultipleNotifications) {
218
219
            $allow = [];
220
221
            foreach($this->notifications as $index => $notification) {
222
                $allow[$index] = $this->hasRequiredFields($notification);
223
            }
224
225
            if (! in_array(false,$allow)) {
226
                return $this->notifications;
227
            }
228
        }
229
230
        $error = "The fields:  'from_id' , 'to_id', 'url', 'category_id' are required";
231
        throw new NotificationBuilderException($error);
232
    }
233
234
    /**
235
     * Refresh the state of the notifications
236
     */
237
    public function refresh()
238
    {
239
        $this->notifications = [];
240
241
        return $this;
242
    }
243
244
    /**
245
     * @param $var
246
     * @return bool
247
     */
248
    protected function isIterable($var)
249
    {
250
        return (is_array($var) || $var instanceof Traversable);
251
    }
252
253
    /**
254
     * It set the entity who will do
255
     * the action of receive or
256
     * send
257
     *
258
     * @param $from
259
     * @param $property
260
     * @return array
261
     */
262
    protected function setEntityAction($from, $property)
263
    {
264
        // Check if has the entity as parameter
265
        // it should be the firstOne
266
        if ($this->hasEntity($from)) {
267
            $this->isString($from[0]);
268
            $this->isNumeric($from[1]);
269
270
            $this->setBuilderData("{$property}_type", $from[0]);
271
            $this->setBuilderData("{$property}_id", $from[1]);
272
        } else {
273
            $this->isNumeric($from[0]);
274
            $this->setBuilderData("{$property}_id", $from[0]);
275
        }
276
    }
277
278
    /**
279
     * If the values passed are 2 or more,
280
     * it means that you spefied the entity
281
     * over then the id
282
     *
283
     * @param  array $info
284
     * @return bool
285
     */
286
    protected function hasEntity(array $info)
287
    {
288
        return count($info) >= 2;
289
    }
290
291
    /**
292
     * Set date on the array
293
     */
294
    protected function setDate()
295
    {
296
        $this->date = $data = Carbon::now();
0 ignored issues
show
Documentation Bug introduced by
It seems like $data = \Carbon\Carbon::now() of type object<Carbon\Carbon> is incompatible with the declared type string of property $date.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
297
298
        $this->setBuilderData('updated_at', $data);
299
        $this->setBuilderData('created_at', $data);
300
    }
301
302
    /**
303
     * @return string
304
     */
305
    protected function getDate()
306
    {
307
        return $this->date;
308
    }
309
310
    /**
311
     * Set builder Data
312
     *
313
     * @param $field
314
     * @param $data
315
     */
316
    protected function setBuilderData($field, $data)
317
    {
318
        return $this->notifications[$field] = $data;
319
    }
320
321
322
    /**
323
     * @param mixed $offset
324
     * @return bool
325
     */
326
    public function offsetExists($offset)
327
    {
328
        return array_key_exists($offset,$this->notifications);
329
    }
330
331
332
    /**
333
     * @param mixed $offset
334
     * @return mixed
335
     */
336
    public function offsetGet($offset)
337
    {
338
        return $this->notifications[$offset];
339
    }
340
341
342
    /**
343
     * @param mixed $offset
344
     * @param mixed $value
345
     */
346
    public function offsetSet($offset, $value)
347
    {
348
        if (method_exists($this, $offset)) {
349
350
            return $this->{$offset}($value);
351
        }
352
353
        if ($this->isRequiredField($offset)) {
354
            $this->notifications[$offset] = $value;
355
        }
356
    }
357
358
    /**
359
     * @param mixed $offset
360
     * @return null
361
     */
362
    public function offsetUnset($offset)
363
    {
364
        unset($this->notifications[$offset]);
365
    }
366
}
367