Merge pull request #15840 from yashodha/participant_edit
[civicrm-core.git] / CRM / Mailing / BAO / Query.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
bc77d7c0 4 | Copyright CiviCRM LLC. All rights reserved. |
6a488035 5 | |
bc77d7c0
TO
6 | This work is published under the GNU AGPLv3 license with some |
7 | permitted exceptions and without any warranty. For full license |
8 | and copyright information, see https://civicrm.org/licensing |
6a488035
TO
9 +--------------------------------------------------------------------+
10 */
11
12/**
13 *
14 * @package CRM
ca5cec67 15 * @copyright CiviCRM LLC https://civicrm.org/licensing
6a488035
TO
16 */
17class CRM_Mailing_BAO_Query {
18
e0ef6999 19 /**
0a71a7f7 20 * Get fields for the mailing & mailing job entity.
21 *
22 * @return array
e0ef6999 23 */
00be9182 24 public static function &getFields() {
0a71a7f7 25 $mailingFields = CRM_Mailing_BAO_Mailing::fields();
26 $mailingJobFields = CRM_Mailing_BAO_MailingJob::fields();
27
28 // In general it's good to return as many fields as could possibly be searched, but
29 // with the limitation that if the fields do not have unique names they might
30 // clobber other fields :-(
31 $fields = [
32 'mailing_id' => $mailingFields['id'],
33 'mailing_job_start_date' => $mailingJobFields['mailing_job_start_date'],
34 ];
35 return $fields;
6a488035
TO
36 }
37
38 /**
100fef9d 39 * If mailings are involved, add the specific Mailing fields
6a488035 40 *
77b97be7 41 * @param $query
6a488035 42 */
00be9182 43 public static function select(&$query) {
6a488035
TO
44 // if Mailing mode add mailing id
45 if ($query->_mode & CRM_Contact_BAO_Query::MODE_MAILING) {
46 $query->_select['mailing_id'] = "civicrm_mailing.id as mailing_id";
47 $query->_element['mailing_id'] = 1;
2cc569f2 48
335038eb 49 // base table is contact, so join recipients to it
6c552737
TO
50 $query->_tables['civicrm_mailing_recipients'] = $query->_whereTables['civicrm_mailing_recipients']
51 = " INNER JOIN civicrm_mailing_recipients ON civicrm_mailing_recipients.contact_id = contact_a.id ";
2cc569f2 52
335038eb 53 $query->_tables['civicrm_mailing'] = $query->_whereTables['civicrm_mailing'] = 1;
2cc569f2
PJ
54
55 // get mailing name
a7488080 56 if (!empty($query->_returnProperties['mailing_name'])) {
353ffa53 57 $query->_select['mailing_name'] = "civicrm_mailing.name as mailing_name";
2cc569f2
PJ
58 $query->_element['mailing_name'] = 1;
59 }
60
61 // get mailing subject
a7488080 62 if (!empty($query->_returnProperties['mailing_subject'])) {
353ffa53 63 $query->_select['mailing_subject'] = "civicrm_mailing.subject as mailing_subject";
2cc569f2
PJ
64 $query->_element['mailing_subject'] = 1;
65 }
66
67 // get mailing status
a7488080 68 if (!empty($query->_returnProperties['mailing_job_status'])) {
6c552737
TO
69 $query->_tables['civicrm_mailing_job'] = $query->_whereTables['civicrm_mailing_job']
70 = " LEFT JOIN civicrm_mailing_job ON civicrm_mailing_job.mailing_id = civicrm_mailing.id AND civicrm_mailing_job.parent_id IS NULL AND civicrm_mailing_job.is_test != 1 ";
353ffa53 71 $query->_select['mailing_job_status'] = "civicrm_mailing_job.status as mailing_job_status";
2cc569f2
PJ
72 $query->_element['mailing_job_status'] = 1;
73 }
74
75 // get email on hold
a7488080 76 if (!empty($query->_returnProperties['email_on_hold'])) {
2cc569f2
PJ
77 $query->_select['email_on_hold'] = "recipient_email.on_hold as email_on_hold";
78 $query->_element['email_on_hold'] = 1;
79 $query->_tables['recipient_email'] = $query->_whereTables['recipient_email'] = 1;
80 }
81
82 // get recipient email
a7488080 83 if (!empty($query->_returnProperties['email'])) {
2cc569f2
PJ
84 $query->_select['email'] = "recipient_email.email as email";
85 $query->_element['email'] = 1;
86 $query->_tables['recipient_email'] = $query->_whereTables['recipient_email'] = 1;
87 }
88
89 // get user opt out
a7488080 90 if (!empty($query->_returnProperties['contact_opt_out'])) {
2cc569f2
PJ
91 $query->_select['contact_opt_out'] = "contact_a.is_opt_out as contact_opt_out";
92 $query->_element['contact_opt_out'] = 1;
93 }
94
95 // mailing job end date / completed date
a7488080 96 if (!empty($query->_returnProperties['mailing_job_end_date'])) {
6c552737
TO
97 $query->_tables['civicrm_mailing_job'] = $query->_whereTables['civicrm_mailing_job']
98 = " LEFT JOIN civicrm_mailing_job ON civicrm_mailing_job.mailing_id = civicrm_mailing.id AND civicrm_mailing_job.parent_id IS NULL AND civicrm_mailing_job.is_test != 1 ";
353ffa53 99 $query->_select['mailing_job_end_date'] = "civicrm_mailing_job.end_date as mailing_job_end_date";
2cc569f2
PJ
100 $query->_element['mailing_job_end_date'] = 1;
101 }
47546fcf 102
a7488080 103 if (!empty($query->_returnProperties['mailing_recipients_id'])) {
335038eb
PJ
104 $query->_select['mailing_recipients_id'] = " civicrm_mailing_recipients.id as mailing_recipients_id";
105 $query->_element['mailing_recipients_id'] = 1;
47546fcf 106 }
6a488035 107 }
04cac635 108
109 if (CRM_Utils_Array::value('mailing_campaign_id', $query->_returnProperties)) {
110 $query->_select['mailing_campaign_id'] = 'civicrm_mailing.campaign_id as mailing_campaign_id';
111 $query->_element['mailing_campaign_id'] = 1;
112 $query->_tables['civicrm_campaign'] = 1;
113 }
6a488035
TO
114 }
115
2c3ccaa9 116 /**
117 * Get the metadata for fields to be included on the mailing search form.
118 *
119 * @throws \CiviCRM_API3_Exception
120 *
121 * @todo ideally this would be a trait included on the mailing search & advanced search
122 * rather than a static function.
123 */
124 public static function getSearchFieldMetadata() {
0058ef3f 125 $fields = ['mailing_job_start_date'];
2c3ccaa9 126 $metadata = civicrm_api3('Mailing', 'getfields', [])['values'];
127 $metadata = array_merge($metadata, civicrm_api3('MailingJob', 'getfields', [])['values']);
128 return array_intersect_key($metadata, array_flip($fields));
129 }
130
e0ef6999
EM
131 /**
132 * @param $query
133 */
00be9182 134 public static function where(&$query) {
6a488035
TO
135 $grouping = NULL;
136 foreach (array_keys($query->_params) as $id) {
a7488080 137 if (empty($query->_params[$id][0])) {
6a488035
TO
138 continue;
139 }
140 if (substr($query->_params[$id][0], 0, 8) == 'mailing_') {
2da8c6c4 141 if ($query->_mode == CRM_Contact_BAO_Query::MODE_CONTACTS) {
6a488035
TO
142 $query->_useDistinct = TRUE;
143 }
144 $grouping = $query->_params[$id][3];
145 self::whereClauseSingle($query->_params[$id], $query);
146 }
147 }
148 }
149
e0ef6999 150 /**
100fef9d 151 * @param string $name
e0ef6999
EM
152 * @param $mode
153 * @param $side
154 *
155 * @return null|string
156 */
00be9182 157 public static function from($name, $mode, $side) {
6a488035 158 $from = NULL;
335038eb 159
6a488035 160 switch ($name) {
335038eb
PJ
161 case 'civicrm_mailing_recipients':
162 $from = " $side JOIN civicrm_mailing_recipients ON civicrm_mailing_recipients.contact_id = contact_a.id";
6a488035
TO
163 break;
164
335038eb
PJ
165 case 'civicrm_mailing_event_queue':
166 // this is tightly binded so as to do a check WRT actual job recipients ('child' type jobs)
167 $from = " INNER JOIN civicrm_mailing_event_queue ON
168 civicrm_mailing_event_queue.contact_id = civicrm_mailing_recipients.contact_id
169 AND civicrm_mailing_event_queue.job_id = civicrm_mailing_job.id AND civicrm_mailing_job.job_type = 'child'";
6a488035
TO
170 break;
171
172 case 'civicrm_mailing':
335038eb
PJ
173 $from = " $side JOIN civicrm_mailing ON civicrm_mailing.id = civicrm_mailing_recipients.mailing_id ";
174 break;
175
176 case 'civicrm_mailing_job':
eb6a4756 177 $from = " $side JOIN civicrm_mailing_job ON civicrm_mailing_job.mailing_id = civicrm_mailing.id AND civicrm_mailing_job.is_test != 1 ";
6a488035
TO
178 break;
179
180 case 'civicrm_mailing_event_bounce':
181 case 'civicrm_mailing_event_delivered':
182 case 'civicrm_mailing_event_opened':
183 case 'civicrm_mailing_event_reply':
184 case 'civicrm_mailing_event_unsubscribe':
185 case 'civicrm_mailing_event_forward':
186 case 'civicrm_mailing_event_trackable_url_open':
187 $from = " $side JOIN $name ON $name.event_queue_id = civicrm_mailing_event_queue.id";
188 break;
2cc569f2
PJ
189
190 case 'recipient_email':
335038eb
PJ
191 $from = " $side JOIN civicrm_email recipient_email ON recipient_email.id = civicrm_mailing_recipients.email_id";
192 break;
7851dc81
JP
193
194 case 'civicrm_campaign':
195 $from = " $side JOIN civicrm_campaign ON civicrm_campaign.id = civicrm_mailing.campaign_id";
196 break;
6a488035
TO
197 }
198
199 return $from;
200 }
201
e0ef6999
EM
202 /**
203 * @param $mode
204 * @param bool $includeCustomFields
205 *
206 * @return array|null
207 */
2da40d21 208 public static function defaultReturnProperties(
a3d7e8ee 209 $mode,
6a488035
TO
210 $includeCustomFields = TRUE
211 ) {
212
213 $properties = NULL;
214 if ($mode & CRM_Contact_BAO_Query::MODE_MAILING) {
be2fb01f 215 $properties = [
2cc569f2 216 'mailing_id' => 1,
04cac635 217 'mailing_campaign_id' => 1,
2cc569f2
PJ
218 'mailing_name' => 1,
219 'sort_name' => 1,
220 'email' => 1,
221 'mailing_subject' => 1,
222 'email_on_hold' => 1,
223 'contact_opt_out' => 1,
224 'mailing_job_status' => 1,
225 'mailing_job_end_date' => 1,
226 'contact_type' => 1,
47546fcf 227 'contact_sub_type' => 1,
21dfd5f5 228 'mailing_recipients_id' => 1,
be2fb01f 229 ];
6a488035
TO
230 }
231 return $properties;
232 }
233
e0ef6999
EM
234 /**
235 * @param $values
236 * @param $query
237 */
00be9182 238 public static function whereClauseSingle(&$values, &$query) {
6a488035
TO
239 list($name, $op, $value, $grouping, $wildcard) = $values;
240
6a488035
TO
241 switch ($name) {
242 case 'mailing_id':
243 $selectedMailings = array_flip($value);
6a488035
TO
244 $value = "(" . implode(',', $value) . ")";
245 $op = 'IN';
246 $query->_where[$grouping][] = "civicrm_mailing.id $op $value";
247
248 $mailings = CRM_Mailing_BAO_Mailing::getMailingsList();
249 foreach ($selectedMailings as $id => $dnc) {
250 $selectedMailings[$id] = $mailings[$id];
251 }
252 $selectedMailings = implode(' or ', $selectedMailings);
253
254 $query->_qill[$grouping][] = "Mailing Name $op \"$selectedMailings\"";
6a488035 255 $query->_tables['civicrm_mailing'] = $query->_whereTables['civicrm_mailing'] = 1;
335038eb 256 $query->_tables['civicrm_mailing_recipients'] = $query->_whereTables['civicrm_mailing_recipients'] = 1;
6a488035
TO
257 return;
258
259 case 'mailing_name':
b0f72207 260 $value = addslashes($value);
481a74f4 261 if ($wildcard) {
6a488035 262 $value = "%$value%";
353ffa53 263 $op = 'LIKE';
6a488035 264 }
b27d1855 265
b0f72207 266 $query->_where[$grouping][] = "civicrm_mailing.name $op '$value'";
353ffa53 267 $query->_qill[$grouping][] = "Mailing Namename $op \"$value\"";
6a488035 268 $query->_tables['civicrm_mailing'] = $query->_whereTables['civicrm_mailing'] = 1;
335038eb 269 $query->_tables['civicrm_mailing_recipients'] = $query->_whereTables['civicrm_mailing_recipients'] = 1;
6a488035
TO
270 return;
271
272 case 'mailing_date':
273 case 'mailing_date_low':
274 case 'mailing_date_high':
6a488035
TO
275 $query->_tables['civicrm_mailing_job'] = $query->_whereTables['civicrm_mailing_job'] = 1;
276 $query->dateQueryBuilder($values,
277 'civicrm_mailing_job', 'mailing_date', 'start_date', 'Mailing Delivery Date'
278 );
279 return;
280
281 case 'mailing_delivery_status':
282 $options = CRM_Mailing_PseudoConstant::yesNoOptions('delivered');
283
284 list($name, $op, $value, $grouping, $wildcard) = $values;
285 if ($value == 'Y') {
286 self::mailingEventQueryBuilder($query, $values,
287 'civicrm_mailing_event_delivered',
288 'mailing_delivery_status',
289 ts('Mailing Delivery'),
290 $options
291 );
292 }
293 elseif ($value == 'N') {
294 $options['Y'] = $options['N'];
be2fb01f 295 $values = [$name, $op, 'Y', $grouping, $wildcard];
6a488035
TO
296 self::mailingEventQueryBuilder($query, $values,
297 'civicrm_mailing_event_bounce',
298 'mailing_delivery_status',
299 ts('Mailing Delivery'),
300 $options
301 );
302 }
303 return;
304
111b2847 305 case 'mailing_bounce_types':
306 $op = 'IN';
be2fb01f 307 $values = [$name, $op, $value, $grouping, $wildcard];
111b2847 308 self::mailingEventQueryBuilder($query, $values,
309 'civicrm_mailing_event_bounce',
310 'bounce_type_id',
311 ts('Bounce type(s)'),
be2fb01f 312 CRM_Core_PseudoConstant::get('CRM_Mailing_Event_DAO_Bounce', 'bounce_type_id', [
7e8c8317
SL
313 'keyColumn' => 'id',
314 'labelColumn' => 'name',
315 ])
111b2847 316 );
317 return;
318
6a488035
TO
319 case 'mailing_open_status':
320 self::mailingEventQueryBuilder($query, $values,
321 'civicrm_mailing_event_opened', 'mailing_open_status', ts('Mailing: Trackable Opens'), CRM_Mailing_PseudoConstant::yesNoOptions('open')
322 );
323 return;
324
325 case 'mailing_click_status':
326 self::mailingEventQueryBuilder($query, $values,
327 'civicrm_mailing_event_trackable_url_open', 'mailing_click_status', ts('Mailing: Trackable URL Clicks'), CRM_Mailing_PseudoConstant::yesNoOptions('click')
328 );
329 return;
330
331 case 'mailing_reply_status':
332 self::mailingEventQueryBuilder($query, $values,
333 'civicrm_mailing_event_reply', 'mailing_reply_status', ts('Mailing: Trackable Replies'), CRM_Mailing_PseudoConstant::yesNoOptions('reply')
334 );
335 return;
336
337 case 'mailing_optout':
be2fb01f 338 $valueTitle = [1 => ts('Opt-out Requests')];
6a488035
TO
339 // include opt-out events only
340 $query->_where[$grouping][] = "civicrm_mailing_event_unsubscribe.org_unsubscribe = 1";
341 self::mailingEventQueryBuilder($query, $values,
342 'civicrm_mailing_event_unsubscribe', 'mailing_unsubscribe',
343 ts('Mailing: '), $valueTitle
344 );
345 return;
346
347 case 'mailing_unsubscribe':
be2fb01f 348 $valueTitle = [1 => ts('Unsubscribe Requests')];
6a488035
TO
349 // exclude opt-out events
350 $query->_where[$grouping][] = "civicrm_mailing_event_unsubscribe.org_unsubscribe = 0";
351 self::mailingEventQueryBuilder($query, $values,
352 'civicrm_mailing_event_unsubscribe', 'mailing_unsubscribe',
353 ts('Mailing: '), $valueTitle
354 );
355 return;
356
357 case 'mailing_forward':
be2fb01f 358 $valueTitle = ['Y' => ts('Forwards')];
6a488035
TO
359 // since its a checkbox
360 $values[2] = 'Y';
361 self::mailingEventQueryBuilder($query, $values,
362 'civicrm_mailing_event_forward', 'mailing_forward',
363 ts('Mailing: '), $valueTitle
364 );
365 return;
335038eb
PJ
366
367 case 'mailing_job_status':
368 if (!empty($value)) {
369 if ($value != 'Scheduled' && $value != 'Canceled') {
370 $query->_tables['civicrm_mailing_event_queue'] = $query->_whereTables['civicrm_mailing_event_queue'] = 1;
371 }
335038eb 372 $query->_tables['civicrm_mailing_job'] = $query->_whereTables['civicrm_mailing_job'] = 1;
335038eb 373 $query->_where[$grouping][] = " civicrm_mailing_job.status = '{$value}' ";
353ffa53 374 $query->_qill[$grouping][] = "Mailing Job Status IS \"$value\"";
335038eb
PJ
375 }
376 return;
04cac635 377
378 case 'mailing_campaign_id':
6f56dc34 379 $name = 'campaign_id';
c432c016 380 $query->_where[$grouping][] = CRM_Contact_BAO_Query::buildClause("civicrm_mailing.$name", $op, $value, 'Integer');
6f56dc34 381 list($op, $value) = CRM_Contact_BAO_Query::buildQillForFieldValue('CRM_Mailing_DAO_Mailing', $name, $value, $op);
be2fb01f 382 $query->_qill[$grouping][] = ts('Campaign %1 %2', [1 => $op, 2 => $value]);
6f56dc34 383 $query->_tables['civicrm_mailing'] = $query->_whereTables['civicrm_mailing'] = 1;
04cac635 384 $query->_tables['civicrm_mailing_recipients'] = $query->_whereTables['civicrm_mailing_recipients'] = 1;
385 return;
6a488035
TO
386 }
387 }
388
389 /**
fe482240 390 * Add all the elements shared between Mailing search and advnaced search.
6a488035 391 *
2c3ccaa9 392 * @param \CRM_Mailing_Form_Search $form
6a488035 393 *
2c3ccaa9 394 * @throws \CiviCRM_API3_Exception
6a488035 395 */
00be9182 396 public static function buildSearchForm(&$form) {
2c3ccaa9 397 $form->addSearchFieldMetadata(['Mailing' => self::getSearchFieldMetadata()]);
398 $form->addFormFieldsFromMetadata();
399
6a488035
TO
400 // mailing selectors
401 $mailings = CRM_Mailing_BAO_Mailing::getMailingsList();
402
403 if (!empty($mailings)) {
404 $form->add('select', 'mailing_id', ts('Mailing Name(s)'), $mailings, FALSE,
be2fb01f 405 ['id' => 'mailing_id', 'multiple' => 'multiple', 'class' => 'crm-select2']
6a488035
TO
406 );
407 }
408
be2fb01f 409 $mailingJobStatuses = [
335038eb
PJ
410 '' => ts('- select -'),
411 'Complete' => 'Complete',
412 'Scheduled' => 'Scheduled',
413 'Running' => 'Running',
21dfd5f5 414 'Canceled' => 'Canceled',
be2fb01f 415 ];
335038eb
PJ
416 $form->addElement('select', 'mailing_job_status', ts('Mailing Job Status'), $mailingJobStatuses, FALSE);
417
111b2847 418 $mailingBounceTypes = CRM_Core_PseudoConstant::get(
419 'CRM_Mailing_Event_DAO_Bounce', 'bounce_type_id',
be2fb01f 420 ['keyColumn' => 'id', 'labelColumn' => 'name']
111b2847 421 );
c9fd7217 422 $form->add('select', 'mailing_bounce_types', ts('Bounce Types'), $mailingBounceTypes, FALSE,
be2fb01f 423 ['id' => 'mailing_bounce_types', 'multiple' => 'multiple', 'class' => 'crm-select2']
c9fd7217 424 );
111b2847 425
6a488035 426 // event filters
be2fb01f
CW
427 $form->addRadio('mailing_delivery_status', ts('Delivery Status'), CRM_Mailing_PseudoConstant::yesNoOptions('delivered'), ['allowClear' => TRUE]);
428 $form->addRadio('mailing_open_status', ts('Trackable Opens'), CRM_Mailing_PseudoConstant::yesNoOptions('open'), ['allowClear' => TRUE]);
429 $form->addRadio('mailing_click_status', ts('Trackable URLs'), CRM_Mailing_PseudoConstant::yesNoOptions('click'), ['allowClear' => TRUE]);
430 $form->addRadio('mailing_reply_status', ts('Trackable Replies'), CRM_Mailing_PseudoConstant::yesNoOptions('reply'), ['allowClear' => TRUE]);
6a488035
TO
431
432 $form->add('checkbox', 'mailing_unsubscribe', ts('Unsubscribe Requests'));
433 $form->add('checkbox', 'mailing_optout', ts('Opt-out Requests'));
434 $form->add('checkbox', 'mailing_forward', ts('Forwards'));
04cac635 435 // Campaign select field
436 CRM_Campaign_BAO_Campaign::addCampaignInComponentSearch($form, 'mailing_campaign_id');
6a488035
TO
437
438 $form->assign('validCiviMailing', TRUE);
6a488035
TO
439 }
440
e0ef6999
EM
441 /**
442 * @param $row
100fef9d 443 * @param int $id
e0ef6999 444 */
35f7561f
TO
445 public static function searchAction(&$row, $id) {
446 }
6a488035 447
e0ef6999
EM
448 /**
449 * @param $tables
450 */
00be9182 451 public static function tableNames(&$tables) {
0a71a7f7 452 if (isset($tables['civicrm_mailing_job'])) {
453 $tables['civicrm_mailing'] = $tables['civicrm_mailing'] ?? 1;
454 $tables['civicrm_mailing_recipients'] = $tables['civicrm_mailing_recipients'] ?? 1;
455 }
337750c9 456 }
6a488035
TO
457
458 /**
459 * Filter query results based on which contacts do (not) have a particular mailing event in their history.
460 *
461 * @param $query
462 * @param $values
100fef9d
CW
463 * @param string $tableName
464 * @param string $fieldName
6a488035
TO
465 * @param $fieldTitle
466 *
77b97be7 467 * @param $valueTitles
6a488035 468 */
00be9182 469 public static function mailingEventQueryBuilder(&$query, &$values, $tableName, $fieldName, $fieldTitle, &$valueTitles) {
6a488035
TO
470 list($name, $op, $value, $grouping, $wildcard) = $values;
471
472 if (empty($value) || $value == 'A') {
473 // don't do any filtering
474 return;
475 }
476
477 if ($value == 'Y') {
478 $query->_where[$grouping][] = $tableName . ".id is not null ";
479 }
480 elseif ($value == 'N') {
481 $query->_where[$grouping][] = $tableName . ".id is null ";
482 }
483
111b2847 484 if (is_array($value)) {
485 $query->_where[$grouping][] = "$tableName.$fieldName $op (" . implode(',', $value) . ")";
86bfa4f6 486 $query->_qill[$grouping][] = "$fieldTitle $op " . implode(', ', array_intersect_key($valueTitles, array_flip($value)));
111b2847 487 }
488 else {
489 $query->_qill[$grouping][] = $fieldTitle . ' - ' . $valueTitles[$value];
490 }
491
dd879954 492 $query->_tables['civicrm_mailing'] = $query->_whereTables['civicrm_mailing'] = 1;
335038eb 493 $query->_tables['civicrm_mailing_job'] = $query->_whereTables['civicrm_mailing_job'] = 1;
6a488035 494 $query->_tables['civicrm_mailing_event_queue'] = $query->_whereTables['civicrm_mailing_event_queue'] = 1;
335038eb 495 $query->_tables['civicrm_mailing_recipients'] = $query->_whereTables['civicrm_mailing_recipients'] = 1;
6a488035
TO
496 $query->_tables[$tableName] = $query->_whereTables[$tableName] = 1;
497 }
96025800 498
6a488035 499}