CRM-13554 - validate values of limit and offset
[civicrm-core.git] / CRM / Contact / Form / Search / Custom / EventAggregate.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_EventAggregate extends CRM_Contact_Form_Search_Custom_Base implements CRM_Contact_Form_Search_Interface {
36
430ae6dd
TO
37 protected $_formValues;
38
39 function __construct(&$formValues) {
6a488035
TO
40 $this->_formValues = $formValues;
41
42 /**
43 * Define the columns for search result rows
44 */
45 $this->_columns = array(
46 ts('Event') => 'event_name',
47 ts('Type') => 'event_type',
48 ts('Number of<br />Participant') => 'participant_count',
49 ts('Total Payment') => 'payment_amount',
50 ts('Fee') => 'fee',
51 ts('Net Payment') => 'net_payment',
52 ts('Participant') => 'participant',
53 );
54 }
55
56 function buildForm(&$form) {
57
58 /**
59 * You can define a custom title for the search form
60 */
61 $this->setTitle('Find Totals for Events');
62
63 /**
64 * Define the search form fields here
65 */
66
67 $form->addElement('checkbox', 'paid_online', ts('Only show Credit Card Payments'));
68
69 $form->addElement('checkbox', 'show_payees', ts('Show payees'));
70
71 $event_type = CRM_Core_OptionGroup::values('event_type', FALSE);
72 foreach ($event_type as $eventId => $eventName) {
73 $form->addElement('checkbox', "event_type_id[$eventId]", 'Event Type', $eventName);
74 }
75 $events = CRM_Event_BAO_Event::getEvents(TRUE);
76 $form->add('select', 'event_id', ts('Event Name'), array('' => ts('- select -')) + $events);
77
78 $form->addDate('start_date', ts('Payments Date From'), FALSE, array('formatType' => 'custom'));
79 $form->addDate('end_date', ts('...through'), FALSE, array('formatType' => 'custom'));
80
81 /**
82 * If you are using the sample template, this array tells the template fields to render
83 * for the search form.
84 */
85 $form->assign('elements', array('paid_online', 'start_date', 'end_date', 'show_payees', 'event_type_id', 'event_id'));
86 }
87
88 /**
89 * Define the smarty template used to layout the search form and results listings.
90 */
91 function templateFile() {
92 return 'CRM/Contact/Form/Search/Custom/EventDetails.tpl';
93 }
94
95 /**
96 * Construct the search query
97 */
98 function all($offset = 0, $rowcount = 0, $sort = NULL,
99 $includeContactIDs = FALSE, $justIDs = FALSE
100 ) {
101 // SELECT clause must include contact_id as an alias for civicrm_contact.id if you are going to use "tasks" like export etc.
102 $select = "civicrm_participant.event_id as event_id,
103 COUNT(civicrm_participant.id) as participant_count,
104 GROUP_CONCAT(DISTINCT(civicrm_event.title)) as event_name,
105 civicrm_event.event_type_id as event_type_id,
106 civicrm_option_value.label as event_type,
107 IF(civicrm_contribution.payment_instrument_id <>0 , 'Yes', 'No') as payment_instrument_id,
108 SUM(civicrm_contribution.total_amount) as payment_amount,
109 format(sum(if(civicrm_contribution.payment_instrument_id <>0,(civicrm_contribution.total_amount *.034) +.45,0)),2) as fee,
110 format(sum(civicrm_contribution.total_amount - (if(civicrm_contribution.payment_instrument_id <>0,(civicrm_contribution.total_amount *.034) +.45,0))),2) as net_payment";
111
112 $from = $this->from();
113
114 $onLine = CRM_Utils_Array::value('paid_online',
115 $this->_formValues
116 );
117 if ($onLine) {
118 $from .= "
119 inner join civicrm_entity_financial_trxn
120 on (civicrm_entity_financial_trxn.entity_id = civicrm_participant_payment.contribution_id and civicrm_entity_financial_trxn.entity_table='civicrm_contribution')";
121 }
122
123 $showPayees = CRM_Utils_Array::value('show_payees',
124 $this->_formValues
125 );
126 if ($showPayees) {
127 $select .= ", GROUP_CONCAT(DISTINCT(civicrm_contact.display_name)) as participant ";
128 $from .= " inner join civicrm_contact
129 on civicrm_contact.id = civicrm_participant.contact_id";
130 }
131 else {
132 unset($this->_columns['Participant']);
133 }
134
135 $where = $this->where();
136
137 $groupBy = "event_id";
138 if (!empty($this->_formValues['event_type_id'])) {
139 $groupBy = "event_type_id";
140 }
141
142 $sql = "
143 SELECT $select
144 FROM $from
145 WHERE $where
146 GROUP BY $groupBy
147 ";
148 // Define ORDER BY for query in $sort, with default value
149 if (!empty($sort)) {
150 if (is_string($sort)) {
151 $sql .= " ORDER BY $sort ";
152 }
153 else {
154 $sql .= " ORDER BY " . trim($sort->orderBy());
155 }
156 }
157 else {
158 $sql .= "ORDER BY event_name desc";
159 }
160
161 if ($rowcount > 0 && $offset >= 0) {
bf00d1b6
DL
162 $offset = CRM_Utils_Type::escape($offset, 'Int');
163 $rowCount = CRM_Utils_Type::escape($rowCount, 'Int');
6a488035
TO
164 $sql .= " LIMIT $offset, $rowcount ";
165 }
166
167 // Uncomment the next line to see the actual SQL generated:
168 //CRM_Core_Error::debug('sql',$sql); exit();
169 return $sql;
170 }
171
172 function from() {
173 return "
174 civicrm_participant_payment
175 left join civicrm_participant
176 on civicrm_participant_payment.participant_id=civicrm_participant.id
177
178 left join civicrm_event on
179 civicrm_participant.event_id = civicrm_event.id
180
181 left join civicrm_contribution
182 on civicrm_contribution.id = civicrm_participant_payment.contribution_id
183
184 left join civicrm_option_value on
185 ( civicrm_option_value.value = civicrm_event.event_type_id AND civicrm_option_value.option_group_id = 14)";
186 }
187
188 /*
189 * WHERE clause is an array built from any required JOINS plus conditional filters based on search criteria field values
190 *
191 */
192 function where($includeContactIDs = FALSE) {
193 $clauses = array();
194
195 $clauses[] = "civicrm_participant.status_id in ( 1 )";
196 $clauses[] = "civicrm_contribution.is_test = 0";
197 $onLine = CRM_Utils_Array::value('paid_online',
198 $this->_formValues
199 );
200 if ($onLine) {
201 $clauses[] = "civicrm_contribution.payment_instrument_id <> 0";
202 }
203
204 $startDate = CRM_Utils_Date::processDate($this->_formValues['start_date']);
205 if ($startDate) {
206 $clauses[] = "civicrm_contribution.receive_date >= $startDate";
207 }
208
209 $endDate = CRM_Utils_Date::processDate($this->_formValues['end_date']);
210 if ($endDate) {
211 $clauses[] = "civicrm_contribution.receive_date <= {$endDate}235959";
212 }
213
214 if (!empty($this->_formValues['event_id'])) {
215 $clauses[] = "civicrm_event.id = {$this->_formValues['event_id']}";
216 }
217
218 if ($includeContactIDs) {
219 $contactIDs = array();
220 foreach ($this->_formValues as $id => $value) {
221 if ($value &&
222 substr($id, 0, CRM_Core_Form::CB_PREFIX_LEN) == CRM_Core_Form::CB_PREFIX
223 ) {
224 $contactIDs[] = substr($id, CRM_Core_Form::CB_PREFIX_LEN);
225 }
226 }
227
228 if (!empty($contactIDs)) {
229 $contactIDs = implode(', ', $contactIDs);
230 $clauses[] = "contact.id IN ( $contactIDs )";
231 }
232 }
233
234 if (!empty($this->_formValues['event_type_id'])) {
235 $event_type_ids = implode(',', array_keys($this->_formValues['event_type_id']));
236 $clauses[] = "civicrm_event.event_type_id IN ( $event_type_ids )";
237 }
238 return implode(' AND ', $clauses);
239 }
240
241
242 /* This function does a query to get totals for some of the search result columns and returns a totals array. */
243 function summary() {
244 $totalSelect = "
245 SUM(civicrm_contribution.total_amount) as payment_amount,COUNT(civicrm_participant.id) as participant_count,
246 format(sum(if(civicrm_contribution.payment_instrument_id <>0,(civicrm_contribution.total_amount *.034) +.45,0)),2) as fee,
247 format(sum(civicrm_contribution.total_amount - (if(civicrm_contribution.payment_instrument_id <>0,(civicrm_contribution.total_amount *.034) +.45,0))),2) as net_payment";
248
249 $from = $this->from();
250
251 $onLine = CRM_Utils_Array::value('paid_online',
252 $this->_formValues
253 );
254 if ($onLine) {
255 $from .= "
256 inner join civicrm_entity_financial_trxn
257 on (civicrm_entity_financial_trxn.entity_id = civicrm_participant_payment.contribution_id and civicrm_entity_financial_trxn.entity_table='civicrm_contribution')";
258 }
259
260
261 $where = $this->where();
262
263 $sql = "
264 SELECT $totalSelect
265 FROM $from
266 WHERE $where
267 ";
268
269 //CRM_Core_Error::debug('sql',$sql);
270 $dao = CRM_Core_DAO::executeQuery($sql,
271 CRM_Core_DAO::$_nullArray
272 );
273 $totals = array();
274 while ($dao->fetch()) {
275 $totals['payment_amount'] = $dao->payment_amount;
276 $totals['fee'] = $dao->fee;
277 $totals['net_payment'] = $dao->net_payment;
278 $totals['participant_count'] = $dao->participant_count;
279 }
280 return $totals;
281 }
282
283 /*
284 * Functions below generally don't need to be modified
285 */
286 function count() {
287 $sql = $this->all();
288
289 $dao = CRM_Core_DAO::executeQuery($sql,
290 CRM_Core_DAO::$_nullArray
291 );
292 return $dao->N;
293 }
294
295 function contactIDs($offset = 0, $rowcount = 0, $sort = NULL) {
296 return $this->all($offset, $rowcount, $sort);
297 }
298
299 function &columns() {
300 return $this->_columns;
301 }
302
303 function setTitle($title) {
304 if ($title) {
305 CRM_Utils_System::setTitle($title);
306 }
307 else {
308 CRM_Utils_System::setTitle(ts('Search'));
309 }
310 }
311}
312