Fix undefined var
[civicrm-core.git] / CRM / Contact / Form / Search / Custom / ContributionAggregate.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.3 |
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_ContributionAggregate implements CRM_Contact_Form_Search_Interface {
36
4e54c348
PJ
37 protected $_formValues;
38 public $_permissionedComponent;
6a488035 39
4e54c348
PJ
40 function __construct(&$formValues) {
41 $this->_formValues = $formValues;
6a488035
TO
42 /**
43 * Define the columns for search result rows
44 */
4e54c348 45
6a488035
TO
46 $this->_columns = array(
47 ts('Contact Id') => 'contact_id',
48 ts('Name') => 'sort_name',
49 ts('Donation Count') => 'donation_count',
50 ts('Donation Amount') => 'donation_amount',
51 );
4e54c348
PJ
52
53 // define component access permission needed
54 $this->_permissionedComponent = 'CiviContribute';
6a488035
TO
55 }
56
57 function buildForm(&$form) {
58
59 /**
60 * You can define a custom title for the search form
61 */
62 $this->setTitle('Find Contributors by Aggregate Totals');
63
64 /**
65 * Define the search form fields here
66 */
67 $form->add('text',
68 'min_amount',
69 ts('Aggregate Total Between $')
70 );
71 $form->addRule('min_amount', ts('Please enter a valid amount (numbers and decimal point only).'), 'money');
72
73 $form->add('text',
74 'max_amount',
75 ts('...and $')
76 );
77 $form->addRule('max_amount', ts('Please enter a valid amount (numbers and decimal point only).'), 'money');
78
79 $form->addDate('start_date', ts('Contribution Date From'), FALSE, array('formatType' => 'custom'));
80 $form->addDate('end_date', ts('...through'), FALSE, array('formatType' => 'custom'));
81
82 $financial_types = CRM_Contribute_PseudoConstant::financialType();
83 foreach($financial_types as $financial_type_id => $financial_type) {
84 $form->addElement('checkbox', "financial_type_id[{$financial_type_id}]", 'Financial Type', $financial_type);
85 }
86
87 /**
88 * If you are using the sample template, this array tells the template fields to render
89 * for the search form.
90 */
91 $form->assign('elements', array('min_amount', 'max_amount', 'start_date', 'end_date', 'financial_type_id'));
92 }
93
94 /**
95 * Define the smarty template used to layout the search form and results listings.
96 */
97 function templateFile() {
98 return 'CRM/Contact/Form/Search/Custom/ContributionAggregate.tpl';
99 }
100
101 /**
102 * Construct the search query
103 */
104 function all($offset = 0, $rowcount = 0, $sort = NULL,
105 $includeContactIDs = FALSE, $justIDs = FALSE
106 ) {
107
108 // SELECT clause must include contact_id as an alias for civicrm_contact.id
109 if ($justIDs) {
110 $select = "contact_a.id as contact_id";
111 }
112 else {
113 $select = "
114DISTINCT contact_a.id as contact_id,
115contact_a.sort_name as sort_name,
116sum(contrib.total_amount) AS donation_amount,
117count(contrib.id) AS donation_count
118";
119 }
120 $from = $this->from();
121
122 $where = $this->where($includeContactIDs);
123
124 $having = $this->having();
125 if ($having) {
126 $having = " HAVING $having ";
127 }
128
129 $sql = "
130SELECT $select
131FROM $from
132WHERE $where
133GROUP BY contact_a.id
134$having
135";
136 //for only contact ids ignore order.
137 if (!$justIDs) {
138 // Define ORDER BY for query in $sort, with default value
139 if (!empty($sort)) {
140 if (is_string($sort)) {
141 $sql .= " ORDER BY $sort ";
142 }
143 else {
144 $sql .= " ORDER BY " . trim($sort->orderBy());
145 }
146 }
147 else {
148 $sql .= "ORDER BY donation_amount desc";
149 }
150 }
151
152 if ($rowcount > 0 && $offset >= 0) {
153 $sql .= " LIMIT $offset, $rowcount ";
154 }
155 return $sql;
156 }
157
158 function from() {
159 return "
160civicrm_contribution AS contrib,
161civicrm_contact AS contact_a
162";
163 }
164
165 /*
166 * WHERE clause is an array built from any required JOINS plus conditional filters based on search criteria field values
167 *
168 */
169 function where($includeContactIDs = FALSE) {
170 $clauses = array();
171
172 $clauses[] = "contrib.contact_id = contact_a.id";
173 $clauses[] = "contrib.is_test = 0";
174
175 $startDate = CRM_Utils_Date::processDate($this->_formValues['start_date']);
176 if ($startDate) {
177 $clauses[] = "contrib.receive_date >= $startDate";
178 }
179
180 $endDate = CRM_Utils_Date::processDate($this->_formValues['end_date']);
181 if ($endDate) {
182 $clauses[] = "contrib.receive_date <= $endDate";
183 }
184
185 if ($includeContactIDs) {
186 $contactIDs = array();
187 foreach ($this->_formValues as $id => $value) {
188 if ($value &&
189 substr($id, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX
190 ) {
191 $contactIDs[] = substr($id, CRM_Core_Form::CB_PREFIX_LEN);
192 }
193 }
194
195 if (!empty($contactIDs)) {
196 $contactIDs = implode(', ', $contactIDs);
197 $clauses[] = "contact_a.id IN ( $contactIDs )";
198 }
199 }
200
201 if (!empty($this->_formValues['financial_type_id'])) {
202 $financial_type_ids = implode(',', array_keys($this->_formValues['financial_type_id']));
203 $clauses[] = "contrib.financial_type_id IN ($financial_type_ids)";
204 }
205
206 return implode(' AND ', $clauses);
207 }
208
209 function having($includeContactIDs = FALSE) {
210 $clauses = array();
211 $min = CRM_Utils_Array::value('min_amount', $this->_formValues);
212 if ($min) {
213 $min = CRM_Utils_Rule::cleanMoney($min);
214 $clauses[] = "sum(contrib.total_amount) >= $min";
215 }
216
217 $max = CRM_Utils_Array::value('max_amount', $this->_formValues);
218 if ($max) {
219 $max = CRM_Utils_Rule::cleanMoney($max);
220 $clauses[] = "sum(contrib.total_amount) <= $max";
221 }
222
223 return implode(' AND ', $clauses);
224 }
225
226 /*
227 * Functions below generally don't need to be modified
228 */
229 function count() {
230 $sql = $this->all();
231
232 $dao = CRM_Core_DAO::executeQuery($sql,
233 CRM_Core_DAO::$_nullArray
234 );
235 return $dao->N;
236 }
237
238 function contactIDs($offset = 0, $rowcount = 0, $sort = NULL) {
239 return $this->all($offset, $rowcount, $sort, FALSE, TRUE);
240 }
241
242 function &columns() {
243 return $this->_columns;
244 }
245
246 function setTitle($title) {
247 if ($title) {
248 CRM_Utils_System::setTitle($title);
249 }
250 else {
251 CRM_Utils_System::setTitle(ts('Search'));
252 }
253 }
254
255 function summary() {
256 return NULL;
257 }
258}
259