INFRA-132 - CRM/Contact - Misc
[civicrm-core.git] / CRM / Contact / Form / Search / Custom / ActivitySearch.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
39de6fd5 4 | CiviCRM version 4.6 |
6a488035 5 +--------------------------------------------------------------------+
06b69b18 6 | Copyright CiviCRM LLC (c) 2004-2014 |
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 +--------------------------------------------------------------------+
26*/
27
28/**
29 *
30 * @package CRM
06b69b18 31 * @copyright CiviCRM LLC (c) 2004-2014
6a488035
TO
32 * $Id$
33 *
34 */
35class CRM_Contact_Form_Search_Custom_ActivitySearch implements CRM_Contact_Form_Search_Interface {
36
430ae6dd
TO
37 protected $_formValues;
38
86538308
EM
39 /**
40 * @param $formValues
41 */
42 /**
43 * @param $formValues
44 */
00be9182 45 public function __construct(&$formValues) {
6a488035
TO
46 $this->_formValues = $formValues;
47
48 /**
49 * Define the columns for search result rows
50 */
51 $this->_columns = array(
52 ts('Name') => 'sort_name',
53 ts('Status') => 'activity_status',
54 ts('Activity Type') => 'activity_type',
55 ts('Activity Subject') => 'activity_subject',
56 ts('Scheduled By') => 'source_contact',
57 ts('Scheduled Date') => 'activity_date',
58 ts(' ') => 'activity_id',
59 ts(' ') => 'activity_type_id',
60 ts(' ') => 'case_id',
61 ts('Location') => 'location',
62 ts('Duration') => 'duration',
63 ts('Details') => 'details',
64 ts('Assignee') => 'assignee',
65 );
66
67 $this->_groupId = CRM_Core_DAO::getFieldValue('CRM_Core_DAO_OptionGroup',
68 'activity_status',
69 'id',
70 'name'
71 );
72
73 //Add custom fields to columns array for inclusion in export
74 $groupTree = &CRM_Core_BAO_CustomGroup::getTree('Activity', $form, NULL,
75 NULL, '', NULL
76 );
77
6a488035
TO
78 //use simplified formatted groupTree
79 $groupTree = CRM_Core_BAO_CustomGroup::formatGroupTree($groupTree, 1, $form);
80
81 //cycle through custom fields and assign to _columns array
82 foreach ($groupTree as $key) {
83 foreach ($key['fields'] as $field) {
84 $fieldlabel = $key['title'] . ": " . $field['label'];
85 $this->_columns[$fieldlabel] = $field['column_name'];
86 }
87 }
88 //end custom fields
89 }
90
86538308 91 /**
c490a46a 92 * @param CRM_Core_Form $form
86538308 93 */
00be9182 94 public function buildForm(&$form) {
6a488035
TO
95
96 /**
97 * You can define a custom title for the search form
98 */
99 $this->setTitle('Find Latest Activities');
100
101 /**
102 * Define the search form fields here
103 */
104 // Allow user to choose which type of contact to limit search on
105 $form->add('select', 'contact_type', ts('Find...'), CRM_Core_SelectValues::contactType());
106
107 // Text box for Activity Subject
108 $form->add('text',
109 'activity_subject',
110 ts('Activity Subject')
111 );
112
113 // Select box for Activity Type
114 $activityType = array('' => ' - select activity - ') + CRM_Core_PseudoConstant::activityType();
115
116 $form->add('select', 'activity_type_id', ts('Activity Type'),
117 $activityType,
118 FALSE
119 );
120
121 // textbox for Activity Status
122 $activityStatus = array('' => ' - select status - ') + CRM_Core_PseudoConstant::activityStatus();
123
124 $form->add('select', 'activity_status_id', ts('Activity Status'),
125 $activityStatus,
126 FALSE
127 );
128
129 // Activity Date range
130 $form->addDate('start_date', ts('Activity Date From'), FALSE, array('formatType' => 'custom'));
131 $form->addDate('end_date', ts('...through'), FALSE, array('formatType' => 'custom'));
132
6a488035
TO
133 // Contact Name field
134 $form->add('text', 'sort_name', ts('Contact Name'));
135
136 /**
137 * If you are using the sample template, this array tells the template fields to render
138 * for the search form.
139 */
140 $form->assign('elements', array(
141 'contact_type', 'activity_subject', 'activity_type_id',
142 'activity_status_id', 'start_date', 'end_date', 'sort_name',
143 ));
144 }
145
146 /**
147 * Define the smarty template used to layout the search form and results listings.
148 */
00be9182 149 public function templateFile() {
6a488035
TO
150 return 'CRM/Contact/Form/Search/Custom/ActivitySearch.tpl';
151 }
152
153 /**
154 * Construct the search query
155 */
51ccfbbe
TO
156 function all(
157 $offset = 0, $rowcount = 0, $sort = NULL,
6a488035
TO
158 $includeContactIDs = FALSE, $justIDs = FALSE
159 ) {
160
161 // SELECT clause must include contact_id as an alias for civicrm_contact.id
162 if ($justIDs) {
163 $select = 'contact_a.id as contact_id';
164 }
165 else {
166 $select = '
167 contact_a.id as contact_id,
168 contact_a.sort_name as sort_name,
169 contact_a.contact_type as contact_type,
170 activity.id as activity_id,
171 activity.activity_type_id as activity_type_id,
172 contact_b.sort_name as source_contact,
173 ov1.label as activity_type,
174 activity.subject as activity_subject,
175 activity.activity_date_time as activity_date,
176 ov2.label as activity_status,
177 cca.case_id as case_id,
178 activity.location as location,
179 activity.duration as duration,
180 activity.details as details,
181 assignment.activity_id as assignment_activity,
182 contact_c.display_name as assignee
183 ';
184 }
185
186 $from = $this->from();
187
188 $where = $this->where($includeContactIDs);
189
190 if (!empty($where)) {
191 $where = "WHERE $where";
192 }
193
194 // add custom group fields to SELECT and FROM clause
195 $groupTree = CRM_Core_BAO_CustomGroup::getTree('Activity', $form, NULL, NULL, '', NULL);
196
197 foreach ($groupTree as $key) {
7c34ab11 198 if (!empty($key['extends']) && $key['extends'] == 'Activity') {
6a488035
TO
199 $select .= ", " . $key['table_name'] . ".*";
200 $from .= " LEFT JOIN " . $key['table_name'] . " ON " . $key['table_name'] . ".entity_id = activity.id";
201 }
202 }
203 // end custom groups add
204
205 $sql = " SELECT $select FROM $from $where ";
206
207 //no need to add order when only contact Ids.
208 if (!$justIDs) {
209 // Define ORDER BY for query in $sort, with default value
210 if (!empty($sort)) {
211 if (is_string($sort)) {
21d32567 212 $sort = CRM_Utils_Type::escape($sort, 'String');
6a488035
TO
213 $sql .= " ORDER BY $sort ";
214 }
215 else {
216 $sql .= ' ORDER BY ' . trim($sort->orderBy());
217 }
218 }
219 else {
220 $sql .= 'ORDER BY contact_a.sort_name, activity.activity_date_time DESC, activity.activity_type_id, activity.status_id, activity.subject';
221 }
222 }
7c34ab11 223 else {
26a9b6ab
C
224 //CRM-14107, since there could be multiple activities against same contact,
225 //we need to provide GROUP BY on contact id to prevent duplicacy on prev/next entries
226 $sql .= 'GROUP BY contact_a.id
227ORDER BY contact_a.sort_name';
7c34ab11 228 }
6a488035
TO
229
230 if ($rowcount > 0 && $offset >= 0) {
bf00d1b6 231 $offset = CRM_Utils_Type::escape($offset, 'Int');
dd3a4117 232 $rowcount = CRM_Utils_Type::escape($rowcount, 'Int');
6a488035
TO
233 $sql .= " LIMIT $offset, $rowcount ";
234 }
235 return $sql;
236 }
237
238 // Alters the date display in the Activity Date Column. We do this after we already have
239 // the result so that sorting on the date column stays pertinent to the numeric date value
86538308
EM
240 /**
241 * @param $row
242 */
00be9182 243 public function alterRow(&$row) {
6a488035
TO
244 $row['activity_date'] = CRM_Utils_Date::customFormat($row['activity_date'], '%B %E%f, %Y %l:%M %P');
245 }
246
247 // Regular JOIN statements here to limit results to contacts who have activities.
86538308
EM
248 /**
249 * @return string
250 */
00be9182 251 public function from() {
e7e657f0 252 $activityContacts = CRM_Core_OptionGroup::values('activity_contacts', FALSE, FALSE, FALSE, NULL, 'name');
9e74e3ce 253 $assigneeID = CRM_Utils_Array::key('Activity Assignees', $activityContacts);
ecaec004
RN
254 $targetID = CRM_Utils_Array::key('Activity Targets', $activityContacts);
255 $sourceID = CRM_Utils_Array::key('Activity Source', $activityContacts);
256
6a488035 257 return "
ecaec004
RN
258 civicrm_activity activity
259 LEFT JOIN civicrm_activity_contact target
260 ON activity.id = target.activity_id AND target.record_type_id = {$targetID}
261 JOIN civicrm_contact contact_a
262 ON contact_a.id = target.contact_id
6a488035
TO
263 JOIN civicrm_option_value ov1
264 ON activity.activity_type_id = ov1.value AND ov1.option_group_id = 2
265 JOIN civicrm_option_value ov2
266 ON activity.status_id = ov2.value AND ov2.option_group_id = {$this->_groupId}
ecaec004 267 LEFT JOIN civicrm_activity_contact sourceContact
8ef12e64 268 ON activity.id = sourceContact.activity_id AND sourceContact.record_type_id = {$sourceID}
6a488035 269 JOIN civicrm_contact contact_b
ecaec004 270 ON sourceContact.contact_id = contact_b.id
6a488035
TO
271 LEFT JOIN civicrm_case_activity cca
272 ON activity.id = cca.activity_id
38ba593b 273 LEFT JOIN civicrm_activity_contact assignment
9e74e3ce 274 ON activity.id = assignment.activity_id AND assignment.record_type_id = {$assigneeID}
6a488035 275 LEFT JOIN civicrm_contact contact_c
38ba593b 276 ON assignment.contact_id = contact_c.id ";
6a488035
TO
277 }
278
86538308 279 /**
c490a46a
CW
280 * WHERE clause is an array built from any required JOINS plus conditional filters based on search criteria field values
281 *
86538308
EM
282 * @param bool $includeContactIDs
283 *
284 * @return string
285 */
00be9182 286 public function where($includeContactIDs = FALSE) {
6a488035
TO
287 $clauses = array();
288
289 // add contact name search; search on primary name, source contact, assignee
290 $contactname = $this->_formValues['sort_name'];
291 if (!empty($contactname)) {
292 $dao = new CRM_Core_DAO();
293 $contactname = $dao->escape($contactname);
294 $clauses[] = "(contact_a.sort_name LIKE '%{$contactname}%' OR
295 contact_b.sort_name LIKE '%{$contactname}%' OR
296 contact_c.display_name LIKE '%{$contactname}%')";
297 }
298
299 $subject = $this->_formValues['activity_subject'];
300
301 if (!empty($this->_formValues['contact_type'])) {
302 $clauses[] = "contact_a.contact_type LIKE '%{$this->_formValues['contact_type']}%'";
303 }
304
305 if (!empty($subject)) {
306 $dao = new CRM_Core_DAO();
307 $subject = $dao->escape($subject);
308 $clauses[] = "activity.subject LIKE '%{$subject}%'";
309 }
310
311 if (!empty($this->_formValues['activity_status_id'])) {
312 $clauses[] = "activity.status_id = {$this->_formValues['activity_status_id']}";
313 }
314
315 if (!empty($this->_formValues['activity_type_id'])) {
316 $clauses[] = "activity.activity_type_id = {$this->_formValues['activity_type_id']}";
317 }
318
319 $startDate = $this->_formValues['start_date'];
320 if (!empty($startDate)) {
321 $startDate .= '00:00:00';
322 $startDateFormatted = CRM_Utils_Date::processDate($startDate);
323 if ($startDateFormatted) {
324 $clauses[] = "activity.activity_date_time >= $startDateFormatted";
325 }
326 }
327
328 $endDate = $this->_formValues['end_date'];
329 if (!empty($endDate)) {
330 $endDate .= '23:59:59';
331 $endDateFormatted = CRM_Utils_Date::processDate($endDate);
332 if ($endDateFormatted) {
333 $clauses[] = "activity.activity_date_time <= $endDateFormatted";
334 }
335 }
336
337 if ($includeContactIDs) {
338 $contactIDs = array();
339 foreach ($this->_formValues as $id => $value) {
340 if ($value &&
341 substr($id, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX
342 ) {
343 $contactIDs[] = substr($id, CRM_Core_Form::CB_PREFIX_LEN);
344 }
345 }
346
347 if (!empty($contactIDs)) {
348 $contactIDs = implode(', ', $contactIDs);
349 $clauses[] = "contact_a.id IN ( $contactIDs )";
350 }
351 }
352
353 return implode(' AND ', $clauses);
354 }
355
dcc94695 356 /**
6a488035 357 * Functions below generally don't need to be modified
dcc94695 358 * @return integer
6a488035 359 */
00be9182 360 public function count() {
6a488035
TO
361 $sql = $this->all();
362
363 $dao = CRM_Core_DAO::executeQuery($sql,
364 CRM_Core_DAO::$_nullArray
365 );
366 return $dao->N;
367 }
368
86538308
EM
369 /**
370 * @param int $offset
371 * @param int $rowcount
372 * @param null $sort
373 *
374 * @return string
375 */
00be9182 376 public function contactIDs($offset = 0, $rowcount = 0, $sort = NULL) {
6a488035
TO
377 return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
378 }
379
86538308
EM
380 /**
381 * @return array
382 */
00be9182 383 public function &columns() {
6a488035
TO
384 return $this->_columns;
385 }
386
86538308
EM
387 /**
388 * @param $title
389 */
00be9182 390 public function setTitle($title) {
6a488035
TO
391 if ($title) {
392 CRM_Utils_System::setTitle($title);
393 }
394 else {
395 CRM_Utils_System::setTitle(ts('Search'));
396 }
397 }
398
86538308
EM
399 /**
400 * @return null
401 */
00be9182 402 public function summary() {
6a488035
TO
403 return NULL;
404 }
405}