]> git.agnieray.net Git - galette.git/blob - galette/lib/Galette/Entity/Reminder.php
Fix mail reminders
[galette.git] / galette / lib / Galette / Entity / Reminder.php
1 <?php
2
3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
5 /**
6 * Reminders
7 *
8 * PHP version 5
9 *
10 * Copyright © 2013-2021 The Galette Team
11 *
12 * This file is part of Galette (http://galette.tuxfamily.org).
13 *
14 * Galette is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation, either version 3 of the License, or
17 * (at your option) any later version.
18 *
19 * Galette is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with Galette. If not, see <http://www.gnu.org/licenses/>.
26 *
27 * @category Entity
28 * @package Galette
29 *
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2013-2021 The Galette Team
32 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
33 * @link http://galette.tuxfamily.org
34 * @since Available since 0.7.5dev - 2013-02-11
35 */
36
37 namespace Galette\Entity;
38
39 use Galette\Features\Replacements;
40 use Throwable;
41 use Analog\Analog;
42 use Galette\Core\GaletteMail;
43 use Galette\Core\Db;
44 use Galette\Core\History;
45
46 /**
47 * Reminders
48 *
49 * @category Entity
50 * @name Reminder
51 * @package Galette
52 * @author Johan Cwiklinski <johan@x-tnd.be>
53 * @copyright 2009-2021 The Galette Team
54 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
55 * @link http://galette.tuxfamily.org
56 * @since Available since 0.7.5dev - 2013-02-11
57 */
58
59 class Reminder
60 {
61 use Replacements;
62
63 public const TABLE = 'reminders';
64 public const PK = 'reminder_id';
65
66 private $id;
67 private $type;
68 private $dest;
69 private $date;
70 /** @var boolean */
71 private $success = false;
72 /** @var boolean */
73 private $nomail;
74 private $comment;
75 private $msg;
76
77 public const IMPENDING = 1;
78 public const LATE = 2;
79
80 /**
81 * Main constructor
82 *
83 * @param mixed $args Arguments
84 */
85 public function __construct($args = null)
86 {
87 if ($args !== null) {
88 if (is_int($args)) {
89 $this->load($args);
90 } elseif (is_object($args)) {
91 $this->loadFromRs($args);
92 } else {
93 Analog::log(
94 __METHOD__ . ': unknonw arg',
95 Analog::WARNING
96 );
97 }
98 }
99 }
100
101 /**
102 * Load a reminder from its id
103 *
104 * @param int $id Identifier
105 *
106 * @return void
107 */
108 private function load($id)
109 {
110 global $zdb;
111 try {
112 $select = $zdb->select(self::TABLE);
113 $select->limit(1)
114 ->where(self::PK . ' = ' . $id);
115
116 $results = $zdb->execute($select);
117 $this->loadFromRs($results->current());
118 } catch (Throwable $e) {
119 Analog::log(
120 'An error occurred loading reminder #' . $id . "Message:\n" .
121 $e->getMessage(),
122 Analog::ERROR
123 );
124 }
125 }
126
127 /**
128 * Load reminder from a db ResultSet
129 *
130 * @param ResultSet $rs ResultSet
131 *
132 * @return void
133 */
134 private function loadFromRs($rs)
135 {
136 global $zdb;
137
138 try {
139 $pk = self::PK;
140 $this->id = $rs->$pk;
141 $this->type = $rs->reminder_type;
142 $this->dest = new Adherent($zdb, (int)$rs->reminder_dest);
143 $this->date = $rs->reminder_date;
144 $this->success = $rs->reminder_success;
145 $this->nomail = $rs->reminder_nomail;
146 $this->comment = $rs->reminder_comment;
147 } catch (Throwable $e) {
148 Analog::log(
149 __METHOD__ . ': incorrect ResultSet. Error: ' . $e->getMessage(),
150 Analog::ERROR
151 );
152 Analog::log(
153 print_r($rs, true),
154 Analog::INFO
155 );
156 }
157 }
158
159 /**
160 * Store reminder in database and history
161 *
162 * @param Db $zdb Database instance
163 *
164 * @return boolean
165 */
166 private function store($zdb)
167 {
168 $now = new \DateTime();
169 $data = array(
170 'reminder_type' => $this->type,
171 'reminder_dest' => $this->dest->id,
172 'reminder_date' => $now->format('Y-m-d'),
173 'reminder_success' => ($this->success) ?
174 true :
175 ($zdb->isPostgres() ? 'false' : 0),
176 'reminder_nomail' => ($this->nomail) ?
177 true :
178 ($zdb->isPostgres() ? 'false' : 0)
179 );
180 try {
181 $insert = $zdb->insert(self::TABLE);
182 $insert->values($data);
183
184 $add = $zdb->execute($insert);
185 if (!($add->count() > 0)) {
186 Analog::log('Reminder not stored!', Analog::ERROR);
187 return false;
188 }
189 return true;
190 } catch (Throwable $e) {
191 Analog::log(
192 'An error occurred storing reminder: ' . $e->getMessage() .
193 "\n" . print_r($data, true),
194 Analog::ERROR
195 );
196 return false;
197 }
198 }
199
200 /**
201 * Was reminder sent successfully?
202 *
203 * @return boolean
204 */
205 public function isSuccess()
206 {
207 return $this->success;
208 }
209
210 /**
211 * Did member had an email when reminder was sent?
212 *
213 * @return boolean
214 */
215 public function hasMail()
216 {
217 return !$this->nomail;
218 }
219
220 /**
221 * Send the reminder
222 *
223 * @param Texts $texts Text object
224 * @param History $hist History
225 * @param Db $zdb Database instance
226 *
227 * @return boolean
228 */
229 public function send(Texts $texts, History $hist, Db $zdb)
230 {
231 global $preferences;
232
233 $this->success = false;
234
235 $type_name = 'late';
236 if ($this->type === self::IMPENDING) {
237 $type_name = 'impending';
238 }
239
240 if ($this->hasMail()) {
241 $texts->setMember($this->dest)
242 ->setNoContribution();
243
244 $texts->getTexts(
245 $type_name . 'duedate',
246 $this->dest->language
247 );
248
249 $mail = new GaletteMail($preferences);
250 $mail->setSubject($texts->getSubject());
251 $mail->setRecipients(
252 array(
253 $this->dest->getEmail() => $this->dest->sname
254 )
255 );
256 $mail->setMessage($texts->getBody());
257 $sent = $mail->send();
258
259 $details = str_replace(
260 array(
261 '%name',
262 '%mail',
263 '%days'
264 ),
265 array(
266 $this->dest->sname,
267 $this->dest->getEmail(),
268 $this->dest->days_remaining
269 ),
270 _T("%name <%mail> (%days days)")
271 );
272
273 if ($sent == GaletteMail::MAIL_SENT) {
274 $this->success = true;
275 $msg = '';
276 if ($type_name == 'late') {
277 $msg = _T("Sent reminder email for late membership");
278 } else {
279 $msg = _T("Sent reminder email for impending membership");
280 }
281 $this->msg = $details;
282 $hist->add($msg, $details);
283 } else {
284 if ($type_name == 'late') {
285 $msg = _T("A problem happened while sending late membership email");
286 } else {
287 $msg = _T("A problem happened while sending impending membership email");
288 }
289 $this->msg = $details;
290 $hist->add($msg, $details);
291 }
292 } else {
293 $this->nomail = true;
294 $str = str_replace(
295 '%membership',
296 $type_name,
297 _T("Unable to send %membership reminder (no email address).")
298 );
299 $details = str_replace(
300 array(
301 '%name',
302 '%id',
303 '%days'
304 ),
305 array(
306 $this->dest->sname,
307 $this->dest->id,
308 $this->dest->days_remaining
309 ),
310 _T("%name (#%id - %days days)")
311 );
312 $hist->add($str, $details);
313 $this->msg = $this->dest->sname;
314 }
315 //store reminder in database
316 $this->store($zdb);
317 return $this->success;
318 }
319
320 /**
321 * Retrieve message
322 *
323 * @return string
324 */
325 public function getMessage()
326 {
327 return $this->msg;
328 }
329
330 /**
331 * Getter
332 *
333 * @param string $name Property name
334 *
335 * @return mixed
336 */
337 public function __get($name)
338 {
339 switch ($name) {
340 case 'member_id':
341 return $this->dest->id;
342 case 'type':
343 case 'date':
344 return $this->$name;
345 default:
346 Analog::log(
347 'Unable to get Reminder property ' . $name,
348 Analog::WARNING
349 );
350 break;
351 }
352 }
353
354 /**
355 * Setter
356 *
357 * @param string $name Property name
358 * @param mixed $value Property value
359 *
360 * @return void
361 */
362 public function __set($name, $value)
363 {
364 switch ($name) {
365 case 'type':
366 if (
367 $value === self::IMPENDING
368 || $value === self::LATE
369 ) {
370 $this->type = $value;
371 } else {
372 throw new \UnexpectedValueException(
373 'Unknown type!'
374 );
375 }
376 break;
377 case 'dest':
378 if ($this->type !== null && $value instanceof Adherent) {
379 $this->dest = $value;
380
381 if ($value->getEmail() != '') {
382 $this->nomail = false;
383 }
384 } else {
385 if (!$value instanceof Adherent) {
386 throw new \UnexpectedValueException(
387 'Please provide a member object.'
388 );
389 } else {
390 throw new \UnderflowException(
391 'Please set reminder type first.'
392 );
393 }
394 }
395 break;
396 default:
397 Analog::log(
398 'Unable to set property ' . $name,
399 Analog::WARNING
400 );
401 break;
402 }
403 }
404 }