Completed
Push — master ( 5099d4...7e4e3e )
by
unknown
03:07
created

NotifynderManager::dispatchWith()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 6
rs 9.4285
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
namespace Fenos\Notifynder;
4
5
use BadMethodCallException;
6
use Closure;
7
use Fenos\Notifynder\Builder\NotifynderBuilder;
8
use Fenos\Notifynder\Contracts\NotifynderCategory;
9
use Fenos\Notifynder\Contracts\NotifynderDispatcher;
10
use Fenos\Notifynder\Contracts\NotifynderGroup;
11
use Fenos\Notifynder\Contracts\NotifynderNotification;
12
use Fenos\Notifynder\Contracts\NotifynderSender;
13
use InvalidArgumentException;
14
15
/**
16
 * Class Notifynder.
17
 *
18
 * Notifynder is a Facade Class that has
19
 * all the methods necessary to use the library.
20
 *
21
 * Notifynder allow you to have a flexible notification
22
 * management. It will provide you a nice and easy API
23
 * to store, retrieve and organise your notifications.
24
 */
25
class NotifynderManager extends NotifynderBuilder implements Notifynder
26
{
27
    /**
28
     * Version Notifynder.
29
     *
30
     * @var string
31
     */
32
    const VERSION = '3.1.0';
33
34
    /**
35
     * @var NotifynderCategory
36
     */
37
    protected $notifynderCategory;
38
39
    /**
40
     * @var array
41
     */
42
    protected $categoriesContainer = [];
43
44
    /**
45
     * @var Models\NotificationCategory|null
46
     */
47
    protected $defaultCategory;
48
49
    /**
50
     * @var NotifynderSender
51
     */
52
    protected $notifynderSender;
53
54
    /**
55
     * @var NotifynderNotification
56
     */
57
    protected $notification;
58
59
    /**
60
     * @var NotifynderDispatcher
61
     */
62
    protected $notifynderDispatcher;
63
64
    /**
65
     * This sender method
66
     * will be used on the dispatcher.
67
     *
68
     * @var string
69
     */
70
    protected $eventSender = 'send';
71
72
    /**
73
     * @var NotifynderGroup
74
     */
75
    protected $notifynderGroup;
76
77
    /**
78
     * @var string | null
79
     */
80
    protected $entity;
81
82
    /**
83
     * @param NotifynderCategory     $notifynderCategory
84
     * @param NotifynderSender       $notifynderSender
85
     * @param NotifynderNotification $notification
86
     * @param NotifynderDispatcher   $notifynderDispatcher
87
     * @param NotifynderGroup        $notifynderGroup
88
     */
89
    public function __construct(NotifynderCategory $notifynderCategory,
90
                         NotifynderSender $notifynderSender,
91
                         NotifynderNotification $notification,
92
                         NotifynderDispatcher $notifynderDispatcher,
93
                         NotifynderGroup $notifynderGroup)
94
    {
95
        $this->notifynderCategory = $notifynderCategory;
96
        $this->notifynderSender = $notifynderSender;
97
        $this->notification = $notification;
98
        $this->notifynderDispatcher = $notifynderDispatcher;
99
        $this->notifynderGroup = $notifynderGroup;
100
101
        parent::__construct($notifynderCategory);
102
    }
103
104
    /**
105
     * Set the category of the
106
     * notification.
107
     *
108
     * @param $name
109
     * @return $this
110
     */
111
    public function category($name)
112
    {
113
        // Check if the category is lazy loaded
114
        if ($this->isLazyLoaded($name)) {
115
            // Yes it is, split out the value from the array
116
            $this->defaultCategory = $this->getCategoriesContainer($name);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getCategoriesContainer($name) of type array is incompatible with the declared type object<Fenos\Notifynder\...ificationCategory>|null of property $defaultCategory.

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...
117
118
            // set category on the builder
119
            parent::category($this->defaultCategory->id);
120
121
            return $this;
122
        }
123
124
        // Otherwise ask to the db and give me the right category
125
        // associated with this name. If the category is not found
126
        // it throw CategoryNotFoundException
127
        $category = $this->notifynderCategory->findByName($name);
128
129
        $this->defaultCategory = $category;
130
131
        // Set the category on the array
132
        $this->setCategoriesContainer($name, $category);
133
134
        // set category on the builder
135
        parent::category($category->id);
136
137
        return $this;
138
    }
139
140
    /**
141
     * Define an entity when Notifynder is
142
     * used Polymorphically.
143
     *
144
     * @param $name
145
     * @return $this
146
     */
147
    public function entity($name)
148
    {
149
        $this->entity = $name;
150
151
        return $this;
152
    }
153
154
    /**
155
     * Add a category.
156
     *
157
     * @param $name
158
     * @param $text
159
     * @return static
160
     */
161
    public function addCategory($name, $text)
162
    {
163
        return $this->notifynderCategory->add($name, $text);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->notifynder...ory->add($name, $text); (Fenos\Notifynder\Models\NotificationCategory) is incompatible with the return type declared by the interface Fenos\Notifynder\Notifynder::addCategory of type Fenos\Notifynder\Notifynder.

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...
164
    }
165
166
    /**
167
     * Update a category.
168
     *
169
     * @param  array $updates
170
     * @param        $categoryId
171
     * @return mixed
172
     */
173
    public function updateCategory(array $updates, $categoryId)
174
    {
175
        return $this->notifynderCategory->update($updates, $categoryId);
176
    }
177
178
    /**
179
     * Send notifications
180
     * Both multiple and single.
181
     *
182
     * @param  array $info
183
     * @return mixed
184
     */
185 View Code Duplication
    public function send($info = [])
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...
186
    {
187
        $info = (count($info) > 0) ? $info : $this->toArray();
188
189
        $notificationSent = $this->notifynderSender->send($info, $this->defaultCategory);
0 ignored issues
show
Bug introduced by
It seems like $this->defaultCategory can also be of type object<Fenos\Notifynder\...s\NotificationCategory>; however, Fenos\Notifynder\Contrac...otifynderSender::send() does only seem to accept null, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
190
191
        $this->refresh();
192
193
        return $notificationSent;
194
    }
195
196
    /**
197
     * Send immediately the notification
198
     * even if the queue is enabled.
199
     *
200
     * @param  array $info
201
     * @return mixed
202
     */
203 View Code Duplication
    public function sendNow($info = [])
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...
204
    {
205
        $info = (count($info) > 0) ? $info : $this->toArray();
206
207
        $notificationsSent = $this->notifynderSender->sendNow($info, $this->defaultCategory);
208
209
        $this->refresh();
210
211
        return $notificationsSent;
212
    }
213
214
    /**
215
     * Send One notification.
216
     *
217
     * @param  array $info
218
     * @return mixed
219
     */
220 View Code Duplication
    public function sendOne($info = [])
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...
221
    {
222
        $info = (count($info) > 0) ? $info : $this->toArray();
223
224
        $notificationSent = $this->notifynderSender->sendOne($info, $this->defaultCategory);
225
226
        $this->refresh();
227
228
        return $notificationSent;
229
    }
230
231
    /**
232
     * Send multiple notifications.
233
     *
234
     * @param  array                $info
235
     * @return Senders\SendMultiple
236
     */
237 View Code Duplication
    public function sendMultiple($info = [])
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...
238
    {
239
        $info = (count($info) > 0) ? $info : $this->toArray();
240
241
        $notificationsSent = $this->notifynderSender->sendMultiple($info, $this->defaultCategory);
0 ignored issues
show
Unused Code introduced by
The call to NotifynderSender::sendMultiple() has too many arguments starting with $this->defaultCategory.

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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
242
243
        $this->refresh();
244
245
        return $notificationsSent;
246
    }
247
248
    /**
249
     * Send a group of notifications.
250
     *
251
     * @param $groupName
252
     * @param $info
253
     * @return mixed
254
     */
255
    public function sendGroup($groupName, $info = [])
256
    {
257
        $info = (count($info) > 0) ? $info : $this->toArray();
258
259
        $notificationsSent = $this->notifynderSender->sendGroup($this, $groupName, $info);
0 ignored issues
show
Unused Code introduced by
The call to NotifynderSender::sendGroup() has too many arguments starting with $info.

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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
260
261
        $this->refresh();
262
263
        return $notificationsSent;
264
    }
265
266
    /**
267
     * Read one notification.
268
     *
269
     * @param $notificationId
270
     * @return bool|Models\Notification
271
     */
272
    public function readOne($notificationId)
273
    {
274
        return $this->notification->readOne($notificationId);
275
    }
276
277
    /**
278
     * Read notification in base the number
279
     * Given.
280
     *
281
     * @param         $toId
282
     * @param         $numbers
283
     * @param  string $order
284
     * @return mixed
285
     */
286
    public function readLimit($toId, $numbers, $order = 'ASC')
287
    {
288
        $notification = $this->notification->entity($this->entity);
289
290
        return $notification->readLimit($toId, $numbers, $order);
291
    }
292
293
    /**
294
     * Read all notifications of the given
295
     * entity.
296
     *
297
     * @param $toId
298
     * @return Number
299
     */
300
    public function readAll($toId)
301
    {
302
        $notifications = $this->notification->entity($this->entity);
303
304
        return $notifications->readAll($toId);
305
    }
306
307
    /**
308
     * Delete a single notification.
309
     *
310
     * @param $notificationId
311
     * @return bool
312
     */
313
    public function delete($notificationId)
314
    {
315
        return $this->notification->delete($notificationId);
316
    }
317
318
    /**
319
     * Delete number of notifications
320
     * specified of the given entity.
321
     *
322
     * @param         $toId
323
     * @param         $number
324
     * @param  string $order
325
     * @return mixed
326
     */
327
    public function deleteLimit($toId, $number, $order = 'ASC')
328
    {
329
        $notifications = $this->notification->entity($this->entity);
330
331
        return $notifications->deleteLimit($toId, $number, $order);
332
    }
333
334
    /**
335
     * Delete all notifications
336
     * of the the given entity.
337
     *
338
     * @param $toId
339
     * @return bool
340
     */
341
    public function deleteAll($toId)
342
    {
343
        $notifications = $this->notification->entity($this->entity);
344
345
        return $notifications->deleteAll($toId);
346
    }
347
348
    /**
349
     * Delete All notifications from a
350
     * defined category.
351
     *
352
     * @param $categoryName string
353
     * @param $expired Bool
354
     * @return bool
355
     */
356
    public function deleteByCategory($categoryName, $expired = false)
357
    {
358
        return $this->notification->deleteByCategory($categoryName, $expired);
359
    }
360
361
    /**
362
     * Get Notifications not read
363
     * of the given entity.
364
     *
365
     * @param           $toId
366
     * @param  null     $limit
367
     * @param  null|int $paginate
368
     * @param  string   $order
369
     * @param Closure   $filterScope
370
     * @return mixed
371
     */
372
    public function getNotRead($toId, $limit = null, $paginate = null, $order = 'desc', Closure $filterScope = null)
373
    {
374
        $notifications = $this->notification->entity($this->entity);
375
376
        return $notifications->getNotRead($toId, $limit, $paginate, $order, $filterScope);
377
    }
378
379
    /**
380
     * Get all notifications of the
381
     * given entity.
382
     *
383
     * @param           $toId
384
     * @param  null     $limit
385
     * @param  int|null $paginate
386
     * @param  string   $order
387
     * @param Closure   $filterScope
388
     * @return mixed
389
     */
390
    public function getAll($toId, $limit = null, $paginate = null, $order = 'desc', Closure $filterScope = null)
391
    {
392
        $notifications = $this->notification->entity($this->entity);
393
394
        return $notifications->getAll($toId, $limit, $paginate, $order, $filterScope);
395
    }
396
397
    /**
398
     * Get number of notification not read
399
     * of the given entity.
400
     *
401
     * @param         $toId
402
     * @param Closure $filterScope
403
     * @return mixed
404
     */
405
    public function countNotRead($toId, Closure $filterScope = null)
406
    {
407
        $notifications = $this->notification->entity($this->entity);
408
409
        return $notifications->countNotRead($toId, $filterScope);
410
    }
411
412
    /**
413
     * Find Notification by ID.
414
     *
415
     * @param $notificationId
416
     * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Model|static
417
     */
418
    public function findNotificationById($notificationId)
419
    {
420
        return $this->notification->find($notificationId);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->notification->find($notificationId); of type Illuminate\Database\Eloq...\NotifynderNotification adds the type Fenos\Notifynder\Contracts\NotifynderNotification to the return on line 420 which is incompatible with the return type declared by the interface Fenos\Notifynder\Notifynder::findNotificationById of type Illuminate\Database\Eloq...s\Notifynder\Notifynder.
Loading history...
421
    }
422
423
    /**
424
     * Get last notification of the given
425
     * entity, second parameter can filter by
426
     * category.
427
     *
428
     * @param         $toId
429
     * @param null    $category
430
     * @param Closure $filterScope
431
     * @return mixed
432
     */
433
    public function getLastNotification($toId, $category = null, Closure $filterScope = null)
434
    {
435
        $notification = $this->notification->entity($this->entity);
436
437
        if (is_null($category)) {
438
            return $notification->getLastNotification($toId, $filterScope);
439
        }
440
441
        return $notification->getLastNotificationByCategory($category, $toId, $filterScope);
442
    }
443
444
    /**
445
     * Add category to a group
446
     * giving the names of them.
447
     *
448
     * @param $groupName
449
     * @param $categoryName
450
     * @return mixed
451
     */
452
    public function addCategoryToGroupByName($groupName, $categoryName)
453
    {
454
        return $this->notifynderGroup->addCategoryToGroupByName($groupName, $categoryName);
455
    }
456
457
    /**
458
     * Add category to a group
459
     * giving the ids of them.
460
     *
461
     * @param $groupId
462
     * @param $categoryId
463
     * @return mixed
464
     */
465
    public function addCategoryToGroupById($groupId, $categoryId)
466
    {
467
        return $this->notifynderGroup->addCategoryToGroupById($groupId, $categoryId);
468
    }
469
470
    /**
471
     * Add categories to a group having as first parameter
472
     * the name of the group, and others as name
473
     * categories.
474
     *
475
     * @return mixed
476
     */
477
    public function addCategoriesToGroup()
478
    {
479
        return $this->notifynderGroup->addMultipleCategoriesToGroup(func_get_args());
0 ignored issues
show
Unused Code introduced by
The call to NotifynderGroup::addMultipleCategoriesToGroup() has too many arguments starting with func_get_args().

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.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
480
    }
481
482
    /**
483
     * Fire method for fire listeners
484
     * of logic.
485
     *
486
     * @param  string     $key
487
     * @param  string     $categoryName
488
     * @param  mixed|null $values
489
     * @return mixed|null
490
     */
491
    public function fire($key, $categoryName, $values = [])
492
    {
493
        return $this->notifynderDispatcher->sendWith($this->eventSender)
494
                    ->fire($this, $key, $categoryName, $values);
495
    }
496
497
    /**
498
     * Associate events to categories.
499
     *
500
     * @param        $data
501
     * @param  array $delegation
502
     * @return mixed
503
     */
504
    public function delegate(array $delegation, $data = [])
505
    {
506
        return $this->notifynderDispatcher->delegate($this, $data, $delegation);
507
    }
508
509
    /**
510
     * Boot Listeners.
511
     *
512
     * @param array $listeners
513
     */
514
    public function bootListeners(array $listeners)
515
    {
516
        $this->notifynderDispatcher->boot($listeners);
517
    }
518
519
    /**
520
     * Get instance of the notifynder builder.
521
     *
522
     * @return NotifynderBuilder
523
     */
524
    public function builder()
525
    {
526
        return new parent($this->notifynderCategory);
527
    }
528
529
    /**
530
     * Extend a custom sender method.
531
     *
532
     * @param           $name
533
     * @param  callable $registrar
534
     * @return $this
535
     */
536
    public function extend($name, $registrar)
537
    {
538
        if (! starts_with($name, 'send')) {
539
            $error = 'The sender method must start with [send]';
540
            throw new InvalidArgumentException($error);
541
        }
542
543
        $this->notifynderSender->extend($name, $registrar);
544
545
        return $this;
546
    }
547
548
    /**
549
     * Check if the category is eager Loaded.
550
     *
551
     * @param $name
552
     * @return bool
553
     */
554
    protected function isLazyLoaded($name)
555
    {
556
        return array_key_exists($name, $this->categoriesContainer);
557
    }
558
559
    /**
560
     * Return the Id of the category.
561
     *
562
     * @return mixed
563
     */
564
    public function id()
565
    {
566
        return $this->defaultCategory->id;
567
    }
568
569
    /**
570
     * Push a category in the categoriesContainer
571
     * property.
572
     *
573
     * @param       $name
574
     * @param array $categoriesContainer
575
     */
576
    protected function setCategoriesContainer($name, $categoriesContainer)
577
    {
578
        $this->categoriesContainer[$name] = $categoriesContainer;
579
    }
580
581
    /**
582
     * Get the categoriesContainer property.
583
     *
584
     * @param $name
585
     * @return array
586
     */
587
    public function getCategoriesContainer($name)
588
    {
589
        return $this->categoriesContainer[$name];
590
    }
591
592
    /**
593
     * Define which method
594
     * the event dispatcher has
595
     * to send the notifications.
596
     *
597
     * @param $customSenderName
598
     * @return $this
599
     */
600
    public function dispatchWith($customSenderName)
601
    {
602
        $this->eventSender = $customSenderName;
603
604
        return $this;
605
    }
606
607
    /**
608
     * Call the custom sender method.
609
     *
610
     * @param $name
611
     * @param $arguments
612
     * @return void|mixed
613
     */
614
    public function __call($name, $arguments)
615
    {
616
        if (starts_with($name, 'send')) {
617
            $arguments = (isset($arguments[0])) ? $arguments[0] : $this->toArray();
618
619
            $notificationsSent = $this->notifynderSender->customSender($name, $arguments);
620
            $this->refresh();
621
622
            return $notificationsSent;
623
        }
624
625
        $error = "method [$name] not found in the class ".self::class;
626
        throw new BadMethodCallException($error);
627
    }
628
629
    /**
630
     * Set builder properties
631
     * When setting dynamic properties.
632
     *
633
     * @param $name
634
     * @param $value
635
     */
636
    public function __set($name, $value)
637
    {
638
        $this->offsetSet($name, $value);
639
    }
640
641
    /**
642
     * Get property from the
643
     * builder.
644
     *
645
     * @param $name
646
     * @return mixed
647
     */
648
    public function __get($name)
649
    {
650
        return $this->offsetGet($name);
651
    }
652
}
653