Completed
Pull Request — master (#106)
by Fabrizio
04:32 queued 02:13
created

NotifynderBuilder::setConfig()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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