]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Events/ContribListener.php
Improve coding standards
[galette.git] / galette / lib / Galette / Events / ContribListener.php
1 <?php
2
3 /**
4 * Copyright © 2003-2024 The Galette Team
5 *
6 * This file is part of Galette (https://galette.eu).
7 *
8 * Galette is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * Galette is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 namespace Galette\Events;
23
24 use Galette\Core\Db;
25 use Galette\Core\GaletteMail;
26 use Galette\Core\History;
27 use Galette\Core\Links;
28 use Galette\Core\Login;
29 use Galette\Core\Preferences;
30 use Galette\Entity\Adherent;
31 use Galette\Entity\Contribution;
32 use Galette\Entity\Texts;
33 use Analog\Analog;
34 use League\Event\ListenerRegistry;
35 use League\Event\ListenerSubscriber;
36 use Slim\Flash\Messages;
37 use Slim\Routing\RouteParser;
38
39 /**
40 * Event listener for contributions
41 *
42 * @author Johan Cwiklinski <johan@x-tnd.be>
43 */
44 class ContribListener implements ListenerSubscriber
45 {
46 private Preferences $preferences;
47 private RouteParser $routeparser;
48 private History $history;
49 private Messages $flash;
50 private Login $login;
51 private Db $zdb;
52
53 /**
54 * Constructor
55 *
56 * @param Preferences $preferences Preferences instance
57 * @param RouteParser $routeparser RouteParser instance
58 * @param History $history History instance
59 * @param Messages $flash Messages instance
60 * @param Login $login Login instance
61 * @param Db $zdb Db instance
62 */
63 public function __construct(
64 Preferences $preferences,
65 RouteParser $routeparser,
66 History $history,
67 Messages $flash,
68 Login $login,
69 Db $zdb
70 ) {
71 $this->preferences = $preferences;
72 $this->routeparser = $routeparser;
73 $this->history = $history;
74 $this->flash = $flash;
75 $this->login = $login;
76 $this->zdb = $zdb;
77 }
78
79 /**
80 * Set up contribution listeners
81 *
82 * @param ListenerRegistry $acceptor Listener
83 *
84 * @return void
85 */
86 public function subscribeListeners(ListenerRegistry $acceptor): void
87 {
88 $acceptor->subscribeTo(
89 'contribution.add',
90 function (GaletteEvent $event): void {
91 $this->contributionAdded($event->getObject());
92 }
93 );
94 }
95
96 /**
97 * Contribution added listener
98 *
99 * @param Contribution $contrib Added contribution
100 *
101 * @return void
102 */
103 public function contributionAdded(Contribution $contrib): void
104 {
105 Analog::log(
106 '[' . get_class($this) . '] Event contribution.add emitted for #' . $contrib->id,
107 Analog::DEBUG
108 );
109
110 $this->callPostContributionScript($contrib);
111
112 if ($contrib->sendEMail()) {
113 $this->sendContribEmail($contrib, true);
114 }
115 $this->sendAdminEmail($contrib, true);
116 }
117
118 /**
119 * Send account email to member
120 *
121 * @param Contribution $contrib Contribution
122 * @param boolean $new New contribution or editing existing one
123 *
124 * @return void
125 */
126 private function sendContribEmail(Contribution $contrib, bool $new): void
127 {
128 if ($this->preferences->pref_mail_method == GaletteMail::METHOD_DISABLED) {
129 //if email has been disabled in the preferences, we should not be here ;
130 //we do not throw an error, just a simple warning that will be show later
131 $msg = _T("You asked Galette to send a confirmation email to the member, but email has been disabled in the preferences.");
132 $this->flash->addMessage(
133 'warning_detected',
134 $msg
135 );
136 return;
137 }
138
139 // Get member information
140 $member = new Adherent($this->zdb);
141 $member->load($contrib->member);
142
143 if ($member->getEmail() == '' && !$member->self_adh) {
144 $this->flash->addMessage(
145 'error_detected',
146 _T("- You can't send a confirmation by email if the member hasn't got an address!")
147 );
148 return;
149 }
150
151 $texts = new Texts(
152 $this->preferences,
153 $this->routeparser,
154 );
155 $texts
156 ->setMember($member)
157 ->setContribution($contrib);
158
159 $text = 'contrib';
160 if (!$contrib->isFee()) {
161 $text = 'donation';
162 }
163 $mtxt = $texts->getTexts($text, $member->language);
164
165 $mail = new GaletteMail($this->preferences);
166 $mail->setSubject($texts->getSubject());
167 $mail->setRecipients(
168 array(
169 $member->getEmail() => $member->sname
170 )
171 );
172
173 $link_card = '';
174 if (strpos($mtxt->tbody, '{LINK_MEMBERCARD}') !== false) {
175 //member card link is present in mail model, let's add it
176 $links = new Links($this->zdb);
177 if ($hash = $links->generateNewLink(Links::TARGET_MEMBERCARD, $contrib->member)) {
178 $link_card = $this->preferences->getURL() .
179 $this->routeparser->urlFor('directlink', ['hash' => $hash]);
180 }
181 }
182 $texts->setMemberCardLink($link_card);
183
184 $link_pdf = '';
185 if (strpos($mtxt->tbody, '{LINK_CONTRIBPDF}') !== false) {
186 //contribution receipt link is present in mail model, let's add it
187 $links = new Links($this->zdb);
188 $ltype = $contrib->type->isExtension() ? Links::TARGET_INVOICE : Links::TARGET_RECEIPT;
189 if ($hash = $links->generateNewLink($ltype, $contrib->id)) {
190 $link_pdf = $this->preferences->getURL() .
191 $this->routeparser->urlFor('directlink', ['hash' => $hash]);
192 }
193 }
194 $texts->setContribLink($link_pdf);
195
196 $mail->setMessage($texts->getBody());
197 $sent = $mail->send();
198
199 if ($sent) {
200 $this->history->add(
201 preg_replace(
202 array('/%name/', '/%email/'),
203 array($member->sname, $member->getEmail()),
204 _T("Email sent to user %name (%email)")
205 )
206 );
207 } else {
208 $txt = preg_replace(
209 array('/%name/', '/%email/'),
210 array($member->sname, $member->getEmail()),
211 _T("A problem happened while sending contribution receipt to user %name (%email)")
212 );
213 $this->history->add($txt);
214 $this->flash->addMessage(
215 'warning_detected',
216 $txt
217 );
218 }
219 }
220
221 /**
222 * Send new contribution email to admin
223 *
224 * @param Contribution $contrib Contribution
225 * @param boolean $new New contribution or editing existing one
226 *
227 * @return void
228 */
229 private function sendAdminEmail(Contribution $contrib, bool $new): void
230 {
231 if (
232 $this->preferences->pref_mail_method == GaletteMail::METHOD_DISABLED
233 || !$this->preferences->pref_bool_mailadh
234 || (!$new && $contrib->member != $this->login->id)
235 ) {
236 return;
237 }
238
239 // Get member information
240 $member = new Adherent($this->zdb);
241 $member->load($contrib->member);
242
243 $texts = new Texts(
244 $this->preferences,
245 $this->routeparser
246 );
247 $texts
248 ->setMember($member)
249 ->setContribution($contrib);
250
251 // Sent email to admin if pref checked
252 // Get email text in database
253 $text = 'newcont';
254 if (!$contrib->isFee()) {
255 $text = 'newdonation';
256 }
257 $texts->getTexts($text, $this->preferences->pref_lang);
258
259 $mail = new GaletteMail($this->preferences);
260 $mail->setSubject($texts->getSubject());
261
262 $recipients = [];
263 foreach ($this->preferences->vpref_email_newadh as $pref_email) {
264 $recipients[$pref_email] = $pref_email;
265 }
266 $mail->setRecipients($recipients);
267
268 $mail->setMessage($texts->getBody());
269 $sent = $mail->send();
270
271 if ($sent) {
272 $this->history->add(
273 preg_replace(
274 array('/%name/', '/%email/'),
275 array($member->sname, $member->getEmail()),
276 _T("Email sent to admin for user %name (%email)")
277 )
278 );
279 } else {
280 $txt = preg_replace(
281 array('/%name/', '/%email/'),
282 array($member->sname, $member->getEmail()),
283 _T("A problem happened while sending to admin notification for user %name (%email) contribution")
284 );
285 $this->history->add($txt);
286 $this->flash->addMessage(
287 'warning_detected',
288 $txt
289 );
290 }
291 }
292
293 /**
294 * Call post contribution script from Preferences
295 *
296 * @param Contribution $contrib Added contribution
297 *
298 * @return void
299 */
300 private function callPostContributionScript(Contribution $contrib): void
301 {
302 //if an external script has been configured, we call it
303 if ($this->preferences->pref_new_contrib_script) {
304 $es = new \Galette\IO\ExternalScript($this->preferences);
305 $res = $contrib->executePostScript($es);
306
307 if ($res !== true) {
308 //send admin an email with all details
309 if ($this->preferences->pref_mail_method > GaletteMail::METHOD_DISABLED) {
310 $mail = new GaletteMail($this->preferences);
311 $mail->setSubject(
312 _T("Post contribution script failed")
313 );
314
315 $recipients = [];
316 foreach ($this->preferences->vpref_email_newadh as $pref_email) {
317 $recipients[$pref_email] = $pref_email;
318 }
319 $mail->setRecipients($recipients);
320
321 $message = _T("The configured post contribution script has failed.");
322 $message .= "\n" . _T("You can find contribution information and script output below.");
323 $message .= "\n\n";
324 $message .= $res;
325
326 $mail->setMessage($message);
327 $sent = $mail->send();
328
329 if (!$sent) {
330 $txt = _T('Post contribution script has failed.');
331 $this->history->add($txt, $message);
332 $warning_detected[] = $txt;
333 //Mails are disabled... We log (not safe, but)...
334 Analog::log(
335 'Email to admin has not been sent. Here was the data: ' .
336 "\n" . print_r($res, true),
337 Analog::ERROR
338 );
339 }
340 } else {
341 //Mails are disabled... We log (not safe, but)...
342 Analog::log(
343 'Post contribution script has failed. Here was the data: ' .
344 "\n" . print_r($res, true),
345 Analog::ERROR
346 );
347 }
348 }
349 }
350 }
351 }