3 /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
10 * Copyright © 2009-2023 The Galette Team
12 * This file is part of Galette (http://galette.tuxfamily.org).
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.
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.
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/>.
30 * @author Johan Cwiklinski <johan@x-tnd.be>
31 * @copyright 2011-2023 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.7dev - 2011-08-27
37 namespace Galette\Core
;
40 use Laminas\Db\Sql\Select
;
43 use Galette\Entity\Adherent
;
44 use Galette\Filters\MailingsList
;
45 use Laminas\Db\Sql\Expression
;
51 * @name MailingHistory
53 * @author Johan Cwiklinski <johan@x-tnd.be>
54 * @copyright 2011-2023 The Galette Team
55 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL License 3.0 or (at your option) any later version
56 * @link http://galette.tuxfamily.org
57 * @since Available since 0.7dev - 2011-08-27
59 * @property MailingsList $filters
61 class MailingHistory
extends History
63 public const TABLE
= 'mailing_history';
64 public const PK
= 'mailing_id';
66 public const FILTER_DC_SENT
= 0;
67 public const FILTER_SENT
= 1;
68 public const FILTER_NOT_SENT
= 2;
70 private $mailing = null;
78 private $sender_address;
79 private $sent = false;
84 * @param Db $zdb Database
85 * @param Login $login Login
86 * @param Preferences $preferences Preferences
87 * @param MailingsList|null $filters Filtering
88 * @param Mailing|null $mailing Mailing
90 public function __construct(Db
$zdb, Login
$login, Preferences
$preferences, MailingsList
$filters = null, Mailing
$mailing = null)
92 parent
::__construct($zdb, $login, $preferences, $filters);
93 $this->mailing
= $mailing;
97 * Get the entire history list
101 public function getHistory()
104 $select = $this->zdb
->select($this->getTableName(), 'a');
106 array('b' => PREFIX_DB
. Adherent
::TABLE
),
107 'a.mailing_sender=b.' . Adherent
::PK
,
108 array('nom_adh', 'prenom_adh'),
111 $this->buildWhereClause($select);
112 $select->order($this->buildOrderClause());
113 $this->proceedCount($select);
114 //add limits to retrieve only relevant rows
115 $this->filters
->setLimits($select);
116 $results = $this->zdb
->execute($select);
119 foreach ($results as $r) {
120 if ($r['mailing_sender'] !== null && $r['mailing_sender_name'] === null) {
121 $r['mailing_sender_name']
122 = Adherent
::getSName($this->zdb
, $r['mailing_sender']);
126 if ($r['mailing_recipients'] != null) {
127 //FIXME: error suppression with @ must be removed, see https://bugs.galette.eu/issues/1744
128 $recipients = @unserialize
($r['mailing_recipients']);
130 $r['mailing_recipients'] = $recipients;
133 if (file_exists(GALETTE_ATTACHMENTS_PATH
. $r[self
::PK
])) {
134 $rdi = new \
RecursiveDirectoryIterator(
135 GALETTE_ATTACHMENTS_PATH
. $r[self
::PK
],
136 \FilesystemIterator
::SKIP_DOTS
138 $contents = new \
RecursiveIteratorIterator(
140 \RecursiveIteratorIterator
::CHILD_FIRST
142 foreach ($contents as $path) {
143 if ($path->isFile()) {
148 $r['attachments'] = $attachments;
152 } catch (Throwable
$e) {
154 'Unable to get history. | ' . $e->getMessage(),
162 * Builds the order clause
164 * @return array SQL ORDER clauses
166 protected function buildOrderClause()
170 switch ($this->filters
->orderby
) {
171 case MailingsList
::ORDERBY_DATE
:
172 $order[] = 'mailing_date ' . $this->filters
->ordered
;
174 case MailingsList
::ORDERBY_SENDER
:
175 $order[] = 'mailing_sender ' . $this->filters
->ordered
;
177 case MailingsList
::ORDERBY_SUBJECT
:
178 $order[] = 'mailing_subject ' . $this->filters
->ordered
;
180 case MailingsList
::ORDERBY_SENT
:
181 $order[] = 'mailing_sent ' . $this->filters
->ordered
;
189 * Builds where clause, for filtering on simple list mode
191 * @param Select $select Original select
195 private function buildWhereClause($select)
198 if ($this->filters
->start_date_filter
!= null) {
199 $d = new \
DateTime($this->filters
->raw_start_date_filter
);
200 $select->where
->greaterThanOrEqualTo(
206 if ($this->filters
->end_date_filter
!= null) {
207 $d = new \
DateTime($this->filters
->raw_end_date_filter
);
208 $select->where
->lessThanOrEqualTo(
214 if ($this->filters
->sender_filter
!= null && $this->filters
->sender_filter
!= '0') {
215 $sender = $this->filters
->sender_filter
;
216 if ($sender == '-1') {
217 $select->where('mailing_sender IS NULL');
219 $select->where
->equalTo(
226 switch ($this->filters
->sent_filter
) {
227 case self
::FILTER_SENT
:
228 $select->where('mailing_sent = true');
230 case self
::FILTER_NOT_SENT
:
231 $select->where('mailing_sent = false');
233 case self
::FILTER_DC_SENT
:
234 //nothing to do here.
239 if ($this->filters
->subject_filter
!= '') {
240 $token = $this->zdb
->platform
->quoteValue(
241 '%' . strtolower($this->filters
->subject_filter
) . '%'
245 'LOWER(mailing_subject) LIKE ' .
249 } catch (Throwable
$e) {
251 __METHOD__
. ' | ' . $e->getMessage(),
259 * Count history entries from the query
261 * @param Select $select Original select
265 private function proceedCount($select)
268 $countSelect = clone $select;
269 $countSelect->reset($countSelect::COLUMNS
);
270 $countSelect->reset($countSelect::JOINS
);
271 $countSelect->reset($countSelect::ORDER
);
272 $countSelect->columns(
274 self
::PK
=> new Expression('COUNT(' . self
::PK
. ')')
278 $results = $this->zdb
->execute($countSelect);
279 $result = $results->current();
282 $this->count
= $result->$k;
283 $this->filters
->setCounter($this->count
);
284 } catch (Throwable
$e) {
286 'Cannot count history | ' . $e->getMessage(),
294 * Load mailing from an existing one
296 * @param Db $zdb Database instance
297 * @param integer $id Model identifier
298 * @param Mailing $mailing Mailing object
299 * @param boolean $new True if we create a 'new' mailing,
300 * false otherwise (from preview for example)
304 public static function loadFrom(Db
$zdb, $id, $mailing, $new = true)
307 $select = $zdb->select(self
::TABLE
);
308 $select->where(['mailing_id' => $id]);
310 $results = $zdb->execute($select);
311 /** @var ArrayObject $result */
312 $result = $results->current();
314 return $mailing->loadFromHistory($result, $new);
315 } catch (Throwable
$e) {
317 'Unable to load mailing model #' . $id . ' | ' .
326 * Store a mailing in the history
328 * @param boolean $sent Defaults to false
332 public function storeMailing($sent = false)
334 if ($this->mailing
instanceof Mailing
) {
335 if ($this->mailing
->sender_name
!= null) {
336 $this->sender_name
= $this->mailing
->getSenderName();
337 $this->sender_address
= $this->mailing
->getSenderAddress();
339 $this->sender
= $this->login
->id
;
340 $this->subject
= $this->mailing
->subject
;
341 $this->message
= $this->mailing
->message
;
342 $this->recipients
= $this->mailing
->recipients
;
344 $this->date
= date('Y-m-d H:i:s');
345 if (!$this->mailing
->existsInHistory()) {
347 $this->mailing
->id
= $this->id
;
348 $this->mailing
->moveAttachments($this->id
);
350 if ($this->mailing
->tmp_path
!== false) {
351 //attachments are still in a temporary path, move them
352 $this->mailing
->moveAttachments($this->id ??
$this->mailing
->history_id
);
354 //existing stored mailing. Just update row.
361 '] Mailing should be an instance of Mailing',
369 * Update in the database
373 public function update()
376 $_recipients = array();
377 if ($this->recipients
!= null) {
378 foreach ($this->recipients
as $_r) {
379 $_recipients[$_r->id
] = $_r->sname
. ' <' . $_r->email
. '>';
383 $sender = ($this->sender
=== 0) ?
384 new Expression('NULL') : $this->sender
;
385 $sender_name = ($this->sender_name
=== null) ?
386 new Expression('NULL') : $this->sender_name
;
387 $sender_address = ($this->sender_address
=== null) ?
388 new Expression('NULL') : $this->sender_address
;
391 'mailing_sender' => $sender,
392 'mailing_sender_name' => $sender_name,
393 'mailing_sender_address' => $sender_address,
394 'mailing_subject' => $this->subject
,
395 'mailing_body' => $this->message
,
396 'mailing_date' => $this->date
,
397 'mailing_recipients' => serialize($_recipients),
398 'mailing_sent' => ($this->sent
) ?
400 ($this->zdb
->isPostgres() ?
'false' : 0)
403 $update = $this->zdb
->update(self
::TABLE
);
404 $update->set($values);
405 $update->where([self
::PK
=> $this->mailing
->history_id
]);
406 $this->zdb
->execute($update);
408 } catch (Throwable
$e) {
410 'An error occurend updating Mailing | ' . $e->getMessage(),
418 * Store in the database
422 public function store()
425 $_recipients = array();
426 if ($this->recipients
!= null) {
427 foreach ($this->recipients
as $_r) {
428 $_recipients[$_r->id
] = $_r->sname
. ' <' . $_r->email
. '>';
433 if ($this->sender
=== 0) {
434 $sender = new Expression('NULL');
436 $sender = $this->sender
;
438 $sender_name = ($this->sender_name
=== null) ?
439 new Expression('NULL') : $this->sender_name
;
440 $sender_address = ($this->sender_address
=== null) ?
441 new Expression('NULL') : $this->sender_address
;
444 'mailing_sender' => $sender,
445 'mailing_sender_name' => $sender_name,
446 'mailing_sender_address' => $sender_address,
447 'mailing_subject' => $this->subject
,
448 'mailing_body' => $this->message
,
449 'mailing_date' => $this->date
,
450 'mailing_recipients' => serialize($_recipients),
451 'mailing_sent' => ($this->sent
) ?
453 ($this->zdb
->isPostgres() ?
'false' : 0)
456 $insert = $this->zdb
->insert(self
::TABLE
);
457 $insert->values($values);
458 $this->zdb
->execute($insert);
460 $this->id
= $this->zdb
->getLastGeneratedValue($this);
462 } catch (Throwable
$e) {
464 'An error occurend storing Mailing | ' . $e->getMessage(),
472 * Remove specified entries
474 * @param integer|array $ids Mailing history entries identifiers
475 * @param History $hist History instance
479 public function removeEntries($ids, History
$hist)
482 if (is_array($ids)) {
484 } elseif (is_numeric($ids)) {
487 //not numeric and not an array: incorrect.
489 'Asking to remove mailing entries, but without ' .
490 'providing an array or a single numeric value.',
497 foreach ($list as $id) {
498 $mailing = new Mailing($this->preferences
, [], $id);
499 $mailing->removeAttachments();
502 $this->zdb
->connection
->beginTransaction();
505 $delete = $this->zdb
->delete(self
::TABLE
);
506 $delete->where
->in(self
::PK
, $list);
507 $this->zdb
->execute($delete);
510 $this->zdb
->connection
->commit();
512 //add an history entry
514 _T("Delete mailing entries")
518 } catch (Throwable
$e) {
519 $this->zdb
->connection
->rollBack();
521 'Unable to delete selected mailing history entries |' .
532 * @param boolean $prefixed Whether table name should be prefixed
536 protected function getTableName($prefixed = false)
538 if ($prefixed === true) {
539 return PREFIX_DB
. self
::TABLE
;
550 protected function getPk()
556 * Get count for current query
560 public function getCount()