copyright and version fixes
[civicrm-core.git] / CRM / Contact / Form / Search / Custom / FullText.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
232624b1 4 | CiviCRM version 4.4 |
6a488035
TO
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
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-2013
32 * $Id$
33 *
34 */
35class CRM_Contact_Form_Search_Custom_FullText implements CRM_Contact_Form_Search_Interface {
36
37 const LIMIT = 10;
38
39 protected $_formValues;
40
41 protected $_columns;
42
43 protected $_text = NULL;
44
45 protected $_textID = NULL;
46
47 protected $_table = NULL;
48
49 protected $_tableName = NULL;
50
51 protected $_entityIDTableName = NULL;
52
53 protected $_tableFields = NULL;
54
55 protected $_limitClause = NULL;
56
57 protected $_limitRowClause = NULL;
58
59 protected $_limitDetailClause = NULL;
60
400c14ba 61 protected $_limitNumber = 10;
6a488035
TO
62 protected $_limitNumberPlus1 = 11; // this should be one more than self::LIMIT
63
64 protected $_foundRows = array();
65
66 function __construct(&$formValues) {
6a488035
TO
67 $this->_text = CRM_Utils_Array::value('text', $formValues);
68 $this->_table = CRM_Utils_Array::value('table', $formValues);
69
70 if (!$this->_text) {
71 $this->_text = CRM_Utils_Request::retrieve('text', 'String', CRM_Core_DAO::$_nullObject);
72 if ($this->_text) {
73 $this->_text = trim($this->_text);
74 $formValues['text'] = $this->_text;
75 }
76 }
77
78 if (!$this->_table) {
79 $this->_table = CRM_Utils_Request::retrieve('table', 'String', CRM_Core_DAO::$_nullObject);
80 if ($this->_table) {
81 $formValues['table'] = $this->_table;
82 }
83 }
84
70ec7bcc 85 // fix text to include wild card characters at beginning and end
6a488035
TO
86 if ($this->_text) {
87 if (is_numeric($this->_text)) {
88 $this->_textID = $this->_text;
89 }
90
91 $strtolower = function_exists('mb_strtolower') ? 'mb_strtolower' : 'strtolower';
92 $this->_text = $strtolower(CRM_Core_DAO::escapeString($this->_text));
93 if (strpos($this->_text, '%') === FALSE) {
94 $this->_text = "'%{$this->_text}%'";
95 }
96 else {
97 $this->_text = "'{$this->_text}'";
98 }
99 }
100 else {
101 $this->_text = "'%'";
102 }
103
104 if (!$this->_table) {
105 $this->_limitClause = " LIMIT {$this->_limitNumberPlus1}";
106 $this->_limitRowClause = $this->_limitDetailClause = " LIMIT {$this->_limitNumber}";
107 }
108 else {
109 // when there is table specified, we would like to use the pager. But since
110 // 1. this custom search has slightly different structure ,
111 // 2. we are in constructor right now,
112 // we 'll use a small hack -
7278c86e
BS
113 $rowCount = CRM_Utils_Array::value('crmRowCount', $_REQUEST, CRM_Utils_Pager::ROWCOUNT);
114 $pageId = CRM_Utils_Array::value('crmPID', $_REQUEST, 1);
6a488035
TO
115 $offset = ($pageId - 1) * $rowCount;
116 $this->_limitClause = NULL;
117 $this->_limitRowClause = " LIMIT $rowCount";
118 $this->_limitDetailClause = " LIMIT $offset, $rowCount";
119 }
82de5f35 120
121 $this->_formValues = $formValues;
6a488035
TO
122 }
123
124 function __destruct() {
125 }
126
127 function initialize() {
128 static $initialized = FALSE;
129
130 if (!$initialized) {
131 $initialized = TRUE;
132
133 $this->buildTempTable();
134
135 $this->fillTable();
136 }
137 }
138
139 function buildTempTable() {
140 $randomNum = md5(uniqid());
141 $this->_tableName = "civicrm_temp_custom_details_{$randomNum}";
142
143 $this->_tableFields = array(
144 'id' => 'int unsigned NOT NULL AUTO_INCREMENT',
145 'table_name' => 'varchar(16)',
146 'contact_id' => 'int unsigned',
147 'sort_name' => 'varchar(128)',
148 'assignee_contact_id' => 'int unsigned',
149 'assignee_sort_name' => 'varchar(128)',
150 'target_contact_id' => 'int unsigned',
151 'target_sort_name' => 'varchar(128)',
152 'activity_id' => 'int unsigned',
153 'activity_type_id' => 'int unsigned',
91da6cd5 154 'record_type' => 'varchar(16)',
6a488035
TO
155 'client_id' => 'int unsigned',
156 'case_id' => 'int unsigned',
157 'case_start_date' => 'datetime',
158 'case_end_date' => 'datetime',
159 'case_is_deleted' => 'tinyint',
160 'subject' => 'varchar(255)',
161 'details' => 'varchar(255)',
162 'contribution_id' => 'int unsigned',
400c14ba 163 'financial_type' => 'varchar(255)',
6a488035
TO
164 'contribution_page' => 'varchar(255)',
165 'contribution_receive_date' => 'datetime',
166 'contribution_total_amount' => 'decimal(20,2)',
167 'contribution_trxn_Id' => 'varchar(255)',
168 'contribution_source' => 'varchar(255)',
169 'contribution_status' => 'varchar(255)',
170 'contribution_check_number' => 'varchar(255)',
171 'participant_id' => 'int unsigned',
172 'event_title' => 'varchar(255)',
173 'participant_fee_level' => 'varchar(255)',
174 'participant_fee_amount' => 'int unsigned',
175 'participant_source' => 'varchar(255)',
176 'participant_register_date' => 'datetime',
177 'participant_status' => 'varchar(255)',
178 'participant_role' => 'varchar(255)',
179 'membership_id' => 'int unsigned',
180 'membership_fee' => 'int unsigned',
181 'membership_type' => 'varchar(255)',
182 'membership_start_date' => 'datetime',
183 'membership_end_date' => 'datetime',
184 'membership_source' => 'varchar(255)',
185 'membership_status' => 'varchar(255)',
186 );
187
188 $sql = "
189CREATE TEMPORARY TABLE {$this->_tableName} (
190";
191
192 foreach ($this->_tableFields as $name => $desc) {
193 $sql .= "$name $desc,\n";
194 }
195
196 $sql .= "
197 PRIMARY KEY ( id )
198) ENGINE=HEAP DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
199";
200 CRM_Core_DAO::executeQuery($sql);
201
202 $this->_entityIDTableName = "civicrm_temp_custom_entityID_{$randomNum}";
203 $sql = "
204CREATE TEMPORARY TABLE {$this->_entityIDTableName} (
205 id int unsigned NOT NULL AUTO_INCREMENT,
206 entity_id int unsigned NOT NULL,
207
208 UNIQUE INDEX unique_entity_id ( entity_id ),
209 PRIMARY KEY ( id )
210) ENGINE=HEAP DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci
211";
212 CRM_Core_DAO::executeQuery($sql);
213 }
214
215 function fillTable() {
216 $config = CRM_Core_Config::singleton();
217
218 if ((!$this->_table || $this->_table == 'Contact')) {
219 $this->fillContact();
220 }
221
222 if ((!$this->_table || $this->_table == 'Activity') &&
223 CRM_Core_Permission::check('view all activities')
224 ) {
225 $this->fillActivity();
226 }
227
228 if ((!$this->_table || $this->_table == 'Case') &&
229 in_array('CiviCase', $config->enableComponents)
230 ) {
231 $this->fillCase();
232 }
233
234 if ((!$this->_table || $this->_table == 'Contribution') &&
235 in_array('CiviContribute', $config->enableComponents) &&
236 CRM_Core_Permission::check('access CiviContribute')
237 ) {
238 $this->fillContribution();
239 }
240
241 if ((!$this->_table || $this->_table == 'Participant') &&
242 (in_array('CiviEvent', $config->enableComponents) &&
243 CRM_Core_Permission::check('view event participants')
244 )
245 ) {
246 $this->fillParticipant();
247 }
248
249 if ((!$this->_table || $this->_table == 'Membership') &&
250 in_array('CiviMember', $config->enableComponents) &&
251 CRM_Core_Permission::check('access CiviMember')
252 ) {
253 $this->fillMembership();
254 }
255
256 $this->filterACLContacts();
257 }
258
259 function filterACLContacts() {
260 if (CRM_Core_Permission::check('view all contacts')) {
261 CRM_Core_DAO::executeQuery("DELETE FROM {$this->_tableName} WHERE contact_id IN (SELECT id FROM civicrm_contact WHERE is_deleted = 1)");
262 return;
263 }
264
265 $session = CRM_Core_Session::singleton();
266 $contactID = $session->get('userID');
267 if (!$contactID) {
268 $contactID = 0;
269 }
270
271 CRM_Contact_BAO_Contact_Permission::cache($contactID);
272
273 $params = array(1 => array($contactID, 'Integer'));
274
275 $sql = "
276DELETE t.*
277FROM {$this->_tableName} t
278WHERE NOT EXISTS ( SELECT c.id
279 FROM civicrm_acl_contact_cache c
280 WHERE c.user_id = %1 AND t.contact_id = c.contact_id )
281";
282 CRM_Core_DAO::executeQuery($sql, $params);
283
284 $sql = "
285DELETE t.*
286FROM {$this->_tableName} t
287WHERE t.table_name = 'Activity' AND
288 NOT EXISTS ( SELECT c.id
289 FROM civicrm_acl_contact_cache c
290 WHERE c.user_id = %1 AND ( t.target_contact_id = c.contact_id OR t.target_contact_id IS NULL ) )
291";
292 CRM_Core_DAO::executeQuery($sql, $params);
293
294 $sql = "
295DELETE t.*
296FROM {$this->_tableName} t
297WHERE t.table_name = 'Activity' AND
298 NOT EXISTS ( SELECT c.id
299 FROM civicrm_acl_contact_cache c
300 WHERE c.user_id = %1 AND ( t.assignee_contact_id = c.contact_id OR t.assignee_contact_id IS NULL ) )
301";
302 CRM_Core_DAO::executeQuery($sql, $params);
303 }
304
400c14ba 305 function fillCustomInfo(&$tables, $extends) {
6a488035
TO
306 $sql = "
307SELECT cg.table_name, cf.column_name
308FROM civicrm_custom_group cg
309INNER JOIN civicrm_custom_field cf ON cf.custom_group_id = cg.id
310WHERE cg.extends IN $extends
311AND cg.is_active = 1
312AND cf.is_active = 1
313AND cf.is_searchable = 1
314AND cf.html_type IN ( 'Text', 'TextArea', 'RichTextEditor' )
315";
316
317 $dao = CRM_Core_DAO::executeQuery($sql);
318 while ($dao->fetch()) {
319 if (!array_key_exists($dao->table_name, $tables)) {
320 $tables[$dao->table_name] = array(
321 'id' => 'entity_id',
322 'fields' => array(),
323 );
324 }
325 $tables[$dao->table_name]['fields'][$dao->column_name] = NULL;
326 }
327 }
328
329 function runQueries(&$tables) {
330 $sql = "TRUNCATE {$this->_entityIDTableName}";
331 CRM_Core_DAO::executeQuery($sql);
332
333 $maxRowCount = 0;
334 foreach ($tables as $tableName => $tableValues) {
335 if ($tableName == 'final') {
336 continue;
337 }
400c14ba 338 else {
339 if ($tableName == 'sql') {
340 foreach ($tableValues as $sqlStatement) {
341 $sql = "
6a488035
TO
342REPLACE INTO {$this->_entityIDTableName} ( entity_id )
343$sqlStatement
344{$this->_limitClause}
345";
400c14ba 346 CRM_Core_DAO::executeQuery($sql);
347 }
6a488035 348 }
400c14ba 349 else {
350 $clauses = array();
6a488035 351
400c14ba 352 foreach ($tableValues['fields'] as $fieldName => $fieldType) {
353 if ($fieldType == 'Int') {
354 if ($this->_textID) {
355 $clauses[] = "$fieldName = {$this->_textID}";
356 }
357 }
358 else {
359 $clauses[] = "$fieldName LIKE {$this->_text}";
6a488035
TO
360 }
361 }
6a488035 362
400c14ba 363 if (empty($clauses)) {
364 continue;
365 }
6a488035 366
400c14ba 367 $whereClause = implode(' OR ', $clauses);
6a488035 368
400c14ba 369 //resolve conflict between entity tables.
370 if ($tableName == 'civicrm_note' &&
371 $entityTable = CRM_Utils_Array::value('entity_table', $tableValues)
372 ) {
373 $whereClause .= " AND entity_table = '{$entityTable}'";
374 }
6a488035 375
400c14ba 376 $sql = "
6a488035
TO
377REPLACE INTO {$this->_entityIDTableName} ( entity_id )
378SELECT {$tableValues['id']}
379FROM $tableName
380WHERE ( $whereClause )
381AND {$tableValues['id']} IS NOT NULL
382GROUP BY {$tableValues['id']}
383{$this->_limitClause}
384";
400c14ba 385 CRM_Core_DAO::executeQuery($sql);
386 }
6a488035
TO
387 }
388 }
389
390 if (isset($tables['final'])) {
391 foreach ($tables['final'] as $sqlStatement) {
392 CRM_Core_DAO::executeQuery($sqlStatement);
393 }
394 }
395
396 $rowCount = "SELECT count(*) FROM {$this->_entityIDTableName}";
397 $tableKey = array_keys($tables);
398 $this->_foundRows[ucfirst(str_replace('civicrm_', '', $tableKey[0]))] =
399 CRM_Core_DAO::singleValueQuery($rowCount);
400 }
401
402 function fillContactIDs() {
403 $contactSQL = array();
404 $contactSQL[] = "
405SELECT et.entity_id
406FROM civicrm_entity_tag et
407INNER JOIN civicrm_tag t ON et.tag_id = t.id
408WHERE et.entity_table = 'civicrm_contact'
409AND et.tag_id = t.id
410AND t.name LIKE {$this->_text}
411GROUP BY et.entity_id
412";
413
414 // lets delete all the deceased contacts from the entityID box
415 // this allows us to keep numbers in sync
416 // when we have acl contacts, the situation gets even more murky
417 $final = array();
418 $final[] = "DELETE FROM {$this->_entityIDTableName} WHERE entity_id IN (SELECT id FROM civicrm_contact WHERE is_deleted = 1)";
419
420 $tables = array(
421 'civicrm_contact' => array(
422 'id' => 'id',
423 'fields' => array(
424 'sort_name' => NULL,
425 'nick_name' => NULL,
426 'display_name' => NULL,
427 ),
428 ),
429 'civicrm_address' => array(
430 'id' => 'contact_id',
431 'fields' => array(
432 'street_address' => NULL,
433 'city' => NULL,
434 'postal_code' => NULL,
435 ),
436 ),
437 'civicrm_email' => array(
438 'id' => 'contact_id',
439 'fields' => array('email' => NULL),
440 ),
441 'civicrm_phone' => array(
442 'id' => 'contact_id',
443 'fields' => array('phone' => NULL),
444 ),
445 'civicrm_note' => array(
446 'id' => 'entity_id',
447 'entity_table' => 'civicrm_contact',
448 'fields' => array(
449 'subject' => NULL,
450 'note' => NULL,
451 ),
452 ),
400c14ba 453 'sql' => $contactSQL,
6a488035
TO
454 'final' => $final,
455 );
456
457 // get the custom data info
458 $this->fillCustomInfo($tables,
459 "( 'Contact', 'Individual', 'Organization', 'Household' )"
460 );
461
462 $this->runQueries($tables);
463 }
464
465 function fillContact() {
466
467 $this->fillContactIDs();
468
469 //move data from entity table to detail table.
470 $this->moveEntityToDetail('Contact');
471 }
472
473 function fillActivityIDs() {
474 $contactSQL = array();
475
476 $contactSQL[] = "
477SELECT distinct ca.id
478FROM civicrm_activity ca
91da6cd5
DL
479INNER JOIN civicrm_activity_contact cat ON cat.activity_id = ca.id
480INNER JOIN civicrm_contact c ON cat.contact_id = c.id
481LEFT JOIN civicrm_email e ON cat.contact_id = e.contact_id
6a488035
TO
482LEFT JOIN civicrm_option_group og ON og.name = 'activity_type'
483LEFT JOIN civicrm_option_value ov ON ( ov.option_group_id = og.id )
484WHERE ( (c.sort_name LIKE {$this->_text} OR c.display_name LIKE {$this->_text}) OR
485 ( e.email LIKE {$this->_text} AND
486 ca.activity_type_id = ov.value AND
487 ov.name IN ('Inbound Email', 'Email') ) )
488AND (ca.is_deleted = 0 OR ca.is_deleted IS NULL)
489AND (c.is_deleted = 0 OR c.is_deleted IS NULL)
6a488035
TO
490";
491
492 $contactSQL[] = "
493SELECT et.entity_id
494FROM civicrm_entity_tag et
495INNER JOIN civicrm_tag t ON et.tag_id = t.id
496INNER JOIN civicrm_activity ca ON et.entity_id = ca.id
497WHERE et.entity_table = 'civicrm_activity'
498AND et.tag_id = t.id
499AND t.name LIKE {$this->_text}
500AND (ca.is_deleted = 0 OR ca.is_deleted IS NULL)
501GROUP BY et.entity_id
502";
503
504 $contactSQL[] = "
505SELECT distinct ca.id
506FROM civicrm_activity ca
507WHERE (ca.subject LIKE {$this->_text} OR ca.details LIKE {$this->_text})
508AND (ca.is_deleted = 0 OR ca.is_deleted IS NULL)
509";
510
511 $final = array();
6a488035
TO
512
513 $tables = array(
400c14ba 514 'civicrm_activity' => array('fields' => array()),
6a488035
TO
515 'sql' => $contactSQL,
516 'final' => $final,
517 );
518
519 $this->fillCustomInfo($tables, "( 'Activity' )");
520 $this->runQueries($tables);
521 }
522
523 function fillActivity() {
524
525 $this->fillActivityIDs();
526
527 //move data from entity table to detail table
528 $this->moveEntityToDetail('Activity');
529 }
530
531 function fillCase() {
400c14ba 532 $this->fillCaseIDs();
6a488035
TO
533
534 //move data from entity table to detail table
535 $this->moveEntityToDetail('Case');
536 }
537
400c14ba 538 function fillCaseIDs() {
6a488035
TO
539 $contactSQL = array();
540
541 $contactSQL[] = "
542SELECT distinct cc.id
543FROM civicrm_case cc
544LEFT JOIN civicrm_case_contact ccc ON cc.id = ccc.case_id
545LEFT JOIN civicrm_contact c ON ccc.contact_id = c.id
546WHERE (c.sort_name LIKE {$this->_text} OR c.display_name LIKE {$this->_text})
547 AND (cc.is_deleted = 0 OR cc.is_deleted IS NULL)
548";
549
550 if ($this->_textID) {
551 $contactSQL[] = "
552SELECT distinct cc.id
553FROM civicrm_case cc
554LEFT JOIN civicrm_case_contact ccc ON cc.id = ccc.case_id
555LEFT JOIN civicrm_contact c ON ccc.contact_id = c.id
556WHERE cc.id = {$this->_textID}
557 AND (cc.is_deleted = 0 OR cc.is_deleted IS NULL)
558";
559 }
560
561 $contactSQL[] = "
562SELECT et.entity_id
563FROM civicrm_entity_tag et
564INNER JOIN civicrm_tag t ON et.tag_id = t.id
565WHERE et.entity_table = 'civicrm_case'
566AND et.tag_id = t.id
567AND t.name LIKE {$this->_text}
568GROUP BY et.entity_id
569";
570
571 $tables = array(
400c14ba 572 'civicrm_case' => array('fields' => array()),
6a488035
TO
573 'sql' => $contactSQL,
574 );
575
576 $this->runQueries($tables);
577 }
578
579 function fillContribution() {
580 //get contribution ids in entity table.
581 $this->fillContributionIDs();
582
583 //move data from entity table to detail table
584 $this->moveEntityToDetail('Contribution');
585 }
586
587 /**
588 * get contribution ids in entity tables.
589 */
590 function fillContributionIDs() {
591 $contactSQL = array();
592 $contactSQL[] = "
593SELECT distinct cc.id
594FROM civicrm_contribution cc
595INNER JOIN civicrm_contact c ON cc.contact_id = c.id
596WHERE (c.sort_name LIKE {$this->_text} OR
597 c.display_name LIKE {$this->_text})
598";
599 $tables = array(
400c14ba 600 'civicrm_contribution' => array(
601 'id' => 'id',
6a488035
TO
602 'fields' => array(
603 'source' => NULL,
604 'amount_level' => NULL,
605 'trxn_Id' => NULL,
606 'invoice_id' => NULL,
607 'check_number' => ($this->_textID) ? 'Int' : NULL,
608 'total_amount' => ($this->_textID) ? 'Int' : NULL,
609 ),
610 ),
611 'sql' => $contactSQL,
612 'civicrm_note' => array(
613 'id' => 'entity_id',
614 'entity_table' => 'civicrm_contribution',
615 'fields' => array(
616 'subject' => NULL,
617 'note' => NULL,
618 ),
619 ),
620 );
621
622 // get the custom data info
623 $this->fillCustomInfo($tables, "( 'Contribution' )");
624 $this->runQueries($tables);
625 }
626
627 function fillParticipant() {
628 //get participant ids in entity table.
629 $this->fillParticipantIDs();
630
631 //move data from entity table to detail table
632 $this->moveEntityToDetail('Participant');
633 }
634
635 /**
636 * get participant ids in entity tables.
637 */
638 function fillParticipantIDs() {
639 $contactSQL = array();
640 $contactSQL[] = "
641SELECT distinct cp.id
642FROM civicrm_participant cp
643INNER JOIN civicrm_contact c ON cp.contact_id = c.id
644WHERE (c.sort_name LIKE {$this->_text} OR c.display_name LIKE {$this->_text})
645";
646 $tables = array(
400c14ba 647 'civicrm_participant' => array(
648 'id' => 'id',
6a488035
TO
649 'fields' => array(
650 'source' => NULL,
651 'fee_level' => NULL,
652 'fee_amount' => ($this->_textID) ? 'Int' : NULL,
653 ),
654 ),
655 'sql' => $contactSQL,
656 'civicrm_note' => array(
657 'id' => 'entity_id',
658 'entity_table' => 'civicrm_participant',
659 'fields' => array(
660 'subject' => NULL,
661 'note' => NULL,
662 ),
663 ),
664 );
665
666 // get the custom data info
667 $this->fillCustomInfo($tables, "( 'Participant' )");
668 $this->runQueries($tables);
669 }
670
671 function fillMembership() {
672
673 //get membership ids in entity table.
674 $this->fillMembershipIDs();
675
676 //move data from entity table to detail table
677 $this->moveEntityToDetail('Membership');
678 }
679
680 /**
681 * get membership ids in entity tables.
682 */
683 function fillMembershipIDs() {
684 $contactSQL = array();
685 $contactSQL[] = "
686SELECT distinct cm.id
687FROM civicrm_membership cm
688INNER JOIN civicrm_contact c ON cm.contact_id = c.id
689WHERE (c.sort_name LIKE {$this->_text} OR c.display_name LIKE {$this->_text})
690";
691 $tables = array(
400c14ba 692 'civicrm_membership' => array(
693 'id' => 'id',
6a488035
TO
694 'fields' => array('source' => NULL),
695 ),
696 'sql' => $contactSQL,
697 );
698
699 // get the custom data info
700 $this->fillCustomInfo($tables, "( 'Membership' )");
701 $this->runQueries($tables);
702 }
703
704 function buildForm(&$form) {
705 $config = CRM_Core_Config::singleton();
706
707 $form->applyFilter('__ALL__', 'trim');
708 $form->add('text',
709 'text',
710 ts('Find'),
711 TRUE
712 );
713
714 // also add a select box to allow the search to be constrained
715 $tables = array('' => ts('All tables'));
716 if (CRM_Core_Permission::check('view all contacts')) {
717 $tables['Contact'] = ts('Contacts');
718 }
719 if (CRM_Core_Permission::check('view all activities')) {
720 $tables['Activity'] = ts('Activities');
721 }
722 if (in_array('CiviCase', $config->enableComponents)) {
723 $tables['Case'] = ts('Cases');
724 }
725 if (in_array('CiviContribute', $config->enableComponents)) {
726 $tables['Contribution'] = ts('Contributions');
727 }
728 if (in_array('CiviEvent', $config->enableComponents) && CRM_Core_Permission::check('view event participants')) {
729 $tables['Participant'] = ts('Participants');
730 }
731 if (in_array('CiviMember', $config->enableComponents)) {
732 $tables['Membership'] = ts('Memberships');
733 }
734
82de5f35 735 $form->add('select', 'table', ts('Tables'), $tables );
6a488035
TO
736
737 $form->assign('csID', $form->get('csid'));
738
739 // also add the limit constant
740 $form->assign('limit', self::LIMIT);
741
82de5f35 742 // set form defaults
743 if (!empty($form->_formValues)) {
744 $defaults = array();
745
746 if (isset($form->_formValues['text'])) {
747 $defaults['text'] = $form->_formValues['text'];
748 }
749
750 if (isset($form->_formValues['table'])) {
751 $defaults['table'] = $form->_formValues['table'];
752 $form->assign('table', $form->_formValues['table']);
753 }
754
755 $form->setDefaults($defaults);
756 }
757
6a488035
TO
758 /**
759 * You can define a custom title for the search form
760 */
761 $this->setTitle(ts('Full-text Search'));
762 }
763
764 function &columns() {
765 $this->_columns = array(
766 ts('Contact Id') => 'contact_id',
767 ts('Name') => 'sort_name',
768 );
769
770 return $this->_columns;
771 }
772
773 function summary() {
774 $this->initialize();
775
400c14ba 776 $summary = array(
777 'Contact' => array(),
6a488035
TO
778 'Activity' => array(),
779 'Case' => array(),
780 'Contribution' => array(),
781 'Participant' => array(),
782 'Membership' => array(),
783 );
784
785
786 // now iterate through the table and add entries to the relevant section
787 $sql = "SELECT * FROM {$this->_tableName}";
788 if ($this->_table) {
789 $sql .= " {$this->_limitRowClause} ";
790 }
791 $dao = CRM_Core_DAO::executeQuery($sql);
792
793 $activityTypes = CRM_Core_PseudoConstant::activityType(TRUE, TRUE);
794 $roleIds = CRM_Event_PseudoConstant::participantRole();
795 while ($dao->fetch()) {
796 $row = array();
797 foreach ($this->_tableFields as $name => $dontCare) {
798 if ($name != 'activity_type_id') {
799 $row[$name] = $dao->$name;
800 }
801 else {
802 $row['activity_type'] = CRM_Utils_Array::value($dao->$name, $activityTypes);
803 }
804 }
805 if (isset($row['participant_role'])) {
806 $participantRole = explode(CRM_Core_DAO::VALUE_SEPARATOR, $row['participant_role']);
807 $viewRoles = array();
808 foreach ($participantRole as $k => $v) {
809 $viewRoles[] = $roleIds[$v];
810 }
811 $row['participant_role'] = implode(', ', $viewRoles);
812 }
813 $summary[$dao->table_name][] = $row;
814 }
815
816 $summary['Count'] = array();
817 foreach (array_keys($summary) as $table) {
818 $summary['Count'][$table] = CRM_Utils_Array::value($table, $this->_foundRows);
819 if ($summary['Count'][$table] >= self::LIMIT) {
820 $summary['addShowAllLink'][$table] = TRUE;
821 }
822 else {
823 $summary['addShowAllLink'][$table] = FALSE;
824 }
825 }
826
827 return $summary;
828 }
829
830 function count() {
831 $this->initialize();
832
833 if ($this->_table) {
834 return $this->_foundRows[$this->_table];
835 }
836 else {
837 return CRM_Core_DAO::singleValueQuery("SELECT count(id) FROM {$this->_tableName}");
838 }
839 }
840
bbce9d40 841 function contactIDs($offset = 0, $rowcount = 0, $sort = NULL, $returnSQL = FALSE) {
6a488035
TO
842 $this->initialize();
843
bbce9d40
DL
844 $sql = "SELECT contact_id FROM {$this->_tableName}";
845 if ($returnSQL) {
846 return $sql;
847 }
848 else {
849 return CRM_Core_DAO::singleValueQuery($sql);
850 }
6a488035
TO
851 }
852
400c14ba 853 function all($offset = 0, $rowcount = 0, $sort = NULL, $includeContactIDs = FALSE, $justIDs = FALSE) {
6a488035
TO
854 $this->initialize();
855
856 if ($justIDs) {
857 $select = "contact_a.contact_id as contact_id";
858 }
859 else {
860 $select = "
861 contact_a.contact_id as contact_id ,
862 contact_a.sort_name as sort_name
863";
864 }
865
866 $sql = "
867SELECT $select
868FROM {$this->_tableName} contact_a
869 {$this->_limitRowClause}
870";
871 return $sql;
872 }
873
874 function from() {
875 return NULL;
876 }
877
878 function where($includeContactIDs = FALSE) {
879 return NULL;
880 }
881
882 function templateFile() {
883 return 'CRM/Contact/Form/Search/Custom/FullText.tpl';
884 }
885
886 function setDefaultValues() {
887 return array();
888 }
889
400c14ba 890 function alterRow(&$row) {
891 }
6a488035
TO
892
893 function setTitle($title) {
894 if ($title) {
895 CRM_Utils_System::setTitle($title);
896 }
897 }
898
899 /**
900 * get entity id retrieve related data from db and move all data to detail table.
901 *
902 */
903 function moveEntityToDetail($tableName) {
904 $sql = NULL;
905 switch ($tableName) {
906 case 'Contact':
907 $sql = "
908INSERT INTO {$this->_tableName}
909( contact_id, sort_name, table_name )
910SELECT c.id, c.sort_name, 'Contact'
911 FROM {$this->_entityIDTableName} ct
912INNER JOIN civicrm_contact c ON ct.entity_id = c.id
913{$this->_limitDetailClause}
914";
915 break;
916
917 case 'Activity':
918 $sql = "
919INSERT INTO {$this->_tableName}
91da6cd5
DL
920( table_name, activity_id, subject, details, contact_id, sort_name, record_type,
921 activity_type_id, case_id, client_id )
6a488035 922SELECT 'Activity', ca.id, substr(ca.subject, 1, 50), substr(ca.details, 1, 250),
c7b8b4e4 923 c1.id, c1.sort_name, cac.record_type_id,
6a488035
TO
924 ca.activity_type_id,
925 cca.case_id,
926 ccc.contact_id as client_id
927FROM {$this->_entityIDTableName} eid
928INNER JOIN civicrm_activity ca ON ca.id = eid.entity_id
91da6cd5
DL
929INNER JOIN civicrm_activity_contact cac ON cac.activity_id = ca.id
930INNER JOIN civicrm_contact c1 ON cac.contact_id = c1.id
6a488035
TO
931LEFT JOIN civicrm_case_activity cca ON cca.activity_id = ca.id
932LEFT JOIN civicrm_case_contact ccc ON ccc.case_id = cca.case_id
933WHERE (ca.is_deleted = 0 OR ca.is_deleted IS NULL)
934GROUP BY ca.id
935{$this->_limitDetailClause}
936";
937 break;
938
939 case 'Contribution':
940 $sql = "
941INSERT INTO {$this->_tableName}
942( table_name, contact_id, sort_name, contribution_id, financial_type, contribution_page, contribution_receive_date,
943 contribution_total_amount, contribution_trxn_Id, contribution_source, contribution_status, contribution_check_number )
944 SELECT 'Contribution', c.id, c.sort_name, cc.id, cct.name, ccp.title, cc.receive_date,
945 cc.total_amount, cc.trxn_id, cc.source, contribution_status.label, cc.check_number
946 FROM {$this->_entityIDTableName} ct
947INNER JOIN civicrm_contribution cc ON cc.id = ct.entity_id
948LEFT JOIN civicrm_contact c ON cc.contact_id = c.id
949LEFT JOIN civicrm_financial_type cct ON cct.id = cc.financial_type_id
950LEFT JOIN civicrm_contribution_page ccp ON ccp.id = cc.contribution_page_id
951LEFT JOIN civicrm_option_group option_group_contributionStatus ON option_group_contributionStatus.name = 'contribution_status'
952LEFT JOIN civicrm_option_value contribution_status ON
953( contribution_status.option_group_id = option_group_contributionStatus.id AND contribution_status.value = cc.contribution_status_id )
954{$this->_limitDetailClause}
955";
956 break;
957
958 case 'Participant':
959 $sql = "
960INSERT INTO {$this->_tableName}
961( table_name, contact_id, sort_name, participant_id, event_title, participant_fee_level, participant_fee_amount,
962participant_register_date, participant_source, participant_status, participant_role )
963 SELECT 'Participant', c.id, c.sort_name, cp.id, ce.title, cp.fee_level, cp.fee_amount, cp.register_date, cp.source,
964 participantStatus.label, cp.role_id
965 FROM {$this->_entityIDTableName} ct
966INNER JOIN civicrm_participant cp ON cp.id = ct.entity_id
967LEFT JOIN civicrm_contact c ON cp.contact_id = c.id
968LEFT JOIN civicrm_event ce ON ce.id = cp.event_id
969LEFT JOIN civicrm_participant_status_type participantStatus ON participantStatus.id = cp.status_id
970{$this->_limitDetailClause}
971";
972 break;
973
974 case 'Membership':
975 $sql = "
976INSERT INTO {$this->_tableName}
977( table_name, contact_id, sort_name, membership_id, membership_type, membership_fee, membership_start_date,
978membership_end_date, membership_source, membership_status )
979 SELECT 'Membership', c.id, c.sort_name, cm.id, cmt.name, cc.total_amount, cm.start_date, cm.end_date, cm.source, cms.name
980 FROM {$this->_entityIDTableName} ct
981INNER JOIN civicrm_membership cm ON cm.id = ct.entity_id
982LEFT JOIN civicrm_contact c ON cm.contact_id = c.id
983LEFT JOIN civicrm_membership_type cmt ON cmt.id = cm.membership_type_id
984LEFT JOIN civicrm_membership_payment cmp ON cmp.membership_id = cm.id
985LEFT JOIN civicrm_contribution cc ON cc.id = cmp.contribution_id
986LEFT JOIN civicrm_membership_status cms ON cms.id = cm.status_id
987{$this->_limitDetailClause}
988";
989 break;
990
991 case 'Case':
992 $sql = "
993INSERT INTO {$this->_tableName}
994( table_name, contact_id, sort_name, case_id, case_start_date, case_end_date, case_is_deleted )
995SELECT 'Case', c.id, c.sort_name, cc.id, DATE(cc.start_date), DATE(cc.end_date), cc.is_deleted
996FROM {$this->_entityIDTableName} ct
997INNER JOIN civicrm_case cc ON cc.id = ct.entity_id
998LEFT JOIN civicrm_case_contact ccc ON cc.id = ccc.case_id
999LEFT JOIN civicrm_contact c ON ccc.contact_id = c.id
1000{$this->_limitDetailClause}
1001";
1002 break;
6a488035
TO
1003 }
1004
1005 if ($sql) {
1006 CRM_Core_DAO::executeQuery($sql);
1007 }
1008 }
1009}
1010