1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
/** |
6
|
|
|
* Balloon |
7
|
|
|
* |
8
|
|
|
* @author Raffael Sahli <[email protected]> |
9
|
|
|
* @copyright Copryright (c) 2012-2017 gyselroth GmbH (https://gyselroth.com) |
10
|
|
|
* @license GPL-3.0 https://opensource.org/licenses/GPL-3.0 |
11
|
|
|
*/ |
12
|
|
|
|
13
|
|
|
namespace Balloon\App\Notification\Hook; |
14
|
|
|
|
15
|
|
|
use Balloon\App\Notification\Exception; |
16
|
|
|
use Balloon\App\Notification\Notifier; |
17
|
|
|
use Balloon\Filesystem\Node\Collection; |
18
|
|
|
use Balloon\Filesystem\Node\File; |
19
|
|
|
use Balloon\Hook\AbstractHook; |
20
|
|
|
use Balloon\Server; |
21
|
|
|
use Balloon\Server\User; |
22
|
|
|
use Psr\Log\LoggerInterface; |
23
|
|
|
|
24
|
|
|
class Subscription extends AbstractHook |
25
|
|
|
{ |
26
|
|
|
/** |
27
|
|
|
* Body. |
28
|
|
|
* |
29
|
|
|
* @var string |
30
|
|
|
*/ |
31
|
|
|
protected $body = "Hi {user.name} \n\r There have been made changes in your balloon directory."; |
32
|
|
|
|
33
|
|
|
/** |
34
|
|
|
* Subject. |
35
|
|
|
* |
36
|
|
|
* @var string |
37
|
|
|
*/ |
38
|
|
|
protected $subject = 'change'; |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Notification throttle. |
42
|
|
|
* |
43
|
|
|
* @var int |
44
|
|
|
*/ |
45
|
|
|
protected $notification_throttle = 3600; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Notifier. |
49
|
|
|
* |
50
|
|
|
* @var Notifier |
51
|
|
|
*/ |
52
|
|
|
protected $notifier; |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Server. |
56
|
|
|
* |
57
|
|
|
* @var Server |
58
|
|
|
*/ |
59
|
|
|
protected $server; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Logger. |
63
|
|
|
* |
64
|
|
|
* @var LoggerInterface |
65
|
|
|
*/ |
66
|
|
|
protected $logger; |
67
|
|
|
|
68
|
|
|
/** |
69
|
|
|
* User. |
70
|
|
|
* |
71
|
|
|
* @var User |
72
|
|
|
*/ |
73
|
|
|
protected $user; |
74
|
|
|
|
75
|
|
|
/** |
76
|
|
|
* Constructor. |
77
|
|
|
* |
78
|
|
|
* @param Notification $notifier |
79
|
|
|
* @param Server $server |
80
|
|
|
*/ |
81
|
|
|
public function __construct(Notifier $notifier, Server $server, LoggerInterface $logger, ?Iterable $config = null) |
82
|
|
|
{ |
83
|
|
|
$this->notifier = $notifier; |
84
|
|
|
$this->server = $server; |
85
|
|
|
$this->user = $server->getIdentity(); |
86
|
|
|
$this->setOptions($config); |
87
|
|
|
$this->logger = $logger; |
88
|
|
|
} |
89
|
|
|
|
90
|
|
|
/** |
91
|
|
|
* Set config. |
92
|
|
|
* |
93
|
|
|
* @param iterable $config |
94
|
|
|
* |
95
|
|
|
* @return AbstractHook |
96
|
|
|
*/ |
97
|
|
|
public function setOptions(?Iterable $config = null): self |
98
|
|
|
{ |
99
|
|
|
if (null === $config) { |
100
|
|
|
return $this; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
foreach ($config as $option => $value) { |
104
|
|
|
switch ($option) { |
105
|
|
|
case 'body': |
|
|
|
|
106
|
|
|
case 'subject': |
107
|
|
|
$this->{$option} = (string) $value; |
108
|
|
|
|
109
|
|
|
break; |
110
|
|
|
default: |
111
|
|
|
throw new Exception('invalid option '.$option.' given'); |
112
|
|
|
} |
113
|
|
|
} |
114
|
|
|
|
115
|
|
|
return $this; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* {@inheritdoc} |
120
|
|
|
*/ |
121
|
|
|
public function postCreateCollection(Collection $parent, Collection $node, bool $clone): void |
122
|
|
|
{ |
123
|
|
|
$this->notify($parent); |
124
|
|
|
} |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* {@inheritdoc} |
128
|
|
|
*/ |
129
|
|
|
public function postCreateFile(Collection $parent, File $node, bool $clone): void |
130
|
|
|
{ |
131
|
|
|
$this->notify($parent); |
132
|
|
|
} |
133
|
|
|
|
134
|
|
|
/** |
135
|
|
|
* {@inheritdoc} |
136
|
|
|
*/ |
137
|
|
|
public function postDeleteCollection(Collection $node, bool $force, ?string $recursion, bool $recursion_first): void |
138
|
|
|
{ |
139
|
|
|
$this->notify($node->getParent()); |
|
|
|
|
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* {@inheritdoc} |
144
|
|
|
*/ |
145
|
|
|
public function postRestoreFile(File $node, int $version): void |
146
|
|
|
{ |
147
|
|
|
$this->notify($node->getParent()); |
|
|
|
|
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* {@inheritdoc} |
152
|
|
|
*/ |
153
|
|
|
public function postDeleteFile(File $node, bool $force, ?string $recursion, bool $recursion_first): void |
154
|
|
|
{ |
155
|
|
|
$this->notify($node->getParent()); |
|
|
|
|
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* {@inheritdoc} |
160
|
|
|
*/ |
161
|
|
|
public function postPutFile(File $node, $content, bool $force, array $attributes): void |
162
|
|
|
{ |
163
|
|
|
$this->notify($node->getParent()); |
|
|
|
|
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* Check if we need to notify. |
168
|
|
|
* |
169
|
|
|
* @param Collection $collection |
170
|
|
|
*/ |
171
|
|
|
protected function notify(Collection $collection): void |
172
|
|
|
{ |
173
|
|
|
$subs = $collection->getAppAttribute('Balloon\\App\\Notification', 'subscription'); |
174
|
|
|
if (isset($subs[(string) $this->user->getId()])) { |
175
|
|
|
$this->logger->info('user ['.$this->user->getId().'] got a subscription for node ['.$collection->getId().']', [ |
176
|
|
|
'category' => get_class($this), |
177
|
|
|
]); |
178
|
|
|
} else { |
179
|
|
|
$this->logger->info('user ['.$this->user->getId().'] has no subscription for node ['.$collection->getId().']', [ |
180
|
|
|
'category' => get_class($this), |
181
|
|
|
]); |
182
|
|
|
|
183
|
|
|
return; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
$throttle = $collection->getAppAttribute('Balloon\\App\\Notification', 'notification_throttle'); |
187
|
|
|
if (is_array($throttle) && isset($throttle[(string) $collection->getId()])) { |
188
|
|
|
$last = $throttle[(string) $collection->getId()]; |
|
|
|
|
189
|
|
|
} |
190
|
|
|
|
191
|
|
|
$body = preg_replace_callback('/(\{(([a-z]\.*)+)\})/', function ($match) use ($collection) { |
192
|
|
|
return $collection->getAttribute($match[2]); |
193
|
|
|
}, $this->body); |
194
|
|
|
$subject = preg_replace_callback('/(\{(([a-z]\.*)+)\})/', function ($match) use ($collection) { |
195
|
|
|
return $collection->getAttribute($match[2]); |
196
|
|
|
}, $this->subject); |
197
|
|
|
|
198
|
|
|
$this->notifier->notify($this->user, null, $subject, $body); |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
|
As per the PSR-2 coding standard, case statements should not be wrapped in curly braces. There is no need for braces, since each case is terminated by the next
break
.There is also the option to use a semicolon instead of a colon, this is discouraged because many programmers do not even know it works and the colon is universal between programming languages.
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.