Merge pull request #6523 from eileenmcnaughton/CRM-16955
[civicrm-core.git] / CRM / Contact / Form / Search / Custom / Group.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
7e9e8871 4 | CiviCRM version 4.7 |
6a488035 5 +--------------------------------------------------------------------+
e7112fa7 6 | Copyright CiviCRM LLC (c) 2004-2015 |
6a488035
TO
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 +--------------------------------------------------------------------+
d25dd0ee 26 */
6a488035
TO
27
28/**
29 *
30 * @package CRM
e7112fa7 31 * @copyright CiviCRM LLC (c) 2004-2015
6a488035
TO
32 * $Id$
33 *
34 */
96025800 35class CRM_Contact_Form_Search_Custom_Group extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
6a488035
TO
36
37 protected $_formValues;
38
39 protected $_tableName = NULL;
40
41 protected $_where = ' (1) ';
42
43 protected $_aclFrom = NULL;
44 protected $_aclWhere = NULL;
45
86538308
EM
46 /**
47 * @param $formValues
48 */
00be9182 49 public function __construct(&$formValues) {
6a488035
TO
50 $this->_formValues = $formValues;
51 $this->_columns = array(
7b99ead3 52 ts('Contact ID') => 'contact_id',
6a488035
TO
53 ts('Contact Type') => 'contact_type',
54 ts('Name') => 'sort_name',
55 ts('Group Name') => 'gname',
56 ts('Tag Name') => 'tname',
57 );
58
59 $this->_includeGroups = CRM_Utils_Array::value('includeGroups', $this->_formValues, array());
60 $this->_excludeGroups = CRM_Utils_Array::value('excludeGroups', $this->_formValues, array());
61 $this->_includeTags = CRM_Utils_Array::value('includeTags', $this->_formValues, array());
62 $this->_excludeTags = CRM_Utils_Array::value('excludeTags', $this->_formValues, array());
63
64 //define variables
65 $this->_allSearch = FALSE;
353ffa53
TO
66 $this->_groups = FALSE;
67 $this->_tags = FALSE;
68 $this->_andOr = CRM_Utils_Array::value('andOr', $this->_formValues);
6a488035
TO
69 //make easy to check conditions for groups and tags are
70 //selected or it is empty search
71 if (empty($this->_includeGroups) && empty($this->_excludeGroups) &&
72 empty($this->_includeTags) && empty($this->_excludeTags)
73 ) {
74 //empty search
75 $this->_allSearch = TRUE;
76 }
77
78 $this->_groups = (!empty($this->_includeGroups) || !empty($this->_excludeGroups));
79
80 $this->_tags = (!empty($this->_includeTags) || !empty($this->_excludeTags));
81 }
82
00be9182 83 public function __destruct() {
27d88bc7 84 // mysql drops the tables when connection is terminated
6a488035
TO
85 // cannot drop tables here, since the search might be used
86 // in other parts after the object is destroyed
87 }
88
86538308 89 /**
11cac306 90 * @param CRM_Core_Form $form
86538308 91 */
00be9182 92 public function buildForm(&$form) {
6a488035
TO
93
94 $this->setTitle(ts('Include / Exclude Search'));
95
24431f7b 96 $groups = CRM_Core_PseudoConstant::nestedGroup();
6a488035 97
cd43c5e3 98 $tags = CRM_Core_PseudoConstant::get('CRM_Core_DAO_EntityTag', 'tag_id', array('onlyActive' => FALSE));
6a488035
TO
99 if (count($groups) == 0 || count($tags) == 0) {
100 CRM_Core_Session::setStatus(ts("At least one Group and Tag must be present for Custom Group / Tag search."), ts('Missing Group/Tag'));
101 $url = CRM_Utils_System::url('civicrm/contact/search/custom/list', 'reset=1');
102 CRM_Utils_System::redirect($url);
103 }
104
11cac306
CW
105 $select2style = array(
106 'multiple' => TRUE,
107 'style' => 'width: 100%; max-width: 60em;',
108 'class' => 'crm-select2',
109 'placeholder' => ts('- select -'),
6a488035
TO
110 );
111
11cac306
CW
112 $form->add('select', 'includeGroups',
113 ts('Include Group(s)'),
114 $groups,
115 FALSE,
116 $select2style
117 );
118
119 $form->add('select', 'excludeGroups',
120 ts('Exclude Group(s)'),
121 $groups,
122 FALSE,
123 $select2style
6a488035
TO
124 );
125
126 $andOr = array(
127 '1' => ts('Show contacts that meet the Groups criteria AND the Tags criteria'),
128 '0' => ts('Show contacts that meet the Groups criteria OR the Tags criteria'),
129 );
29ba7662 130 $form->addRadio('andOr', ts('AND/OR'), $andOr, NULL, '<br />', TRUE);
6a488035 131
11cac306
CW
132 $form->add('select', 'includeTags',
133 ts('Include Tag(s)'),
134 $tags,
135 FALSE,
136 $select2style
6a488035
TO
137 );
138
11cac306
CW
139 $form->add('select', 'excludeTags',
140 ts('Exclude Tag(s)'),
141 $tags,
142 FALSE,
143 $select2style
6a488035
TO
144 );
145
6a488035
TO
146 /**
147 * if you are using the standard template, this array tells the template what elements
148 * are part of the search criteria
149 */
150 $form->assign('elements', array('includeGroups', 'excludeGroups', 'andOr', 'includeTags', 'excludeTags'));
151 }
152
86538308 153 /**
d424ffde 154 * Set search form field defaults here.
86538308
EM
155 * @return array
156 */
00be9182 157 public function setDefaultValues() {
481a74f4 158 $defaults = array('andOr' => '1');
29ba7662
DL
159
160 if (!empty($this->_formValues)) {
161 $defaults['andOr'] = CRM_Utils_Array::value('andOr', $this->_formValues, '1');
162
163 $defaults['includeGroups'] = CRM_Utils_Array::value('includeGroups', $this->_formValues);
164 $defaults['excludeGroups'] = CRM_Utils_Array::value('excludeGroups', $this->_formValues);
f8baa2bb
BS
165
166 $defaults['includeTags'] = CRM_Utils_Array::value('includeTags', $this->_formValues);
167 $defaults['excludeTags'] = CRM_Utils_Array::value('excludeTags', $this->_formValues);
29ba7662
DL
168 }
169
170 return $defaults;
6a488035
TO
171 }
172
86538308
EM
173 /**
174 * @param int $offset
175 * @param int $rowcount
e60f24eb 176 * @param NULL $sort
86538308
EM
177 * @param bool $includeContactIDs
178 * @param bool $justIDs
179 *
180 * @return string
181 */
acb1052e 182 public function all(
6a488035
TO
183 $offset = 0, $rowcount = 0, $sort = NULL,
184 $includeContactIDs = FALSE, $justIDs = FALSE
185 ) {
186
187 if ($justIDs) {
188 $selectClause = "contact_a.id as contact_id";
189 }
190 else {
191 $selectClause = "contact_a.id as contact_id,
192 contact_a.contact_type as contact_type,
193 contact_a.sort_name as sort_name";
194
195 //distinguish column according to user selection
196 if (($this->_includeGroups && !$this->_includeTags)) {
197 unset($this->_columns['Tag Name']);
198 $selectClause .= ", GROUP_CONCAT(DISTINCT group_names ORDER BY group_names ASC ) as gname";
199 }
200 elseif ($this->_includeTags && (!$this->_includeGroups)) {
201 unset($this->_columns['Group Name']);
202 $selectClause .= ", GROUP_CONCAT(DISTINCT tag_names ORDER BY tag_names ASC ) as tname";
203 }
204 elseif (!empty($this->_includeTags) && !empty($this->_includeGroups)) {
205 $selectClause .= ", GROUP_CONCAT(DISTINCT group_names ORDER BY group_names ASC ) as gname , GROUP_CONCAT(DISTINCT tag_names ORDER BY tag_names ASC ) as tname";
206 }
207 else {
208 unset($this->_columns['Tag Name']);
209 unset($this->_columns['Group Name']);
210 }
211 }
212
213 $from = $this->from();
214
215 $where = $this->where($includeContactIDs);
216
217 if (!$justIDs && !$this->_allSearch) {
218 $groupBy = " GROUP BY contact_a.id";
219 }
220 else {
221 // CRM-10850
222 // we do this since this if stmt is called by the smart group part of the code
223 // adding a groupBy clause and saving it as a smart group messes up the query and
224 // bad things happen
225 // andrew hunt seemed to have rewritten this piece when he worked on this search
e60f24eb 226 $groupBy = NULL;
6a488035
TO
227 }
228
229 $sql = "SELECT $selectClause $from WHERE $where $groupBy";
230
231 // Define ORDER BY for query in $sort, with default value
232 if (!$justIDs) {
233 if (!empty($sort)) {
234 if (is_string($sort)) {
21d32567 235 $sort = CRM_Utils_Type::escape($sort, 'String');
6a488035
TO
236 $sql .= " ORDER BY $sort ";
237 }
238 else {
239 $sql .= " ORDER BY " . trim($sort->orderBy());
240 }
241 }
242 else {
243 $sql .= " ORDER BY contact_id ASC";
244 }
245 }
7c34ab11 246 else {
247 $sql .= " ORDER BY contact_a.id ASC";
248 }
6a488035
TO
249
250 if ($offset >= 0 && $rowcount > 0) {
251 $sql .= " LIMIT $offset, $rowcount ";
252 }
253
254 return $sql;
255 }
256
86538308
EM
257 /**
258 * @return string
259 * @throws Exception
260 */
00be9182 261 public function from() {
6a488035
TO
262
263 $iGroups = $xGroups = $iTags = $xTags = 0;
264
265 //define table name
266 $randomNum = md5(uniqid());
267 $this->_tableName = "civicrm_temp_custom_{$randomNum}";
268
269 //block for Group search
270 $smartGroup = array();
271 if ($this->_groups || $this->_allSearch) {
272 $group = new CRM_Contact_DAO_Group();
273 $group->is_active = 1;
274 $group->find();
275 while ($group->fetch()) {
276 $allGroups[] = $group->id;
277 if ($group->saved_search_id) {
278 $smartGroup[$group->saved_search_id] = $group->id;
279 }
280 }
281 $includedGroups = implode(',', $allGroups);
282
283 if (!empty($this->_includeGroups)) {
284 $iGroups = implode(',', $this->_includeGroups);
285 }
286 else {
287 //if no group selected search for all groups
288 $iGroups = NULL;
289 }
290 if (is_array($this->_excludeGroups)) {
291 $xGroups = implode(',', $this->_excludeGroups);
292 }
293 else {
294 $xGroups = 0;
295 }
296
ceefef9f 297 $sql = "CREATE TEMPORARY TABLE Xg_{$this->_tableName} ( contact_id int primary key) ENGINE=MyISAM";
6a488035
TO
298 CRM_Core_DAO::executeQuery($sql);
299
300 //used only when exclude group is selected
301 if ($xGroups != 0) {
302 $excludeGroup = "INSERT INTO Xg_{$this->_tableName} ( contact_id )
303 SELECT DISTINCT civicrm_group_contact.contact_id
304 FROM civicrm_group_contact, civicrm_contact
305 WHERE
306 civicrm_contact.id = civicrm_group_contact.contact_id AND
307 civicrm_group_contact.status = 'Added' AND
308 civicrm_group_contact.group_id IN( {$xGroups})";
309
310 CRM_Core_DAO::executeQuery($excludeGroup);
311
312 //search for smart group contacts
313 foreach ($this->_excludeGroups as $keys => $values) {
314 if (in_array($values, $smartGroup)) {
811a3ea4
DL
315 $ssGroup = new CRM_Contact_DAO_Group();
316 $ssGroup->id = $values;
317 if (!$ssGroup->find(TRUE)) {
318 CRM_Core_Error::fatal();
319 }
320 CRM_Contact_BAO_GroupContactCache::load($ssGroup);
321
322 $smartSql = "
323SELECT gcc.contact_id
324FROM civicrm_group_contact_cache gcc
325WHERE gcc.group_id = {$ssGroup->id}
326";
6a488035 327 $smartGroupQuery = " INSERT IGNORE INTO Xg_{$this->_tableName}(contact_id) $smartSql";
6a488035
TO
328 CRM_Core_DAO::executeQuery($smartGroupQuery);
329 }
330 }
331 }
332
333 $sql = "CREATE TEMPORARY TABLE Ig_{$this->_tableName} ( id int PRIMARY KEY AUTO_INCREMENT,
334 contact_id int,
ceefef9f 335 group_names varchar(64)) ENGINE=MyISAM";
6a488035
TO
336
337 CRM_Core_DAO::executeQuery($sql);
338
339 if ($iGroups) {
340 $includeGroup = "INSERT INTO Ig_{$this->_tableName} (contact_id, group_names)
341 SELECT civicrm_contact.id as contact_id, civicrm_group.title as group_name
342 FROM civicrm_contact
343 INNER JOIN civicrm_group_contact
344 ON civicrm_group_contact.contact_id = civicrm_contact.id
345 LEFT JOIN civicrm_group
346 ON civicrm_group_contact.group_id = civicrm_group.id";
347 }
348 else {
349 $includeGroup = "INSERT INTO Ig_{$this->_tableName} (contact_id, group_names)
350 SELECT civicrm_contact.id as contact_id, ''
351 FROM civicrm_contact";
352 }
6a488035
TO
353 //used only when exclude group is selected
354 if ($xGroups != 0) {
355 $includeGroup .= " LEFT JOIN Xg_{$this->_tableName}
356 ON civicrm_contact.id = Xg_{$this->_tableName}.contact_id";
357 }
358
359 if ($iGroups) {
360 $includeGroup .= " WHERE
361 civicrm_group_contact.status = 'Added' AND
362 civicrm_group_contact.group_id IN($iGroups)";
363 }
364 else {
365 $includeGroup .= " WHERE ( 1 ) ";
366 }
367
368 //used only when exclude group is selected
369 if ($xGroups != 0) {
370 $includeGroup .= " AND Xg_{$this->_tableName}.contact_id IS null";
371 }
372
373 CRM_Core_DAO::executeQuery($includeGroup);
374
375 //search for smart group contacts
376
377 foreach ($this->_includeGroups as $keys => $values) {
378 if (in_array($values, $smartGroup)) {
811a3ea4
DL
379 $ssGroup = new CRM_Contact_DAO_Group();
380 $ssGroup->id = $values;
381 if (!$ssGroup->find(TRUE)) {
382 CRM_Core_Error::fatal();
383 }
384 CRM_Contact_BAO_GroupContactCache::load($ssGroup);
6a488035 385
811a3ea4
DL
386 $smartSql = "
387SELECT gcc.contact_id
388FROM civicrm_group_contact_cache gcc
389WHERE gcc.group_id = {$ssGroup->id}
390";
6a488035
TO
391
392 //used only when exclude group is selected
393 if ($xGroups != 0) {
811a3ea4 394 $smartSql .= " AND gcc.contact_id NOT IN (SELECT contact_id FROM Xg_{$this->_tableName})";
6a488035
TO
395 }
396
397 $smartGroupQuery = " INSERT IGNORE INTO Ig_{$this->_tableName}(contact_id)
398 $smartSql";
399
400 CRM_Core_DAO::executeQuery($smartGroupQuery);
401 $insertGroupNameQuery = "UPDATE IGNORE Ig_{$this->_tableName}
402 SET group_names = (SELECT title FROM civicrm_group
403 WHERE civicrm_group.id = $values)
404 WHERE Ig_{$this->_tableName}.contact_id IS NOT NULL
405 AND Ig_{$this->_tableName}.group_names IS NULL";
406 CRM_Core_DAO::executeQuery($insertGroupNameQuery);
407 }
408 }
409 }
410 //group contact search end here;
411
412 //block for Tags search
413 if ($this->_tags || $this->_allSearch) {
414 //find all tags
415 $tag = new CRM_Core_DAO_Tag();
416 $tag->is_active = 1;
417 $tag->find();
418 while ($tag->fetch()) {
419 $allTags[] = $tag->id;
420 }
421 $includedTags = implode(',', $allTags);
422
423 if (!empty($this->_includeTags)) {
424 $iTags = implode(',', $this->_includeTags);
425 }
426 else {
427 //if no group selected search for all groups
428 $iTags = NULL;
429 }
430 if (is_array($this->_excludeTags)) {
431 $xTags = implode(',', $this->_excludeTags);
432 }
433 else {
434 $xTags = 0;
435 }
436
ceefef9f 437 $sql = "CREATE TEMPORARY TABLE Xt_{$this->_tableName} ( contact_id int primary key) ENGINE=MyISAM";
6a488035
TO
438 CRM_Core_DAO::executeQuery($sql);
439
440 //used only when exclude tag is selected
441 if ($xTags != 0) {
442 $excludeTag = "INSERT INTO Xt_{$this->_tableName} ( contact_id )
443 SELECT DISTINCT civicrm_entity_tag.entity_id
444 FROM civicrm_entity_tag, civicrm_contact
445 WHERE
446 civicrm_entity_tag.entity_table = 'civicrm_contact' AND
447 civicrm_contact.id = civicrm_entity_tag.entity_id AND
448 civicrm_entity_tag.tag_id IN( {$xTags})";
449
450 CRM_Core_DAO::executeQuery($excludeTag);
451 }
452
453 $sql = "CREATE TEMPORARY TABLE It_{$this->_tableName} ( id int PRIMARY KEY AUTO_INCREMENT,
454 contact_id int,
ceefef9f 455 tag_names varchar(64)) ENGINE=MyISAM";
6a488035
TO
456
457 CRM_Core_DAO::executeQuery($sql);
458
459 if ($iTags) {
460 $includeTag = "INSERT INTO It_{$this->_tableName} (contact_id, tag_names)
461 SELECT civicrm_contact.id as contact_id, civicrm_tag.name as tag_name
462 FROM civicrm_contact
463 INNER JOIN civicrm_entity_tag
464 ON ( civicrm_entity_tag.entity_table = 'civicrm_contact' AND
465 civicrm_entity_tag.entity_id = civicrm_contact.id )
466 LEFT JOIN civicrm_tag
467 ON civicrm_entity_tag.tag_id = civicrm_tag.id";
468 }
469 else {
470 $includeTag = "INSERT INTO It_{$this->_tableName} (contact_id, tag_names)
471 SELECT civicrm_contact.id as contact_id, ''
472 FROM civicrm_contact";
473 }
474
475 //used only when exclude tag is selected
476 if ($xTags != 0) {
477 $includeTag .= " LEFT JOIN Xt_{$this->_tableName}
478 ON civicrm_contact.id = Xt_{$this->_tableName}.contact_id";
479 }
480 if ($iTags) {
481 $includeTag .= " WHERE civicrm_entity_tag.tag_id IN($iTags)";
482 }
483 else {
484 $includeTag .= " WHERE ( 1 ) ";
485 }
486
487 //used only when exclude tag is selected
488 if ($xTags != 0) {
489 $includeTag .= " AND Xt_{$this->_tableName}.contact_id IS null";
490 }
491
492 CRM_Core_DAO::executeQuery($includeTag);
493 }
494
495 $from = " FROM civicrm_contact contact_a";
496
497 /*
498 * CRM-10850 / CRM-10848
499 * If we use include / exclude groups as smart groups for ACL's having the below causes
500 * a cycle which messes things up. Hence commenting out for now
501 * $this->buildACLClause('contact_a');
502 */
503
504 /*
95d4473f
DL
505 * check the situation and set booleans
506 */
6a488035 507 $Ig = ($iGroups != 0);
6a488035 508 $It = ($iTags != 0);
6a488035 509 $Xg = ($xGroups != 0);
6a488035
TO
510 $Xt = ($xTags != 0);
511
512 //PICK UP FROM HERE
513 if (!$this->_groups && !$this->_tags) {
514 $this->_andOr = 1;
515 }
516
517 /*
95d4473f
DL
518 * Set from statement depending on array sel
519 */
6a488035
TO
520 $whereitems = array();
521 foreach (array('Ig', 'It') as $inc) {
522 if ($this->_andOr == 1) {
523 if ($$inc) {
524 $from .= " INNER JOIN {$inc}_{$this->_tableName} temptable$inc ON (contact_a.id = temptable$inc.contact_id)";
525 }
526 }
527 else {
528 if ($$inc) {
529 $from .= " LEFT JOIN {$inc}_{$this->_tableName} temptable$inc ON (contact_a.id = temptable$inc.contact_id)";
530 }
531 }
532 if ($$inc) {
533 $whereitems[] = "temptable$inc.contact_id IS NOT NULL";
534 }
535 }
536 $this->_where = $whereitems ? "(" . implode(' OR ', $whereitems) . ')' : '(1)';
537 foreach (array('Xg', 'Xt') as $exc) {
538 if ($$exc) {
539 $from .= " LEFT JOIN {$exc}_{$this->_tableName} temptable$exc ON (contact_a.id = temptable$exc.contact_id)";
540 $this->_where .= " AND temptable$exc.contact_id IS NULL";
541 }
542 }
543
544 $from .= " LEFT JOIN civicrm_email ON ( contact_a.id = civicrm_email.contact_id AND ( civicrm_email.is_primary = 1 OR civicrm_email.is_bulkmail = 1 ) ) {$this->_aclFrom}";
545
546 if ($this->_aclWhere) {
547 $this->_where .= " AND {$this->_aclWhere} ";
548 }
549
550 // also exclude all contacts that are deleted
551 // CRM-11627
552 $this->_where .= " AND (contact_a.is_deleted != 1) ";
553
554 return $from;
555 }
556
86538308
EM
557 /**
558 * @param bool $includeContactIDs
559 *
560 * @return string
561 */
00be9182 562 public function where($includeContactIDs = FALSE) {
6a488035
TO
563 if ($includeContactIDs) {
564 $contactIDs = array();
565
566 foreach ($this->_formValues as $id => $value) {
567 if ($value &&
568 substr($id, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX
569 ) {
570 $contactIDs[] = substr($id, CRM_Core_Form::CB_PREFIX_LEN);
571 }
572 }
573
574 if (!empty($contactIDs)) {
575 $contactIDs = implode(', ', $contactIDs);
576 $clauses[] = "contact_a.id IN ( $contactIDs )";
577 }
578 $where = "{$this->_where} AND " . implode(' AND ', $clauses);
579 }
580 else {
581 $where = $this->_where;
582 }
583
584 return $where;
585 }
586
587 /*
c490a46a
CW
588 * Functions below generally don't need to be modified
589 */
546b78fa 590
86538308 591 /**
546b78fa 592 * @inheritDoc
86538308 593 */
00be9182 594 public function count() {
6a488035
TO
595 $sql = $this->all();
596
597 $dao = CRM_Core_DAO::executeQuery($sql);
598 return $dao->N;
599 }
600
86538308
EM
601 /**
602 * @param int $offset
603 * @param int $rowcount
e60f24eb 604 * @param NULL $sort
86538308
EM
605 * @param bool $returnSQL
606 *
607 * @return string
608 */
00be9182 609 public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = FALSE) {
6a488035
TO
610 return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
611 }
612
86538308
EM
613 /**
614 * @return array
615 */
00be9182 616 public function &columns() {
6a488035
TO
617 return $this->_columns;
618 }
619
86538308 620 /**
e60f24eb 621 * @return NULL
86538308 622 */
00be9182 623 public function summary() {
6a488035
TO
624 return NULL;
625 }
626
86538308
EM
627 /**
628 * @return string
629 */
00be9182 630 public function templateFile() {
6a488035
TO
631 return 'CRM/Contact/Form/Search/Custom.tpl';
632 }
633
86538308
EM
634 /**
635 * @param $title
636 */
00be9182 637 public function setTitle($title) {
6a488035
TO
638 if ($title) {
639 CRM_Utils_System::setTitle($title);
640 }
641 else {
642 CRM_Utils_System::setTitle(ts('Search'));
643 }
644 }
645
86538308
EM
646 /**
647 * @param string $tableAlias
648 */
00be9182 649 public function buildACLClause($tableAlias = 'contact') {
6a488035
TO
650 list($this->_aclFrom, $this->_aclWhere) = CRM_Contact_BAO_Contact_Permission::cacheClause($tableAlias);
651 }
96025800 652
6a488035 653}