Merge pull request #12828 from seamuslee001/lab_core_357
[civicrm-core.git] / CRM / Mailing / Event / BAO / Forward.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2018 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 /**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2018
32 */
33 class CRM_Mailing_Event_BAO_Forward extends CRM_Mailing_Event_DAO_Forward {
34
35 /**
36 * Class constructor.
37 */
38 public function __construct() {
39 parent::__construct();
40 }
41
42 /**
43 * Create a new forward event, create a new contact if necessary
44 *
45 * @param $job_id
46 * @param $queue_id
47 * @param $hash
48 * @param $forward_email
49 * @param null $fromEmail
50 * @param null $comment
51 *
52 * @return bool
53 */
54 public static function &forward($job_id, $queue_id, $hash, $forward_email, $fromEmail = NULL, $comment = NULL) {
55 $q = CRM_Mailing_Event_BAO_Queue::verify($job_id, $queue_id, $hash);
56
57 $successfulForward = FALSE;
58 $contact_id = NULL;
59 if (!$q) {
60 return $successfulForward;
61 }
62
63 // Find the email address/contact, if it exists.
64
65 $contact = CRM_Contact_BAO_Contact::getTableName();
66 $location = CRM_Core_BAO_Location::getTableName();
67 $email = CRM_Core_BAO_Email::getTableName();
68 $queueTable = CRM_Mailing_Event_BAO_Queue::getTableName();
69 $job = CRM_Mailing_BAO_MailingJob::getTableName();
70 $mailing = CRM_Mailing_BAO_Mailing::getTableName();
71 $forward = self::getTableName();
72
73 $domain = CRM_Core_BAO_Domain::getDomain();
74
75 $dao = new CRM_Core_Dao();
76 $dao->query("
77 SELECT $contact.id as contact_id,
78 $email.id as email_id,
79 $contact.do_not_email as do_not_email,
80 $queueTable.id as queue_id
81 FROM ($email, $job as temp_job)
82 INNER JOIN $contact
83 ON $email.contact_id = $contact.id
84 LEFT JOIN $queueTable
85 ON $email.id = $queueTable.email_id
86 LEFT JOIN $job
87 ON $queueTable.job_id = $job.id
88 AND temp_job.mailing_id = $job.mailing_id
89 WHERE $queueTable.job_id = $job_id
90 AND $email.email = '" .
91 CRM_Utils_Type::escape($forward_email, 'String') . "'"
92 );
93
94 $dao->fetch();
95
96 $transaction = new CRM_Core_Transaction();
97
98 if (isset($dao->queue_id) ||
99 (isset($dao->do_not_email) && $dao->do_not_email == 1)
100 ) {
101 // We already sent this mailing to $forward_email, or we should
102 // never email this contact. Give up.
103
104 return $successfulForward;
105 }
106
107 require_once 'api/api.php';
108 $contactParams = array(
109 'email' => $forward_email,
110 'version' => 3,
111 );
112 $contactValues = civicrm_api('contact', 'get', $contactParams);
113 $count = $contactValues['count'];
114
115 if ($count == 0) {
116 // If the contact does not exist, create one.
117
118 $formatted = array(
119 'contact_type' => 'Individual',
120 'version' => 3,
121 );
122 $locationType = CRM_Core_BAO_LocationType::getDefault();
123 $value = array(
124 'email' => $forward_email,
125 'location_type_id' => $locationType->id,
126 );
127 require_once 'CRM/Utils/DeprecatedUtils.php';
128 _civicrm_api3_deprecated_add_formatted_param($value, $formatted);
129 $formatted['onDuplicate'] = CRM_Import_Parser::DUPLICATE_SKIP;
130 $formatted['fixAddress'] = TRUE;
131 $contact = civicrm_api('contact', 'create', $formatted);
132 if (civicrm_error($contact)) {
133 return $successfulForward;
134 }
135 $contact_id = $contact['id'];
136 }
137 $email = new CRM_Core_DAO_Email();
138 $email->email = $forward_email;
139 $email->find(TRUE);
140 $email_id = $email->id;
141 if (!$contact_id) {
142 $contact_id = $email->contact_id;
143 }
144
145 // Create a new queue event.
146
147 $queue_params = array(
148 'email_id' => $email_id,
149 'contact_id' => $contact_id,
150 'job_id' => $job_id,
151 );
152
153 $queue = CRM_Mailing_Event_BAO_Queue::create($queue_params);
154
155 $forward = new CRM_Mailing_Event_BAO_Forward();
156 $forward->time_stamp = date('YmdHis');
157 $forward->event_queue_id = $queue_id;
158 $forward->dest_queue_id = $queue->id;
159 $forward->save();
160
161 $dao->reset();
162 $dao->query(" SELECT $job.mailing_id as mailing_id
163 FROM $job
164 WHERE $job.id = " .
165 CRM_Utils_Type::escape($job_id, 'Integer')
166 );
167 $dao->fetch();
168 $mailing_obj = new CRM_Mailing_BAO_Mailing();
169 $mailing_obj->id = $dao->mailing_id;
170 $mailing_obj->find(TRUE);
171
172 $config = CRM_Core_Config::singleton();
173 $mailer = \Civi::service('pear_mail');
174
175 $recipient = NULL;
176 $attachments = NULL;
177 $message = $mailing_obj->compose($job_id, $queue->id, $queue->hash,
178 $queue->contact_id, $forward_email, $recipient, FALSE, NULL, $attachments, TRUE, $fromEmail
179 );
180 //append comment if added while forwarding.
181 if (count($comment)) {
182 $message->_txtbody = CRM_Utils_Array::value('body_text', $comment) . $message->_txtbody;
183 if (!empty($comment['body_html'])) {
184 $message->_htmlbody = $comment['body_html'] . '<br />---------------Original message---------------------<br />' . $message->_htmlbody;
185 }
186 }
187
188 $body = $message->get();
189 $headers = $message->headers();
190
191 $result = NULL;
192 if (is_object($mailer)) {
193 $errorScope = CRM_Core_TemporaryErrorScope::ignoreException();
194 $result = $mailer->send($recipient, $headers, $body);
195 unset($errorScope);
196 }
197
198 $params = array(
199 'event_queue_id' => $queue->id,
200 'job_id' => $job_id,
201 'hash' => $queue->hash,
202 );
203 if (is_a($result, 'PEAR_Error')) {
204 // Register the bounce event.
205
206 $params = array_merge($params,
207 CRM_Mailing_BAO_BouncePattern::match($result->getMessage())
208 );
209 CRM_Mailing_Event_BAO_Bounce::create($params);
210 }
211 else {
212 $successfulForward = TRUE;
213 // Register the delivery event.
214
215 CRM_Mailing_Event_BAO_Delivered::create($params);
216 }
217
218 $transaction->commit();
219
220 return $successfulForward;
221 }
222
223 /**
224 * Get row count for the event selector.
225 *
226 * @param int $mailing_id
227 * ID of the mailing.
228 * @param int $job_id
229 * Optional ID of a job to filter on.
230 * @param bool $is_distinct
231 * Group by queue ID?.
232 *
233 * @return int
234 * Number of rows in result set
235 */
236 public static function getTotalCount(
237 $mailing_id, $job_id = NULL,
238 $is_distinct = FALSE
239 ) {
240 $dao = new CRM_Core_DAO();
241
242 $forward = self::getTableName();
243 $queue = CRM_Mailing_Event_BAO_Queue::getTableName();
244 $mailing = CRM_Mailing_BAO_Mailing::getTableName();
245 $job = CRM_Mailing_BAO_MailingJob::getTableName();
246
247 $query = "
248 SELECT COUNT($forward.id) as forward
249 FROM $forward
250 INNER JOIN $queue
251 ON $forward.event_queue_id = $queue.id
252 INNER JOIN $job
253 ON $queue.job_id = $job.id
254 INNER JOIN $mailing
255 ON $job.mailing_id = $mailing.id
256 AND $job.is_test = 0
257 WHERE $mailing.id = " . CRM_Utils_Type::escape($mailing_id, 'Integer');
258
259 if (!empty($job_id)) {
260 $query .= " AND $job.id = " . CRM_Utils_Type::escape($job_id, 'Integer');
261 }
262
263 if ($is_distinct) {
264 $query .= " GROUP BY $queue.id ";
265 }
266
267 // query was missing
268 $dao->query($query);
269
270 if ($dao->fetch()) {
271 return $dao->forward;
272 }
273
274 return NULL;
275 }
276
277 /**
278 * Get rows for the event browser.
279 *
280 * @param int $mailing_id
281 * ID of the mailing.
282 * @param int $job_id
283 * Optional ID of the job.
284 * @param bool $is_distinct
285 * Group by queue id?.
286 * @param int $offset
287 * Offset.
288 * @param int $rowCount
289 * Number of rows.
290 * @param array $sort
291 * Sort array.
292 *
293 * @return array
294 * Result set
295 */
296 public static function &getRows(
297 $mailing_id, $job_id = NULL,
298 $is_distinct = FALSE, $offset = NULL, $rowCount = NULL, $sort = NULL
299 ) {
300
301 $dao = new CRM_Core_Dao();
302
303 $forward = self::getTableName();
304 $queue = CRM_Mailing_Event_BAO_Queue::getTableName();
305 $mailing = CRM_Mailing_BAO_Mailing::getTableName();
306 $job = CRM_Mailing_BAO_MailingJob::getTableName();
307 $contact = CRM_Contact_BAO_Contact::getTableName();
308 $email = CRM_Core_BAO_Email::getTableName();
309
310 $query = "
311 SELECT $contact.display_name as from_name,
312 $contact.id as from_id,
313 $email.email as from_email,
314 dest_contact.id as dest_id,
315 dest_email.email as dest_email,
316 $forward.time_stamp as date
317 FROM $contact
318 INNER JOIN $queue
319 ON $queue.contact_id = $contact.id
320 INNER JOIN $email
321 ON $queue.email_id = $email.id
322 INNER JOIN $forward
323 ON $forward.event_queue_id = $queue.id
324 INNER JOIN $queue as dest_queue
325 ON $forward.dest_queue_id = dest_queue.id
326 INNER JOIN $contact as dest_contact
327 ON dest_queue.contact_id = dest_contact.id
328 INNER JOIN $email as dest_email
329 ON dest_queue.email_id = dest_email.id
330 INNER JOIN $job
331 ON $queue.job_id = $job.id
332 INNER JOIN $mailing
333 ON $job.mailing_id = $mailing.id
334 AND $job.is_test = 0
335 WHERE $mailing.id = " . CRM_Utils_Type::escape($mailing_id, 'Integer');
336
337 if (!empty($job_id)) {
338 $query .= " AND $job.id = " . CRM_Utils_Type::escape($job_id, 'Integer');
339 }
340
341 if ($is_distinct) {
342 $query .= " GROUP BY $queue.id, dest_contact.id, dest_email.email, $forward.time_stamp ";
343 }
344
345 $orderBy = "$contact.sort_name ASC, {$forward}.time_stamp DESC";
346 if ($sort) {
347 if (is_string($sort)) {
348 $sort = CRM_Utils_Type::escape($sort, 'String');
349 $orderBy = $sort;
350 }
351 else {
352 $orderBy = trim($sort->orderBy());
353 }
354 }
355
356 $query .= " ORDER BY {$orderBy} ";
357
358 if ($offset || $rowCount) {
359 //Added "||$rowCount" to avoid displaying all records on first page
360 $query .= ' LIMIT ' . CRM_Utils_Type::escape($offset, 'Integer') . ', ' . CRM_Utils_Type::escape($rowCount, 'Integer');
361 }
362
363 $dao->query($query);
364
365 $results = array();
366
367 while ($dao->fetch()) {
368 $from_url = CRM_Utils_System::url('civicrm/contact/view',
369 "reset=1&cid={$dao->from_id}"
370 );
371 $dest_url = CRM_Utils_System::url('civicrm/contact/view',
372 "reset=1&cid={$dao->dest_id}"
373 );
374 $results[] = array(
375 'from_name' => "<a href=\"$from_url\">{$dao->from_name}</a>",
376 'from_email' => $dao->from_email,
377 'dest_email' => "<a href=\"$dest_url\">{$dao->dest_email}</a>",
378 'date' => CRM_Utils_Date::customFormat($dao->date),
379 );
380 }
381 return $results;
382 }
383
384 }