/
Tags.php
146 lines (131 loc) · 3.86 KB
/
Tags.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
namespace Laravel\Horizon;
use stdClass;
use ReflectionClass;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Mail\SendQueuedMailable;
use Illuminate\Events\CallQueuedListener;
use Illuminate\Broadcasting\BroadcastEvent;
use Illuminate\Notifications\SendQueuedNotifications;
use Illuminate\Database\Eloquent\Collection as EloquentCollection;
class Tags
{
/**
* Determine the tags for the given job.
*
* @param mixed $job
* @return array
*/
public static function for($job)
{
if ($tags = static::extractExplicitTags($job)) {
return $tags;
}
return static::modelsFor(static::targetsFor($job))->map(function ($model) {
return get_class($model).':'.$model->getKey();
})->all();
}
/**
* Extract tags from job object.
*
* @param mixed $job
* @return array
*/
public static function extractExplicitTags($job)
{
return $job instanceof CallQueuedListener
? static::tagsForListener($job)
: static::explicitTags(static::targetsFor($job));
}
/**
* Determine tags for the given queued listener.
*
* @param mixed $job
* @return array
*/
protected static function tagsForListener($job)
{
return collect(
[static::extractListener($job), static::extractEvent($job),
])->map(function ($job) {
return static::for($job);
})->collapse()->unique()->toArray();
}
/**
* Determine tags for the given job.
*
* @param array $jobs
* @return mixed
*/
protected static function explicitTags(array $jobs)
{
return collect($jobs)->map(function ($job) {
return method_exists($job, 'tags') ? $job->tags() : [];
})->collapse()->unique()->all();
}
/**
* Get the actual target for the given job.
*
* @param mixed $job
* @return array
*/
public static function targetsFor($job)
{
switch (true) {
case $job instanceof BroadcastEvent:
return [$job->event];
case $job instanceof CallQueuedListener:
return [static::extractEvent($job)];
case $job instanceof SendQueuedMailable:
return [$job->mailable];
case $job instanceof SendQueuedNotifications:
return [$job->notification];
default:
return [$job];
}
}
/**
* Get the models from the given object.
*
* @param array $targets
* @return \Illuminate\Support\Collection
*/
public static function modelsFor(array $targets)
{
$models = [];
foreach ($targets as $target) {
$models[] = collect((new ReflectionClass($target))->getProperties())->map(function ($property) use ($target) {
$property->setAccessible(true);
$value = $property->getValue($target);
if ($value instanceof Model) {
return [$value];
} elseif ($value instanceof EloquentCollection) {
return $value->all();
}
})->collapse()->filter()->all();
}
return collect(array_collapse($models))->unique();
}
/**
* Extract the listener from a queued job.
*
* @param mixed $job
* @return mixed
*/
protected static function extractListener($job)
{
return (new ReflectionClass($job->class))->newInstanceWithoutConstructor();
}
/**
* Extract the event from a queued job.
*
* @param mixed $job
* @return mixed
*/
protected static function extractEvent($job)
{
return isset($job->data[0]) && is_object($job->data[0])
? $job->data[0]
: new stdClass;
}
}