Passed
Push — 5.x ( d5c059...39b1e8 )
by Jeroen
22:13 queued 13s
created

DelayedEmailQueueTable::getNextRecipientGUID()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 11
nc 2
nop 2
dl 0
loc 15
ccs 12
cts 12
cp 1
crap 2
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
namespace Elgg\Database;
4
5
use Elgg\Database;
6
use Elgg\Email\DelayedQueue\DatabaseRecord;
7
use Elgg\Traits\TimeUsing;
8
9
/**
10
 * Interfaces with the database to perform operations on the delayed_email_queue table
11
 *
12
 * @internal
13
 * @since 4.0
14
 */
15
class DelayedEmailQueueTable {
16
	
17
	use TimeUsing;
18
	
19
	/**
20
	 * @var string name of the database table
21
	 */
22
	const TABLE_NAME = 'delayed_email_queue';
23
24
	protected Database $db;
25
	
26
	/**
27
	 * Create new service
28
	 *
29
	 * @param Database $db the database service
30
	 */
31 505
	public function __construct(Database $db) {
32 505
		$this->db = $db;
33
	}
34
	
35
	/**
36
	 * Insert a delayed email into the queue
37
	 *
38
	 * @param int    $recipient_guid    the recipient of the email
39
	 * @param string $delivery_interval the desired interval of the recipient
40
	 * @param mixed  $item              the email to queue
41
	 *
42
	 * @return bool
43
	 */
44 14
	public function queueEmail(int $recipient_guid, string $delivery_interval, $item): bool {
45 14
		$insert = Insert::intoTable(self::TABLE_NAME);
46 14
		$insert->values([
47 14
			'recipient_guid' => $insert->param($recipient_guid, ELGG_VALUE_GUID),
48 14
			'delivery_interval' => $insert->param($delivery_interval, ELGG_VALUE_STRING),
49 14
			'data' => $insert->param(serialize($item), ELGG_VALUE_STRING),
50 14
			'timestamp' => $insert->param($this->getCurrentTime()->getTimestamp(), ELGG_VALUE_TIMESTAMP),
51 14
		]);
52
		
53 14
		return $this->db->insertData($insert) !== 0;
54
	}
55
	
56
	/**
57
	 * Get a row from the queue
58
	 *
59
	 * @param int $id the ID to fetch
60
	 *
61
	 * @return DatabaseRecord|null database row
62
	 */
63 2
	public function getRow(int $id): ?DatabaseRecord {
64 2
		$select = Select::fromTable(self::TABLE_NAME);
65 2
		$select->select('*')
66 2
			->where($select->compare('id', '=', $id, ELGG_VALUE_ID));
67
		
68 2
		return $this->db->getDataRow($select, [$this, 'rowToRecord']);
69
	}
70
	
71
	/**
72
	 * Get all the rows in the queue for a given recipient
73
	 *
74
	 * @param int      $recipient_guid    the recipient
75
	 * @param string   $delivery_interval the interval for the recipient
76
	 * @param null|int $timestamp         (optional) all queue items before time (default: now)
77
	 * @param int      $max_results       (optional) maximum number of rows to return
78
	 *
79
	 * @return DatabaseRecord[] database rows
80
	 */
81 8
	public function getRecipientRows(int $recipient_guid, string $delivery_interval, int $timestamp = null, int $max_results = 0): array {
82 8
		$select = Select::fromTable(self::TABLE_NAME);
83 8
		$select->select('*')
84 8
			->where($select->compare('recipient_guid', '=', $recipient_guid, ELGG_VALUE_GUID))
85 8
			->andWhere($select->compare('delivery_interval', '=', $delivery_interval, ELGG_VALUE_STRING))
86 8
			->andWhere($select->compare('timestamp', '<', $timestamp ?? $this->getCurrentTime()->getTimestamp(), ELGG_VALUE_TIMESTAMP))
87 8
			->orderBy('timestamp', 'ASC')
88 8
			->addOrderBy('id', 'ASC');
89
		
90 8
		if ($max_results > 0) {
91 3
			$select->setMaxResults($max_results);
92
		}
93
		
94 8
		return $this->db->getData($select, [$this, 'rowToRecord']);
95
	}
96
	
97
	/**
98
	 * Fetch the GUID of the next recipient to process
99
	 *
100
	 * @param string   $delivery_interval the delivery interval to get
101
	 * @param null|int $timestamp         (optional) based on queue items before time (default: now)
102
	 *
103
	 * @return null|int
104
	 */
105 2
	public function getNextRecipientGUID(string $delivery_interval, int $timestamp = null): ?int {
106 2
		$select = Select::fromTable(self::TABLE_NAME);
107 2
		$select->select('recipient_guid')
108 2
			->where($select->compare('delivery_interval', '=', $delivery_interval, ELGG_VALUE_STRING))
109 2
			->andWhere($select->compare('timestamp', '<', $timestamp ?? $this->getCurrentTime()->getTimestamp()))
110 2
			->orderBy('timestamp', 'ASC')
111 2
			->addOrderBy('id', 'ASC')
112 2
			->setMaxResults(1);
113
		
114 2
		$row = $this->db->getDataRow($select);
115 2
		if (empty($row)) {
116 1
			return null;
117
		}
118
		
119 2
		return (int) $row->recipient_guid;
120
	}
121
	
122
	/**
123
	 * Remove a queue items from the database
124
	 *
125
	 * @param int $id the row to delete
126
	 *
127
	 * @return int number of deleted rows
128
	 */
129 2
	public function deleteRow(int $id): int {
130 2
		$delete = Delete::fromTable(self::TABLE_NAME);
131 2
		$delete->where($delete->compare('id', '=', $id, ELGG_VALUE_ID));
132
		
133 2
		return $this->db->deleteData($delete);
134
	}
135
	
136
	/**
137
	 * Delete all the queue items from the database for the given recipient and interval
138
	 *
139
	 * @param int      $recipient_guid    the recipient
140
	 * @param string   $delivery_interval the interval for the recipient
141
	 * @param null|int $timestamp         (optional) all queue items before time (default: now)
142
	 * @param int      $max_id            (optional) the max row ID to remove (this includes the given row ID)
143
	 *
144
	 * @return int number of deleted rows
145
	 */
146 3
	public function deleteRecipientRows(int $recipient_guid, string $delivery_interval, int $timestamp = null, int $max_id = 0): int {
147 3
		$delete = Delete::fromTable(self::TABLE_NAME);
148 3
		$delete->where($delete->compare('recipient_guid', '=', $recipient_guid, ELGG_VALUE_GUID))
149 3
			->andWhere($delete->compare('delivery_interval', '=', $delivery_interval, ELGG_VALUE_STRING))
150 3
			->andWhere($delete->compare('timestamp', '<', $timestamp ?? $this->getCurrentTime()->getTimestamp(), ELGG_VALUE_INTEGER))
151 3
			->orderBy('timestamp', 'ASC')
152 3
			->addOrderBy('id', 'ASC');
153
		
154 3
		if ($max_id > 0) {
155 2
			$delete->andWhere($delete->compare('id', '<=', $max_id, ELGG_VALUE_ID));
156
		}
157
		
158 3
		return $this->db->deleteData($delete);
159
	}
160
	
161
	/**
162
	 * Deletes all the queue items from the database for the given recipient
163
	 *
164
	 * @param int $recipient_guid the recipient
165
	 *
166
	 * @return int number of deleted rows
167
	 */
168 1290
	public function deleteAllRecipientRows(int $recipient_guid): int {
169 1290
		$delete = Delete::fromTable(self::TABLE_NAME);
170 1290
		$delete->where($delete->compare('recipient_guid', '=', $recipient_guid, ELGG_VALUE_GUID));
171
		
172 1290
		return $this->db->deleteData($delete);
173
	}
174
	
175
	/**
176
	 * Update the queued notifications for the recipient to a new delivery interval
177
	 *
178
	 * @param int    $recipient_guid    the recipient
179
	 * @param string $delivery_interval the new delivery interval
180
	 *
181
	 * @return bool
182
	 */
183 1
	public function updateRecipientInterval(int $recipient_guid, string $delivery_interval): bool {
184 1
		$update = Update::table(self::TABLE_NAME);
185 1
		$update->set('delivery_interval', $update->param($delivery_interval, ELGG_VALUE_STRING))
186 1
			->where($update->compare('recipient_guid', '=', $recipient_guid, ELGG_VALUE_GUID));
187
		
188 1
		return $this->db->updateData($update);
189
	}
190
	
191
	/**
192
	 * Convert a database row to a manageable object
193
	 *
194
	 * @param \stdClass $row the database record
195
	 *
196
	 * @return DatabaseRecord
197
	 */
198 7
	public function rowToRecord(\stdClass $row): DatabaseRecord {
199 7
		return new DatabaseRecord($row);
200
	}
201
}
202