INFRA-132 - Whitespace fixes in docbloks
[civicrm-core.git] / CRM / Contribute / Selector / Search.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
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-2014
32 * $Id$
33 *
34 */
35
36 /**
37 * This class is used to retrieve and display a range of
38 * contacts that match the given criteria (specifically for
39 * results of advanced search options.
40 *
41 */
42 class CRM_Contribute_Selector_Search extends CRM_Core_Selector_Base implements CRM_Core_Selector_API {
43
44 /**
45 * This defines two actions- View and Edit.
46 *
47 * @var array
48 * @static
49 */
50 static $_links = NULL;
51
52 /**
53 * We use desc to remind us what that column is, name is used in the tpl
54 *
55 * @var array
56 * @static
57 */
58 static $_columnHeaders;
59
60 /**
61 * Properties of contact we're interested in displaying
62 * @var array
63 * @static
64 */
65 static $_properties = array(
66 'contact_id',
67 'contribution_id',
68 'contact_type',
69 'sort_name',
70 'amount_level',
71 'total_amount',
72 'financial_type',
73 'contribution_source',
74 'receive_date',
75 'thankyou_date',
76 'contribution_status_id',
77 'contribution_status',
78 'cancel_date',
79 'product_name',
80 'is_test',
81 'contribution_recur_id',
82 'receipt_date',
83 'membership_id',
84 'currency',
85 'contribution_campaign_id',
86 'contribution_soft_credit_name',
87 'contribution_soft_credit_contact_id',
88 'contribution_soft_credit_amount',
89 'contribution_soft_credit_type',
90 );
91
92 /**
93 * Are we restricting ourselves to a single contact
94 *
95 * @var boolean
96 */
97 protected $_single = FALSE;
98
99 /**
100 * Are we restricting ourselves to a single contact
101 *
102 * @var boolean
103 */
104 protected $_limit = NULL;
105
106 /**
107 * What context are we being invoked from
108 *
109 * @var string
110 */
111 protected $_context = NULL;
112
113 /**
114 * What component context are we being invoked from
115 *
116 * @var string
117 */
118 protected $_compContext = NULL;
119
120 /**
121 * QueryParams is the array returned by exportValues called on
122 * the HTML_QuickForm_Controller for that page.
123 *
124 * @var array
125 */
126 public $_queryParams;
127
128 /**
129 * Represent the type of selector
130 *
131 * @var int
132 */
133 protected $_action;
134
135 /**
136 * The additional clause that we restrict the search with
137 *
138 * @var string
139 */
140 protected $_contributionClause = NULL;
141
142 /**
143 * The query object
144 *
145 * @var string
146 */
147 protected $_query;
148
149 protected $_includeSoftCredits = FALSE;
150
151 /**
152 * Class constructor
153 *
154 * @param array $queryParams
155 * Array of parameters for query.
156 * @param \const|int $action - action of search basic or advanced.
157 * @param string $contributionClause
158 * If the caller wants to further restrict the search (used in contributions).
159 * @param bool $single
160 * Are we dealing only with one contact?.
161 * @param int $limit
162 * How many contributions do we want returned.
163 *
164 * @param string $context
165 * @param null $compContext
166 *
167 * @return \CRM_Contribute_Selector_Search
168 * @access public
169 */
170 function __construct(
171 &$queryParams,
172 $action = CRM_Core_Action::NONE,
173 $contributionClause = NULL,
174 $single = FALSE,
175 $limit = NULL,
176 $context = 'search',
177 $compContext = NULL
178 ) {
179
180 // submitted form values
181 $this->_queryParams = &$queryParams;
182
183 $this->_single = $single;
184 $this->_limit = $limit;
185 $this->_context = $context;
186 $this->_compContext = $compContext;
187
188 $this->_contributionClause = $contributionClause;
189
190 // type of selector
191 $this->_action = $action;
192
193 $this->_includeSoftCredits = CRM_Contribute_BAO_Query::isSoftCreditOptionEnabled($this->_queryParams);
194 $this->_query = new CRM_Contact_BAO_Query(
195 $this->_queryParams,
196 CRM_Contribute_BAO_Query::defaultReturnProperties(
197 CRM_Contact_BAO_Query::MODE_CONTRIBUTE,
198 FALSE
199 ),
200 NULL, FALSE, FALSE,
201 CRM_Contact_BAO_Query::MODE_CONTRIBUTE
202 );
203 if ($this->_includeSoftCredits) {
204 $this->_query->_rowCountClause = " count(civicrm_contribution.id)";
205 $this->_query->_groupByComponentClause = " GROUP BY contribution_search_scredit_combined.id, contribution_search_scredit_combined.contact_id, contribution_search_scredit_combined.scredit_id ";
206 }
207 else {
208 $this->_query->_distinctComponentClause = " civicrm_contribution.id";
209 $this->_query->_groupByComponentClause = " GROUP BY civicrm_contribution.id ";
210 }
211 }
212
213 /**
214 * This method returns the links that are given for each search row.
215 * currently the links added for each row are
216 *
217 * - View
218 * - Edit
219 *
220 * @param int $componentId
221 * @param null $componentAction
222 * @param null $key
223 * @param null $compContext
224 *
225 * @return array
226 */
227 public static function &links($componentId = NULL, $componentAction = NULL, $key = NULL, $compContext = NULL) {
228 $extraParams = NULL;
229 if ($componentId) {
230 $extraParams = "&compId={$componentId}&compAction={$componentAction}";
231 }
232 if ($compContext) {
233 $extraParams .= "&compContext={$compContext}";
234 }
235 if ($key) {
236 $extraParams .= "&key={$key}";
237 }
238
239 if (!(self::$_links)) {
240 self::$_links = array(
241 CRM_Core_Action::VIEW => array(
242 'name' => ts('View'),
243 'url' => 'civicrm/contact/view/contribution',
244 'qs' => "reset=1&id=%%id%%&cid=%%cid%%&action=view&context=%%cxt%%&selectedChild=contribute{$extraParams}",
245 'title' => ts('View Contribution'),
246 ),
247 CRM_Core_Action::UPDATE => array(
248 'name' => ts('Edit'),
249 'url' => 'civicrm/contact/view/contribution',
250 'qs' => "reset=1&action=update&id=%%id%%&cid=%%cid%%&context=%%cxt%%{$extraParams}",
251 'title' => ts('Edit Contribution'),
252 ),
253 CRM_Core_Action::DELETE => array(
254 'name' => ts('Delete'),
255 'url' => 'civicrm/contact/view/contribution',
256 'qs' => "reset=1&action=delete&id=%%id%%&cid=%%cid%%&context=%%cxt%%{$extraParams}",
257 'title' => ts('Delete Contribution'),
258 ),
259 );
260 }
261 return self::$_links;
262 }
263
264 /**
265 * Getter for array of the parameters required for creating pager.
266 *
267 * @param $action
268 * @param array $params
269 */
270 public function getPagerParams($action, &$params) {
271 $params['status'] = ts('Contribution') . ' %%StatusMessage%%';
272 $params['csvString'] = NULL;
273 if ($this->_limit) {
274 $params['rowCount'] = $this->_limit;
275 }
276 else {
277 $params['rowCount'] = CRM_Utils_Pager::ROWCOUNT;
278 }
279
280 $params['buttonTop'] = 'PagerTopButton';
281 $params['buttonBottom'] = 'PagerBottomButton';
282 }
283
284 /**
285 * Returns total number of rows for the query.
286 *
287 * @param
288 *
289 * @return int
290 * Total number of rows
291 */
292 public function getTotalCount($action) {
293 return $this->_query->searchQuery(0, 0, NULL,
294 TRUE, FALSE,
295 FALSE, FALSE,
296 FALSE,
297 $this->_contributionClause
298 );
299 }
300
301 /**
302 * Returns all the rows in the given offset and rowCount
303 *
304 * @param enum $action
305 * The action being performed.
306 * @param int $offset
307 * The row number to start from.
308 * @param int $rowCount
309 * The number of rows to return.
310 * @param string $sort
311 * The sql string that describes the sort order.
312 * @param enum $output
313 * What should the result set include (web/email/csv).
314 *
315 * @return int
316 * the total number of rows for this action
317 */
318 public function &getRows($action, $offset, $rowCount, $sort, $output = NULL) {
319 if ($this->_includeSoftCredits) {
320 // especial sort order when rows include soft credits
321 $sort = "civicrm_contribution.receive_date DESC, civicrm_contribution.id, civicrm_contribution_soft.id";
322 }
323 $result = $this->_query->searchQuery($offset, $rowCount, $sort,
324 FALSE, FALSE,
325 FALSE, FALSE,
326 FALSE,
327 $this->_contributionClause
328 );
329 // process the result of the query
330 $rows = array();
331
332 //CRM-4418 check for view/edit/delete
333 $permissions = array(CRM_Core_Permission::VIEW);
334 if (CRM_Core_Permission::check('edit contributions')) {
335 $permissions[] = CRM_Core_Permission::EDIT;
336 }
337 if (CRM_Core_Permission::check('delete in CiviContribute')) {
338 $permissions[] = CRM_Core_Permission::DELETE;
339 }
340 $mask = CRM_Core_Action::mask($permissions);
341
342 $qfKey = $this->_key;
343 $componentId = $componentContext = NULL;
344 if ($this->_context != 'contribute') {
345 $qfKey = CRM_Utils_Request::retrieve('key', 'String', CRM_Core_DAO::$_nullObject);
346 $componentId = CRM_Utils_Request::retrieve('id', 'Positive', CRM_Core_DAO::$_nullObject);
347 $componentAction = CRM_Utils_Request::retrieve('action', 'String', CRM_Core_DAO::$_nullObject);
348 $componentContext = CRM_Utils_Request::retrieve('compContext', 'String', CRM_Core_DAO::$_nullObject);
349
350 if (!$componentContext &&
351 $this->_compContext
352 ) {
353 $componentContext = $this->_compContext;
354 $qfKey = CRM_Utils_Request::retrieve('qfKey', 'String', CRM_Core_DAO::$_nullObject, NULL, FALSE, 'REQUEST');
355 }
356 }
357
358 // get all contribution status
359 $contributionStatuses = CRM_Core_OptionGroup::values('contribution_status',
360 FALSE, FALSE, FALSE, NULL, 'name', FALSE
361 );
362
363 //get all campaigns.
364 $allCampaigns = CRM_Campaign_BAO_Campaign::getCampaigns(NULL, NULL, FALSE, FALSE, FALSE, TRUE);
365
366 while ($result->fetch()) {
367 $row = array();
368 // the columns we are interested in
369 foreach (self::$_properties as $property) {
370 if (property_exists($result, $property)) {
371 $row[$property] = $result->$property;
372 }
373 }
374
375 //carry campaign on selectors.
376 $row['campaign'] = CRM_Utils_Array::value($result->contribution_campaign_id, $allCampaigns);
377 $row['campaign_id'] = $result->contribution_campaign_id;
378
379 // add contribution status name
380 $row['contribution_status_name'] = CRM_Utils_Array::value($row['contribution_status_id'],
381 $contributionStatuses
382 );
383
384 if ($result->is_pay_later && CRM_Utils_Array::value('contribution_status_name', $row) == 'Pending') {
385 $row['contribution_status'] .= ' (' . ts('Pay Later') . ')';
386 }
387 elseif (CRM_Utils_Array::value('contribution_status_name', $row) == 'Pending') {
388 $row['contribution_status'] .= ' (' . ts('Incomplete Transaction') . ')';
389 }
390
391 if ($row['is_test']) {
392 $row['financial_type'] = $row['financial_type'] . ' (' . ts('test') . ')';
393 }
394
395 $row['checkbox'] = CRM_Core_Form::CB_PREFIX . $result->contribution_id;
396
397 $actions = array(
398 'id' => $result->contribution_id,
399 'cid' => $result->contact_id,
400 'cxt' => $this->_context,
401 );
402
403 $row['action'] = CRM_Core_Action::formLink(
404 self::links($componentId,
405 $componentAction,
406 $qfKey,
407 $componentContext
408 ),
409 $mask, $actions,
410 ts('more'),
411 FALSE,
412 'contribution.selector.row',
413 'Contribution',
414 $result->contribution_id
415 );
416
417 $row['contact_type'] = CRM_Contact_BAO_Contact_Utils::getImage($result->contact_sub_type ? $result->contact_sub_type : $result->contact_type, FALSE, $result->contact_id
418 );
419
420 if (!empty($row['amount_level'])) {
421 CRM_Event_BAO_Participant::fixEventLevel($row['amount_level']);
422 }
423
424 $rows[] = $row;
425 }
426
427 return $rows;
428 }
429
430 /**
431 * @return array
432 * which contains an array of strings
433 */
434
435 // the current internationalisation is bad, but should more or less work
436 // for most of "European" languages
437 public function getQILL() {
438 return $this->_query->qill();
439 }
440
441 /**
442 * Returns the column headers as an array of tuples:
443 * (name, sortName (key to the sort array))
444 *
445 * @param string $action
446 * The action being performed.
447 * @param enum $output
448 * What should the result set include (web/email/csv).
449 *
450 * @return array
451 * the column headers that need to be displayed
452 */
453 public function &getColumnHeaders($action = NULL, $output = NULL) {
454 self::$_columnHeaders = array(
455 array(
456 'name' => $this->_includeSoftCredits ? ts('Contribution Amount') : ts('Amount'),
457 'sort' => 'total_amount',
458 'direction' => CRM_Utils_Sort::DONTCARE,
459 ),
460 );
461 if ($this->_includeSoftCredits) {
462 self::$_columnHeaders =
463 array_merge(
464 self::$_columnHeaders,
465 array(
466 array(
467 'name' => ts('Soft Credit Amount'),
468 'sort' => 'contribution_soft_credit_amount',
469 'direction' => CRM_Utils_Sort::DONTCARE,
470 ),
471 )
472 );
473 }
474 self::$_columnHeaders =
475 array_merge(
476 self::$_columnHeaders,
477 array(
478 array(
479 'name' => ts('Type'),
480 'sort' => 'financial_type',
481 'direction' => CRM_Utils_Sort::DONTCARE,
482 ),
483 array(
484 'name' => ts('Source'),
485 'sort' => 'contribution_source',
486 'direction' => CRM_Utils_Sort::DONTCARE,
487 ),
488 array(
489 'name' => ts('Received'),
490 'sort' => 'receive_date',
491 'direction' => CRM_Utils_Sort::DESCENDING,
492 ),
493 array(
494 'name' => ts('Thank-you Sent'),
495 'sort' => 'thankyou_date',
496 'direction' => CRM_Utils_Sort::DONTCARE,
497 ),
498 array(
499 'name' => ts('Status'),
500 'sort' => 'contribution_status',
501 'direction' => CRM_Utils_Sort::DONTCARE,
502 ),
503 array(
504 'name' => ts('Premium'),
505 'sort' => 'product_name',
506 'direction' => CRM_Utils_Sort::DONTCARE,
507 ),
508 )
509 );
510 if (!$this->_single) {
511 $pre = array(
512 array('desc' => ts('Contact Type')),
513 array(
514 'name' => ts('Name'),
515 'sort' => 'sort_name',
516 'direction' => CRM_Utils_Sort::DONTCARE,
517 ),
518 );
519 self::$_columnHeaders = array_merge($pre, self::$_columnHeaders);
520 }
521 if ($this->_includeSoftCredits) {
522 self::$_columnHeaders =
523 array_merge(
524 self::$_columnHeaders,
525 array(
526 array(
527 'name' => ts('Soft Credit For'),
528 'sort' => 'contribution_soft_credit_name',
529 'direction' => CRM_Utils_Sort::DONTCARE,
530 ),
531 array(
532 'name' => ts('Soft Credit Type'),
533 'sort' => 'contribution_soft_credit_type',
534 'direction' => CRM_Utils_Sort::ASCENDING,
535 ),
536 )
537 );
538 }
539 self::$_columnHeaders =
540 array_merge(
541 self::$_columnHeaders, array(
542 array('desc' => ts('Actions')),
543 )
544 );
545 return self::$_columnHeaders;
546 }
547
548 /**
549 * @return mixed
550 */
551 public function alphabetQuery() {
552 return $this->_query->searchQuery(NULL, NULL, NULL, FALSE, FALSE, TRUE);
553 }
554
555 /**
556 * @return string
557 */
558 public function &getQuery() {
559 return $this->_query;
560 }
561
562 /**
563 * Name of export file.
564 *
565 * @param string $output
566 * Type of output.
567 *
568 * @return string
569 * name of the file
570 */
571 public function getExportFileName($output = 'csv') {
572 return ts('CiviCRM Contribution Search');
573 }
574
575 /**
576 * @return mixed
577 */
578 public function getSummary() {
579 return $this->_query->summaryContribution($this->_context);
580 }
581 }